STM32 使用DMA+双缓冲串口接收不定长数据时,如何避免总线竞争与缓存覆盖?

· 1 浏览

回答(4)

关键点:空闲中断里要立即禁用DMA(清EN位)再读NDTR,否则数据可能被新DMA写入覆盖;处理完再重新配置地址和长度,确保原子性。
嵌入式小兵 · 2026-08-27
总线竞争可考虑将DMA通道优先级设为最高,并开启AHB/APB桥的写缓冲;若用F4系列,建议用DMA2(挂AHB1)减少与CPU的SRAM冲突。
芯海拾遗 · 2026-08-27
用环形队列替代双缓冲更简单:DMA循环写入,CPU按读指针消费,配合空闲中断更新写指针,天然避免覆盖,但需注意队列大小与DMA缓冲对齐。
老周嵌入式 · 2026-08-27
核心方案:采用DMA双缓冲(Memory-to-Memory模式)配合空闲中断(IDLE)实现不定长接收,并利用乒乓机制隔离总线访问。具体实操:1) 配置两个缓冲区buf1/buf2,DMA循环模式交替填充,每次切换时在DMA传输完成中断中更新当前写指针;2) 串口空闲中断触发时,立即读取DMA剩余计数(NDTR)计算实际接收长度,并切换DMA目标地址到另一缓冲区,防止覆盖;3) 总线竞争方面,确保DMA和CPU访问不同缓冲区:CPU处理buf1时,DMA只写buf2,通过内存屏障(__DMB())和关中断保护临界区;4) 若数据率较高,可启用FIFO或双缓冲DMA(如STM32F4的DMA流双缓冲模式),硬件自动切换,减少中断开销。注意:空闲中断需在DMA传输完成前处理,否则可能丢帧;建议在中断中仅拷贝指针,数据处理放主循环。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器