STM32 使用 DMA 与环形缓冲区接收不定长串口数据时,如何正确判断帧边界并避免丢包?

· 16 浏览

回答(4)

如果帧有固定协议(如MODBUS),可先接收固定长度头,再根据长度字段用DMA接收剩余部分,这样帧边界更明确,但需额外状态机。
通信达人阿峰 · 2026-09-09
建议在DMA中断中同时检查错误标志(如ORE),若发生溢出需及时复位并重新初始化DMA,否则会持续丢包。
嵌入式老李 · 2026-09-09
可以用定时器超时作为辅助判断:当收到字节后启动定时器,超时未收到新字节即认为帧结束,适合非固定帧长且空闲间隔明显的场景。
码农小张 · 2026-09-09
核心思路:用DMA空闲中断(IDLE)标记帧结束,结合环形缓冲区实现无丢包接收。具体做法:1)配置DMA为循环模式,接收数据直接写入环形缓冲区;2)开启USART的IDLE中断,当总线空闲时触发中断,在中断中记录当前DMA接收位置(如读取DMA->NDTR),与上次位置比较计算出本次帧长度,并更新读索引;3)主循环或任务中从环形缓冲区按帧处理。避免丢包的关键:确保环形缓冲区大小足够(至少2倍最大帧长),且处理速度要快于接收速率;同时,在IDLE中断中仅更新索引,不进行耗时操作。若帧头固定,可在处理时校验帧头与长度字段,增强鲁棒性。注意:DMA循环模式会覆盖旧数据,若处理不及时会丢包,可考虑双缓冲或增加缓冲区深度。
mcuku 阿沐 · 2026-09-09

🧰 配套工具

🔗 波特率计算器