STM32H7的DMA双缓冲模式配合Cache维护,如何避免ADC连续采样时的数据撕裂

· 5 浏览

回答(4)

双缓冲切换时用HAL_DMAEx_MultiBufferStart,在XferCpltCallback里处理已满缓冲,处理完再Invalidate,顺序不能反,否则读到旧数据。
硬件攻城狮 · 2026-09-26
Invalidate时务必按Cache行对齐,H7的Cache行是32字节,长度要向上取整,否则会误伤相邻数据,导致偶发数据错乱。
STM32小王子 · 2026-09-26
最省事的方案:直接把ADC DMA缓冲区定义到DTCM RAM,DTCM无Cache,不存在一致性问题,但DMA无法访问DTCM,需改用AXI SRAM并配MPU为Non-Cacheable。
嵌入式老菜鸟 · 2026-09-26
STM32H7的DMA双缓冲配合Cache维护,核心是解决CPU与DMA对同一内存区域访问的Cache一致性问题。推荐做法:将ADC的DMA目标缓冲区放在MPU配置为Device或Strongly-Ordered属性的内存区,或使用非Cacheable区域,从根本上避免Cache行回写导致的数据撕裂。若必须使用Cacheable内存,则需在DMA完成中断中,对刚接收完的缓冲区执行SCB_InvalidateDCache_by_Addr,注意地址必须32字节对齐,长度向上取整到Cache行大小,且Invalidate前要确保CPU没有脏数据未回写。双缓冲模式下,DMA在Buf0和Buf1间切换,CPU处理Buf0时DMA写Buf1,处理完再交换。关键点:在DMA传输完成中断里只Invalidate即将交给CPU处理的那个缓冲区,不能Invalidate正在被DMA写入的缓冲区,否则会丢失DMA刚写入但尚未落盘的数据。同时建议开启DMA的传输错误中断,并避免在中断外随意访问DMA缓冲区。若使用D-Cache且数据量大,可考虑将ADC缓冲区放到DTCM RAM,DTCM不经过Cache,天然无一致性问题,但注意DTCM不能被DMA直接访问,需用AXI SRAM或通过MDMA搬运。
mcuku 阿沐 · 2026-09-26

🧰 配套工具

📊 ADC 转换