UART 接收数据较大时,怎么接收
-
@鱼的记忆 发送那端是别人的设备控制不了,是用Jlink调试的,打印口被用来传输数据了
-
这个有点麻烦,这个只能富瑞坤内部人员,看可以解决不,分两次接收,我只会这种
-
如果可以控制发送端,分包发送,两次接收,应该是没问题。谢谢你的帮忙
-
找到解决办法了,接收中断改为半满,这样就有足够时间读取数据,不要在中断中打断点查看数据,这样也会导致接收不完整。具体做法如下
串口初始化
中断执行内容还是上面的图
-
我不建议用芯片带FIFO来做接收中断,我从来都是自己做1个串口字节接收缓冲区,1个串口包处理缓冲区。这种结构对于1个叠包也基本够用了。
attribute((weak)) attribute((section("ram_code"))) void uart0_isr_ram(void)
{
uint8_t int_id;
uint8_t rx_byte;int_id = uart0_reg->u3.iir.int_id; if(int_id == 0x04 || int_id == 0x0c ) /* Receiver data available or Character time-out indication */ { rx_byte = uart0_reg->u1.data; uart0_info.packet_timeout = 2; if(1 == uart0_info.rxd_flg) { uart0_info.rxd_buf[uart0_info.rxd_ctr++] = rx_byte; // if(uart0_info.rxd_ctr == uart0_info.rxd_len) { //收齐 处理包 uart0_info.rxd_ctr = 0; uart0_info.rxd_flg = 0; uart0_info.rxd_cmd_len = uart0_info.rxd_len; memcpy(uart0_info.rxd_cmd_buf, uart0_info.rxd_buf, uart0_info.rxd_len); evt.event_id = 0; //串口0 事件 os_msg_post(uart01_task_id, &evt); } else if(3==uart0_info.rxd_ctr) { uart0_info.rxd_len = rx_byte + 4;//后面字节包的长度 } else ; } else //== 0 { if(0xA7 == rx_byte) //协议包头 { uart0_info.rxd_flg = 1; //开启接收 uart0_info.rxd_ctr = 1; //接收字节计数 uart0_info.rxd_buf[0] = rx_byte; } } } if(int_id == 0x06) { volatile uint32_t line_status = uart0_reg->lsr; } if(int_id == 0x02) { if(uart0_info.txd_ctr < uart0_info.txd_len[uart0_info.txd_busy_index]) //判断当前包是否发送完毕 { uart0_reg->u1.data = uart0_info.txd_buf[uart0_info.txd_busy_index][uart0_info.txd_ctr++]; } else //发完一包 休息或继续下一包 { uart0_info.txd_len[uart0_info.txd_busy_index] = 0; //清除发送包长度 表示空的 可以重新组装 if(uart0_info.txd_len[uart0_info.txd_emptypp_index]>0) //有包要发 则继续 { if(0==uart0_info.txd_busy_index) { uart0_info.txd_busy_index = 1; uart0_info.txd_emptypp_index = 0; } else { uart0_info.txd_busy_index = 0; uart0_info.txd_emptypp_index = 1; } uart0_info.txd_ctr = 1; uart0_reg->u1.data = 0xA7; // } else { uart0_reg->u2.ier.eti = 0; //关闭发送中断 避免这个MCU 产生发送空中断,STC51则不必 关不掉(因为51发送跟接收中断开关共用,而你不可能关闭接收中断) uart0_info.tx_busy = IDLE; } } }
}
-
修改接收中断处理函数,另外收到第一个byte开启硬件定时器做超时处理,收到下一个byte后reload定时器初值保证不产生中断,在间隔一定时间不收到产生超时中断,这个时间要以当前波特率下的的一byte传输数据留下余量。即使用超时成帧机制,再处理一帧数据
-
@赢娶姗姗 挺好的,值得学习学习,感谢
-
@zj4068 现在的使用和这个方法类似
-
自己多想方法,原厂只是demo而已,我把发送函数也做了处理。目前demo是使用无中断发送。好处比较简单,不好的地方数据超多,会比较占用时间。使用填好发送缓冲我数据后,发送第一个字节启动tx串口中断,后续在发送中断中完成,发完后关闭发送中断。相对高效,如果原厂可以开放dma会更高效。
-
@zj4068 没错的 发送中断方式 比查询方式 会更少阻塞CPU一些。 DMA有的话更好, 中断发送方式更加通用,8位机基本没DMA,有的32位也没有串口发送 DMA呢
-
@赢娶姗姗 大佬 我想学习一下您的方法,能看看相关的形参和结构体吗