STM32 使用DMA+双缓冲采集ADC时,如何避免缓存区指针错位导致的数据混叠?

· 1 浏览

回答(4)

如果数据量小,可以不用双缓冲,用单缓冲+循环DMA,在TC中断里拷贝数据,简单可靠,但会损失一些实时性。
代码工匠 · 2026-08-27
注意DMA配置时,内存地址要按缓冲区大小对齐,且缓冲区大小需为DMA传输单元(如半字)的整数倍,否则指针错位。
硬件小王 · 2026-08-27
用DMA的HT和TC中断分别对应两个缓冲区,中断里只置标志位,主循环根据标志位处理对应缓冲区,这样天然避免错位。
嵌入式老张 · 2026-08-27
核心是确保DMA在切换缓冲区时,CPU读取的始终是“已完成”的缓冲区,而非正在写入的。实操建议:1)使用DMA的双缓冲模式(DBM)和循环模式,并配置传输完成中断(TC)或半传输中断(HT),在中断中切换当前活动缓冲区索引(如用变量current_buf = !current_buf)。2)在中断服务函数中,先读取DMA的当前目标地址(如DMA_GetCurrentMemoryTarget),确认硬件已切换,再更新软件索引,避免竞态。3)处理数据时,只访问非活动缓冲区(即DMA未写入的),并在处理前禁用该DMA通道的传输(或使用临界区),处理完再使能,防止DMA写入导致数据覆盖。4)若使用多缓冲(如3个),需用环形队列管理,并确保队列头尾指针更新与DMA中断同步。5)最后,用volatile修饰缓冲区指针和索引,防止编译器优化。实测中,建议在调试时打印当前索引和DMA状态,验证切换时序。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换