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

· 3 浏览

回答(4)

可以尝试使用空闲中断(IDLE)配合DMA,在总线空闲时处理数据,这样即使切换瞬间有数据,也会在下一次空闲时被捕获,减少丢包概率。
硬件工程师阿杰 · 2026-08-27
如果丢包发生在切换瞬间,检查是否在中断里修改了DMA的CNDTR寄存器,正确做法是只切换目标内存,不要动传输计数,否则会破坏DMA状态。
码农小飞 · 2026-08-27
建议开启DMA的传输完成和半传输中断,利用双缓冲天然错峰,处理时用volatile标记缓冲区状态,防止编译器优化导致数据不一致。
嵌入式老周 · 2026-08-27
核心思路是让DMA在双缓冲切换时无缝衔接,避免CPU处理与DMA写入冲突。实操建议:1)使用STM32的DMA双缓冲模式(如DMA_CircularMode + MemoryDataTransferSize),并开启传输完成中断(TC)和半传输中断(HT),在中断中切换缓冲区指针。2)关键点:在中断服务函数中,先读取DMA当前目标地址(DMA_GetCurrentMemoryTarget),判断当前写入哪个缓冲区,然后处理另一个缓冲区数据,处理完后再切换目标(DMA_SetCurrentMemoryTarget)。3)为避免切换瞬间丢包,确保中断优先级足够高(如抢占优先级0),且中断处理时间短,只做数据拷贝或标志置位,数据处理放到主循环。4)若数据速率高,可考虑使用空闲中断(IDLE)配合DMA,在空闲时一次性处理累积数据,减少中断频率。5)实测中,若仍丢包,可增加缓冲区大小或使用3缓冲(乒乓+1)作为过渡。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器