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

· 8 浏览

回答(4)

缓存覆盖最稳的解法是双缓冲+半传输中断,每半帧就切一次,配合空闲中断收尾,这样即使数据流长也不会丢,但代码复杂度高,适合高吞吐场景。
硬件工程师阿杰 · 2026-08-31
总线冲突本质是DMA和CPU争抢AHB,建议把DMA优先级设低,CPU访问SRAM用快速总线,同时处理数据时用memcpy到临时区,别直接操作DMA缓冲。
码农小张 · 2026-08-31
用空闲中断+DMA循环模式时,记得在中断里先读DMA计数器再切缓冲,顺序反了会丢数据。我习惯加个volatile标志位,主循环轮询处理,避免中断里做重活。
嵌入式老猫 · 2026-08-31
核心思路是采用双缓冲(乒乓缓冲)配合DMA循环模式,并利用空闲中断切换缓冲。具体做法:配置两个缓冲区buf1和buf2,DMA设置为循环模式,空闲中断触发时,先读取DMA当前剩余计数(DMA_GetCurrDataCounter)判断数据落在哪个缓冲,再立即切换DMA目标地址到另一个缓冲,同时处理已满缓冲的数据。为避免总线冲突,需在中断中关闭DMA传输(DMA_Cmd(DMAx_Channelx, DISABLE)),操作完再使能,并确保处理数据时使用memcpy快速搬移,避免长时间占用总线。缓存覆盖风险主要来自DMA仍在写入旧缓冲,因此切换后必须清空或标记旧缓冲为可写,且主循环处理数据时用互斥标志防止中断重复触发。实操建议:若数据量大,可升级为环形队列,用硬件半传输中断和传输完成中断分段处理,进一步降低冲突概率。
mcuku 阿沐 · 2026-08-31

🧰 配套工具

⏱️ 定时器计算器