huojinqiu 发表于 2012-4-8 14:37:24

UART0串口接收时出现溢出错误,接收不到RXB0中数据,请帮忙分析

单片机是NEC的uPD78F0513,在调试UART0通信时有溢出错误,在未读取RXB0寄存器之前先读取ASIS0,指示帧错误(如果接收完成时未检测到停止位),然后再读取RXB0寄存器,但是读出来的始终是00,我不知道是没有读出来,还是其它的什么原因.
出现帧错误是什么原因,该怎样解决呢?
请帮忙分析指点下,谢谢~

yangsen 发表于 2012-4-9 08:54:54

我用过0511,代码也不贴不知道怎么给你分析,我把我的代码贴上给你参考吧
/*
**-----------------------------------------------------------------------------
**
**Abstract:
**        This function initializes UART0.
**
**Parameters:
**        None
**
**Returns:
**        None
**
**-----------------------------------------------------------------------------
*/
void UART0_Init( void )
{
        RXE0 = 0;        /* uart0 receive disable */
        TXE0 = 0;
        SRMK0 = 1;        /* INTSR0 disable */
        SRIF0 = 0;        /* INTSR0 IF clear */

        BRGC0 = 0x80 | 0x1a;
        ASIM0 = 0x05;        //8bit none proi,1bit stop
        /* INTSR0 priority low */
        SRPR0 = 1;
        STPR0 = 1;
        /* RXD0 pin setting */
        PM1 |= 0x02;
        SRMK0 = 0;        /* INTSR0 enable */
        STMK0 = 0;
        POWER0 = 1;        /* uart0 enable */
        TXE0 = 1;        /* uart0 TX enable */
        RXE0 = 1;        /* uart0 receive enable */
}
接收中断,向一个循环缓冲填充数据,协议分析里只读缓冲区,读写指针碰头就认为缓冲区空,指针永远指向空单元。
#pragma vector=INTSR0_vect
__interrupt void UART0_ISR( void )
{
        unsigned char err_type;
        //error deal
        err_type = ASIS0;
        SRIF0=0;                //CLEAR THE INTERRUPT FLAG
        if( (err_type & 0x07 )!=0){                //don't check the usart error statute
                err_type=RXB0;        //if has error clear it
                return;
        }
        ucUART0buf=RXB0;
        ucUART0wr++;
        ucUART0wr=ucUART0wr%16;
}
发射中断,采用阻塞方式发送,需要的话可以改成中断方式发
/**********************************************************************/
#pragma vector=INTST0_vect
__interrupt void UART0_ISR_tx( void )
{
        RF_TxD_OUT;
        bSlaveTxdEnd=1;
        return;
}
/**********************************************************************/
void Uart0Send(unsigned char val)
{
        TXS0=val;
        while(bSlaveTxdEnd==0);
        bSlaveTxdEnd=0;
}

huojinqiu 发表于 2012-4-9 15:50:01

本帖最后由 huojinqiu 于 2012-4-9 15:51 编辑

yangsen 发表于 2012-4-9 08:54 static/image/common/back.gif
我用过0511,代码也不贴不知道怎么给你分析,我把我的代码贴上给你参考吧
/*
**-------------------------- ...

不好意思,下面是我的代码。

void UART0_Init( void )
{
        TXE0 = 0;        /* uart0 transmit disable */
        RXE0 = 0;        /* uart0 receive disable */
        STMK0 = 1;        /* INTST0 disable */
        SRMK0 = 1;        /* INTSR0 disable */
        STIF0 = 0;        /* INTST0 IF clear */
        SRIF0 = 0;        /* INTSR0 IF clear */
        BRGC0 = UART0_BASECLK_4 | UART0_BASECLK_DIVISION;
        ASIM0 = UART0_ASIM0_INITIALVALUE | UART0_DATA_LENGTH_8|UART0_STOP_BIT_1|UART0_PARITY_NONE;
        /* INTST0 priority low */
        STPR0 = 1;
        /* INTSR0 priority low */
        SRPR0 = 1;
        /* TXD0 pin setting */
        P1 |= 0x01;
        PM1 &= ~0x01;
        /* RXD0 pin setting */
        PM1 |= 0x02;
}
void UART0_Start( void )
{
        STMK0 = 0;        /* INTST0 enable */
        SRMK0 = 0;        /* INTSR0 enable */
        POWER0 = 1;        /* uart0 enable */
        TXE0 = 1;        /* uart0 transmit enable */
        RXE0 = 1;        /* uart0 receive enable */
}
voidmain( void )
{   
                UART0_Init();
                UART0_Start();
        while (1)
        {
                ;
        }
}
__interrupt void MD_INTSR0( void )
{   
        err_type = ASIS0;
        rx_data = RXB0;
        if( err_type & 0x07 )
                {
                CALL_UART0_Error( err_type );
                return;
        }
                else CALL_UART0_Receive( );
}

单片机发送数据能够用串口调试助手接收到,所以没有贴出发送部分的程序代码;
有两种可能会进入INTSR0,第一种是UART0接收结束,第二种是产生接收错误;通过测试,我没有给单片机发送数据的前提下,程序运行后即进入INTSR0,那么就可能是由于产生接收错误而使程序进入INTSR0,并通过进一步测试产生的接收错误是帧错误(如果接收完成时未检测到停止位),我现在就是不知道为什么会产生帧错误,该从哪找到出现这个错误的原因?
请帮帮!

chuyuming 发表于 2012-4-17 13:40:32

我也贴下我的代码,0511上机通过测试。
void UART6_Init( void )
{
        TXE6 = 0;        /* uart6 transmit disable */
        RXE6 = 0;        /* uart6 receive disable */
        STMK6 = 1;        /* INTST6 disable */
        SRMK6 = 1;        /* INTSR6 disable */
        STIF6 = 0;        /* INTST6 IF clear */
        SRIF6 = 0;        /* INTSR6 IF clear */
      
       
        ASIM6 = 0x05;//数据位8位,停止位1位
      CKSR6 = 3;//2的3次方
      BRGC6 = 78;//波特率=(12M/8)/(2*78)=9615.38
        /* INTST0 priority low */
        STPR6 = 1;
        /* TXD0 pin setting */
        P1 |= 0x08;
        PM1 &= ~0x08;
        /* RXD6 pin setting */
        PM1 |= 0x10;
      
      
      STMK6 = 0;        /* INTST6 enable */
        SRMK6 = 0;        /* INTSR6 enable */
        POWER6 = 1;        /* uart6 enable */
        TXE6 = 1;        /* uart6 transmit enable */
        //RXE6 = 1;        /* uart6 receive enable */
}
void uart6send(unsigned char *psend,unsigned char num)
{
      unsigned char i;
        STIF6 = 0;
      
        for(i=0;i<num;i++)
        {
                TXB6 = *(psend+i);
                while(STIF6==0);
                STIF6 = 0;
                NOP();NOP();NOP();NOP();
        }
      delay3(1);
   
}

void uart6receive( uchar* rxbuf, uchar rxnum )
{
        gUart0RxLen = rxnum;
        gpUart0RxAddress = rxbuf;
       
        if (gUart0RxLen > 0)
    {
                *gpUart0RxAddress = RXB6;
                gpUart0RxAddress++;
                gUart0RxLen--;
        }
}

yangsen 发表于 2012-4-19 09:03:23

楼上,楼主用的是UART0,我测试了,的确会有溢出错误,并且导致下一个字节不能接收,有1~3%的可能出现(我测试每次发2000字节,会丢10~30字节,不一定)。我原来的程序在收到帧不对时不会回应答,这样主机会重发若干次,这样就把这个问题掩盖掉了,实际上最坏情况会导致主机重发两次。昨天看了又看手册,实在想不明白这个问题怎么避免。不知道楼主解决了没有。不能的话只能靠协议保证可靠了。

chuyuming 发表于 2012-4-19 16:15:28

yangsen 发表于 2012-4-19 09:03 static/image/common/back.gif
楼上,楼主用的是UART0,我测试了,的确会有溢出错误,并且导致下一个字节不能接收,有1~3%的可能出现(我 ...

改下寄存器名字么,这段程序用在产品上到现在暂时还没出过问题,可以参考下
页: [1]
查看完整版本: UART0串口接收时出现溢出错误,接收不到RXB0中数据,请帮忙分析