STM32 使用DMA+双缓冲接收不定长串口数据时,如何避免因缓冲区切换导致的丢包?

· 1 浏览

回答(4)

如果使用空闲中断,记得在空闲中断里先读DMA剩余计数,再切换缓冲区,否则可能丢失最后几个字节。实测有效。
STM32实战派 · 2026-08-27
检查DMA的FIFO和突发模式配置,适当开启FIFO可缓冲数据,但注意对齐要求;同时关闭DMA的FIFO错误中断,防止误触发。
码农小刘 · 2026-08-27
建议用环形缓冲区配合DMA,中断里只更新写索引,主循环轮询读索引,避免在中断中做复杂处理,减少丢包概率。
嵌入式老张 · 2026-08-27
核心思路是确保DMA在切换缓冲区时不会漏掉新到达的数据。建议采用“乒乓缓冲+空闲中断”方案:配置两个缓冲区(如buf1、buf2),DMA循环模式或半满/全满中断触发切换。当DMA半满或全满时,在中断中立即切换目标地址(通过修改DMA->CMAR或使用双缓冲模式),同时记录当前已接收长度。为避免丢包,需在切换前检查DMA当前剩余计数(DMA_GetCurrDataCounter),若剩余计数小于预期阈值,则延迟切换或采用“先拷贝后切换”策略。实操建议:1) 使用STM32的DMA双缓冲模式(如DMA_InitTypeDef.DMA_Mode = DMA_Mode_Circular),硬件自动切换,减少中断延迟;2) 在空闲中断(IDLE)中处理完整帧,而非在DMA中断中处理数据,降低丢包风险;3) 若数据速率高,可增加缓冲区深度或使用FIFO,并确保中断优先级足够高。最后,务必测试边界条件(如数据恰好跨越缓冲区边界),并加入超时重传机制兜底。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器