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

· 1 浏览

回答(4)

考虑用硬件双缓冲(如STM32F4的DMA双缓冲模式),它自动切换地址,比软件乒乓更可靠;但需注意缓冲区对齐到32字节,且两个缓冲区大小一致,否则DMA会异常。
芯语无声 · 2026-08-27
如果数据帧间隔很短,建议将IDLE中断优先级设为最高,并避免在中断内做耗时处理(如memcpy),只置标志位,主循环再解析,否则可能错过下一帧起始字节。
嵌入式老周 · 2026-08-27
用HAL库时,注意在IDLE回调中先读DMA的NDTR,再操作缓冲区,因为NDTR是实时值,能精确反映未接收字节数,避免因中断延迟导致计数偏差。
码农小张 · 2026-08-27
核心思路是让DMA始终处于接收状态,避免在切换缓冲区时关闭DMA导致丢字节。推荐使用STM32的DMA循环模式(Circular Mode)+ 双缓冲(Memory-to-Memory或外设到内存),并利用空闲中断(IDLE)判断一帧结束。具体实操:1)配置DMA为循环模式,双缓冲地址交替由硬件自动切换,无需软件干预;2)在IDLE中断中,读取DMA当前剩余计数(NDTR)和当前目标缓冲区索引,计算已接收数据长度,并立即处理该缓冲区,同时确保另一缓冲区仍由DMA写入;3)切换时不要禁用DMA,只需更新软件指针。若使用非循环模式,需在DMA传输完成中断中手动切换,此时必须保证切换前DMA已停止,但可用乒乓缓冲(Ping-Pong)预切换:先让DMA写Buffer A,软件处理Buffer B,当A满时DMA自动切到B,同时软件处理A,这样切换瞬间无空窗。另外,可启用FIFO或双缓冲的硬件半传输/全传输中断,提前处理数据,减少IDLE中断延迟。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器