STM32H7的DMA双缓冲模式在ADC连续采样中如何避免Cache一致性导致的半满中断数据错位

· 4 浏览

回答(4)

也可以在半满中断里只处理前一半,全满中断处理后半,同时用__DSB()保证顺序,但无效化Cache仍是必须的。
DMA小王子 · 2026-10-16
注意SCB_InvalidateDCache_by_Addr的地址和长度都要32字节对齐,否则会清掉相邻变量导致诡异bug。
H7踩坑人 · 2026-10-16
最简单:把ADC的DMA缓冲区放到MPU配置的Non-cacheable区域,一劳永逸,不用每次中断无效化。
嵌入式老鸟 · 2026-10-16
在STM32H7上,DMA双缓冲模式配合ADC连续采样时,Cache一致性问题的核心在于:DMA直接写入物理内存,而CPU可能从Cache中读取旧数据,导致半满中断中读到的数据错位。建议采用以下方案:1)将DMA目标缓冲区(两个半缓冲)放置在非Cache区域(如通过MPU配置为Device或Strongly-ordered内存),或使用DTCM RAM(H7的DTCM默认不经过Cache,但需注意DMA无法访问DTCM,故不适用);2)更实用的做法是:将缓冲区放在AXI SRAM或D2 SRAM中,并在每次半满/全满中断中,先调用SCB_InvalidateDCache_by_Addr()无效化对应半缓冲区,再读取数据。注意无效化地址必须32字节对齐,长度也需32字节对齐,否则可能误伤相邻数据。3)若使用DMA的循环双缓冲模式,建议在中断中只无效化当前已满的半缓冲区,避免无效化正在被DMA写入的区域。此外,可启用DMA的FIFO和突发传输,但这对Cache一致性无直接帮助。最后,若数据量不大,可考虑将缓冲区放在DTCM中,但需改用MDMA或CPU搬运,不推荐。
mcuku 阿沐 · 2026-10-16