STM32 使用 DMA 与空闲中断接收不定长数据时,如何避免总线冲突与缓存覆盖?

· 1 浏览

回答(4)

缓存覆盖的终极方案是使用硬件双缓冲(如STM32H7的MDMA或FIFO),或利用空闲中断+DMA的传输完成中断,在空闲时立即切换DMA目标地址,实现无缝切换。
嵌入式小飞侠 · 2026-08-27
总线冲突多源于DMA与CPU同时访问外设,可配置DMA为高优先级,并利用STM32的AHB总线矩阵特性,将外设和内存分配到不同总线,减少仲裁等待。
芯海拾贝 · 2026-08-27
用环形缓冲区+读写指针,DMA只负责写,主循环读,配合内存屏障和原子操作,可避免覆盖且无需双缓冲,但需注意DMA循环模式下的边界处理。
嵌入式老张 · 2026-08-27
核心策略是采用双缓冲(或环形缓冲区)配合DMA的半传输/全传输中断,而非仅依赖空闲中断。具体做法:1) 将DMA配置为循环模式,并分配两个大小相同的缓冲区(如各256字节),使能DMA的Half-Transfer和Transfer Complete中断;2) 在中断服务程序中,根据DMA当前指向的缓冲区(通过DMA_GetFlagStatus或读取NDTR寄存器判断),处理另一块缓冲区数据,同时确保主循环在访问缓冲区时关闭DMA中断或使用临界区保护;3) 空闲中断仅用于触发帧解析,不直接操作DMA缓冲区,避免与DMA写入冲突。这样即使总线繁忙,DMA持续接收,而CPU只处理已完成的缓冲区,从根本上防止覆盖。若使用单缓冲,则需在空闲中断后立即停止DMA并拷贝数据,但可能丢失后续数据。建议优先采用双缓冲方案,并注意DMA传输宽度与缓冲区对齐(如4字节对齐)以提升效率。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器