STM32 使用DMA+双缓冲串口接收不定长数据时,如何避免缓冲区覆盖与丢帧?

· 1 浏览

回答(4)

双缓冲适合帧长固定场景,不定长时建议配合超时定时器(如TIM)在帧间隔后触发处理,更稳妥。
硬件工程师阿杰 · 2026-08-27
用CNDTR判断剩余字节数,若剩余数等于缓冲区大小说明刚切换,需特殊处理边界情况,防止漏帧。
码农小飞 · 2026-08-27
建议在IDLE中断中先关闭DMA(HAL_UART_DMAStop),处理完再重新启动,避免处理期间新数据写入同一缓冲区。
嵌入式老周 · 2026-08-27
核心方案:采用DMA双缓冲(Memory-to-Memory或外设到内存)配合空闲中断(IDLE)实现不定长接收。配置两个缓冲区(如buf1/buf2),DMA循环模式交替填充,每次进入IDLE中断时,先读取DMA的CNDTR寄存器判断当前写指针位置,从而确定哪个缓冲区正在被写入、哪个已完成。处理逻辑:在IDLE中断中,若当前DMA写指针在buf1,则处理buf2数据;反之处理buf1。关键点:1)确保缓冲区大小大于最大帧长,且处理速度高于接收速率;2)在中断中仅拷贝数据到应用层队列,避免长时间占用;3)启用DMA传输完成中断(TC)作为兜底,防止IDLE丢失时缓冲区溢出。实操建议:使用HAL库时,在HAL_UARTEx_RxEventCallback中根据Size参数区分缓冲区,并配合__HAL_DMA_GET_COUNTER实时校验。若帧间隔极短,可考虑增加第三缓冲区或使用环形队列二次缓冲。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器