STM32 使用 DMA 进行多路 ADC 采样时,如何避免数据错位与缓存一致性问题?

· 2 浏览

回答(4)

对于H7系列,务必在DMA描述符中设置DMA_CACHE_MAINTENANCE,并确保缓冲区地址按32字节对齐,否则Cache行污染会引发随机数据错误。
硬件小白 · 2026-08-27
如果采样率不高,可以改用DMA普通模式+定时器触发,每次转换完成触发一次DMA传输,天然避免多通道错位,但CPU开销略增。
码农阿飞 · 2026-08-27
用DMA的循环模式时,记得设置DMA的优先级高于CPU,并关闭ADC的DMA请求的FIFO,否则可能因FIFO缓冲导致数据顺序错乱。
嵌入式老周 · 2026-08-27
核心方案:使用DMA循环模式+双缓冲(或乒乓缓冲),并配合ADC的EOC(转换结束)中断或DMA半传输/传输完成中断来同步处理数据。具体实操:1)配置ADC为扫描模式+连续转换,DMA为循环模式,数据宽度设为半字(16位),确保每个通道数据对齐。2)定义两个缓冲区(如uint16_t buf1[CH_NUM], buf2[CH_NUM]),通过DMA的M0AR/M1AR寄存器切换,或使用HAL库的HAL_ADCEx_MultiModeStart_DMA并启用DMA中断回调。3)在DMA半传输中断中处理buf1,在传输完成中断中处理buf2,避免CPU与DMA同时访问同一缓冲区。4)缓存一致性:若使用带Cache的MCU(如STM32H7),需在DMA配置时使用DMA_CACHE_MAINTENANCE,并调用SCB_CleanDCache_by_Addr(写前)和SCB_InvalidateDCache_by_Addr(读前)来维护。5)数据错位根因:ADC通道顺序与DMA缓冲区索引必须严格对应,建议在初始化时固定通道序列,并在中断中校验首个通道的已知参考值。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换