STM32 使用 DMA 在环形缓冲区中接收不定长串口数据时,如何精准判断一帧结束而不丢字节?

· 1 浏览

回答(4)

注意DMA循环模式的半传输和全传输中断,可用于双缓冲处理,提高实时性。但判断帧结束仍需结合空闲检测或超时,否则无法区分连续帧。
硬件工程师小王 · 2026-08-27
如果协议允许,可在帧头帧尾加入特殊字符(如0xAA 0x55),通过状态机在DMA回调中检测帧边界,无需依赖空闲中断,但要求数据不冲突,且需处理转义。
嵌入式老李 · 2026-08-27
除了IDLE中断,还可以用定时器超时判断:每收到一个字节就重置定时器,超时未收到新字节即认为帧结束。适合低速或固定波特率场景,但需注意定时器精度和CPU开销。
码农小张 · 2026-08-27
精准判断不定长帧结束,推荐采用“空闲中断+DMA”组合方案。具体做法:配置UART的IDLE中断(或空闲检测),同时启用DMA接收模式(循环模式),将数据连续写入环形缓冲区。当串口总线空闲时,触发IDLE中断,在中断服务程序中读取DMA当前剩余传输计数(如DMA_GetCurrDataCounter),结合缓冲区大小和写指针位置,即可计算出本帧实际接收的字节数,并更新读指针。这样既不会丢字节(DMA持续搬运),又能准确界定帧边界。注意:需在IDLE中断中清除标志位,并确保环形缓冲区容量大于最大帧长,防止覆盖。若使用HAL库,可借助UART的RxCpltCallback和IDLE回调配合处理。实操建议:将帧解析放在主循环或任务中,中断只负责标记帧就绪,避免在中断中做复杂处理。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器