WCH沁恒单片机
直播中

张英

7年用户 1371经验值
私信 关注
[问答]

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)

高澜栖

2022-8-18 10:10:01
先按如下优化:

  • 可以降低波特率试试;
  • 将uart_receive_input和uart_receive_buff_input函数上方加上__attribute__((section(".highcode")))
  • 不要在中断内使用memset,中断程序是在ram中运行的,速度要求快,可以手写for循环代替。
  • 外部读取fifo的时候最好关闭中断
  • UART1_GetLinSTA要赋值给一个临时变量才算一句代码。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分