请教一下CH573串口接收数据包不完整问题

使用的CH573串口1接收数据,每接收一字节数据要调用void uart_receive_input(unsigned char value)函数将输入放入缓存区处理,字节数少的话处理起来没问题,但是如果接收的是一个256字节的数据包,接受的数据好像不完整,校验会不通过,请问要接收256字节的数据包,甚至512字节,每个字节还要调用函数放入缓存区,串口终端应该怎样写才能接收完整。

第一个函数是单字节暂存,第二个函数是多字节暂存,附上我的串口中断函数,请指出不足,谢谢。

void uart_receive_input(unsigned char value)//单字节暂存
{
    
    if(1 == rx_buf_out - rx_buf_in) {
        //串口接收缓存已满
    }else if((rx_buf_in > rx_buf_out) && ((rx_buf_in - rx_buf_out) >= sizeof(wifi_uart_rx_buf))) {
        //串口接收缓存已满
    }else {
        //串口接收缓存未满
        if(rx_buf_in >= (unsigned char *)(wifi_uart_rx_buf + sizeof(wifi_uart_rx_buf))) {
            rx_buf_in = (unsigned char *)(wifi_uart_rx_buf);
        }
        
        *rx_buf_in ++ = value;
    }
}
void uart_receive_buff_input(unsigned char value[], unsigned short data_len)//多字节暂存
{
    
    unsigned short i = 0;
    for(i = 0; i < data_len; i++) {
        uart_receive_input(value[i]);
    }
}
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void UART1_IRQHandler( void )        // UART1 中断
{
    UINT8V i = 0;

    UINT8V Recv;

    switch ( UART1_GetITFlag() )
    {
        case UART_II_LINE_STAT :        // 线路状态错误
        {
            UART1_GetLinSTA();
            break;
        }

        case UART_II_RECV_RDY :          // 数据达到设置触发点
            for ( i = 0 ; i != trigB_UART_Wifi; i++ )
            {
                Recv = R8_UART1_RBR;
                uart_receive_input(Recv);
            }
        break;

        case UART_II_RECV_TOUT :         // 接收超时,暂时一帧数据接收完成
            i = UART1_RecvString( Wifi_RxBuff );
            uart_receive_buff_input(Wifi_RxBuff,i);
            memset(Wifi_RxBuff,0,i);
        break;

        case UART_II_THR_EMPTY :         // 发送缓存区空,可继续发送
        break;

        case UART_II_MODEM_CHG :         // 只支持串口0
        break;

        default :
        break;
    }
}


先按如下优化:

  1. 可以降低波特率试试;

  2. 将uart_receive_input和uart_receive_buff_input函数上方加上__attribute__((section(".highcode")))

  3. 不要在中断内使用memset,中断程序是在ram中运行的,速度要求快,可以手写for循环代替。

  4. 外部读取fifo的时候最好关闭中断

  5. UART1_GetLinSTA要赋值给一个临时变量才算一句代码。


您好,请问外部读取FIFO时关闭中断是什么意思。


防止fifo的参数变量在参与程序运算时被中断打断,然后中断中对fifo变量进行操作更改,会导致丢数据等情形。


这个要怎么操作呢


PFIC_EnableIRQ( UART1_IRQn );        //打开串口1中断

PFIC_DisableIRQ( UART1_IRQn );       //关闭串口1中断

你需要先一步步试,排除问题。


请问是要在进入串口1中断时关闭中断,在要退出中断时使能中断吗


不是在中断程序中,是在外部主程序中,从buffer里取数据时关闭中断,取完数据打开中断。


谢谢您的解答,但是我修改了您指出的不足之后,问题仍没有解决,还有一个问题,就是有时我在向串口发送大数据包时,系统会重新启动,这又是什么原因造成的呢。


你把工程发过来吧,发到邮箱:mx@wch.cn。


我这边给个建议,确认串口有没有接收错误,并且不影响当前的代码的话,,很简单:   只需要再初始化一路串口,然后让速率略大于当前串口的速率, 然后把当前的串口接收的数据实时发送出去即可.

另外还有一个要注意的是: ch57x ch58x 系列的芯片 串口时钟来源于系统时钟,在波特率比较高的情况下, 部分波特率可能有一定的误差.



串口中断为什么用for循环呀。


串口中断接受代码写的问题


只是为了避免中断程序处理时间占用过长,memset是flash中的程序,运行没有ram中的程序快。而且楼上的问题最后并不是串口处理,是其他方面错误导致的。


解决了吗,请问


请教大神,可以添加我的qq吗,942344644,谢谢


只有登录才能回复,可以选择微信账号登录