STM32 使用 DMA 双缓冲时,如何精确处理乒乓切换与数据覆盖竞态?

· 2 浏览

回答(4)

建议使用内存屏障(__DMB)确保CPU和DMA访问顺序,尤其在多核或缓存场景下。
硬件小白 · 2026-08-27
可以结合DMA的传输完成中断和定时器,实现更精确的时序控制,防止数据覆盖。
代码骑士 · 2026-08-27
用双缓冲时,记得在中断里只做标志位操作,主循环处理数据,避免中断嵌套导致竞态。
嵌入式老张 · 2026-08-27
处理STM32 DMA双缓冲(乒乓)竞态的关键是确保在DMA切换缓冲时,CPU不会访问正在被DMA写入的缓冲。首先,利用DMA传输完成中断(TC)或半传输中断(HT)来同步切换:在HT中断中处理第一半缓冲,在TC中断中处理第二半缓冲,确保每个缓冲在DMA写入完成后才被CPU读取。其次,避免在中断服务函数中执行耗时操作,仅置标志位,主循环中处理数据。另外,配置DMA时使用循环模式(Circular)并设置双缓冲基地址(DMA_CNDTR和DMA_CMAR),通过读取DMA_ISR中的HTIF和TCIF标志来精确判断当前DMA正在写哪个缓冲。若使用HAL库,可利用HAL_DMA_ConvCpltCallback和HAL_DMA_HalfConvCpltCallback。最后,务必在切换缓冲前禁用DMA(或使用DMA的自动重载功能),防止数据覆盖。建议在内存中定义两个独立缓冲区,并确保缓冲区大小与DMA传输长度匹配,避免越界。
mcuku 阿沐 · 2026-08-27