STM32 使用 DMA+双缓冲接收不定长串口数据时,如何避免缓冲区切换瞬间丢字节?

· 1 浏览

回答(4)

补充:若必须用双缓冲,建议在切换时利用DMA的传输完成中断,并在中断中先拷贝数据到用户缓冲区,再切换,同时确保中断优先级高于串口中断,避免数据覆盖。
STM32实战派 · 2026-08-27
补充:使用DMA的循环模式+空闲中断,配合软件环形队列,无需切换缓冲区,只需在空闲中断时读取DMA的当前数据位置,并更新读指针,这样从根本上消除切换问题。
码农小李 · 2026-08-27
补充:在切换缓冲区时,先关闭DMA传输(清EN位),等当前字节传输完成后(检查BSY标志),再更新M0AR/M1AR,最后重新使能,这样可彻底避免切换瞬间丢数据。
嵌入式老张 · 2026-08-27
避免缓冲区切换瞬间丢字节的关键在于确保DMA在切换时不会因缓冲区指针更新而错过新到达的数据。实操建议:1) 使用DMA的半传输和传输完成中断,在中断中处理数据,而不是在切换时直接修改DMA的M0AR/M1AR寄存器;2) 采用双缓冲模式时,确保在中断服务程序中先读取当前DMA的NDTR寄存器(剩余字节数),再切换缓冲区,因为NDTR反映的是硬件当前写入位置,可据此计算已接收数据;3) 若使用空闲中断(IDLE)配合DMA,建议在空闲中断中先禁用DMA(或暂停),处理完数据后再重新启用,避免切换瞬间硬件仍写入旧缓冲区;4) 考虑使用环形缓冲区(如基于DMA的循环模式),通过维护读写指针来避免切换,因为循环模式无需修改DMA地址,天然无切换开销。实际测试中,若波特率较高(如1Mbps以上),建议将DMA优先级设为最高,并确保中断响应时间小于一个字节传输时间(约10us@1Mbps),否则可考虑增加硬件FIFO或使用双缓冲+乒乓切换时在切换前等待当前传输完成。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器