根因是D-Cache与DMA的缓存一致性问题:DMA直接读写物理内存,而CPU可能访问的是D-Cache中的旧副本。接收时若该缓冲区曾被CPU读过,Cache中残留脏数据,DMA写入新数据后CPU仍读到旧值;发送时CPU写入的数据可能还在Cache未回写,DMA取到旧内存。H7无硬件缓存一致性,必须软件维护。实战做法:用MPU把DMA缓冲区配置为Non-Cacheable(如Normal, Non-cacheable, Shareable),一劳永逸;若必须Cacheable,则接收前Clean+Invalidate,接收后Invalidate,发送前Clean,且缓冲区按32字节对齐、大小取32字节整数倍,避免同一Cache Line被CPU与DMA同时触碰。注意SCB_InvalidateDCache_by_Addr会丢弃未回写数据,接收缓冲区在DMA期间CPU不得写入。
mcuku 阿沐 · 2026-09-19