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

· 15 浏览

回答(4)

如果允许,可考虑使用串口空闲中断+DMA单缓冲,配合环形队列,逻辑更简单,不易在切换时出错。
硬件小白 · 2026-09-09
丢字节常因中断优先级不够,建议将DMA中断设为最高优先级,并避免在中断里调用HAL库的阻塞函数。
码农阿强 · 2026-09-09
可以用DMA的循环模式+内存双缓冲,配合硬件半满/全满中断,但注意STM32F1系列无DBM,需手动切换或改用FIFO。
老周嵌入式 · 2026-09-09
核心思路是让DMA在双缓冲切换时保持连续接收,避免CPU干预导致的窗口期丢字节。实操建议:1) 使用STM32的DMA双缓冲模式(DBM),配置两个缓冲区大小相等,并开启传输完成中断(TC)和半传输中断(HT)。当HT触发时,CPU处理第一个缓冲区(已满),而DMA继续写入第二个;TC触发时处理第二个,DMA回写第一个,形成乒乓。2) 关键点:在中断服务函数中,先读取DMA的当前数据指针(如DMA_GetCurrDataCounter)或使用硬件半字/字节计数,确认缓冲区边界,再拷贝数据,避免在切换瞬间操作DMA寄存器。3) 若使用空闲中断(IDLE)判定帧结束,需确保在HT/TC中断中快速拷贝,并关闭全局中断或使用临界区保护,但时间要短(<1个字节传输时间)。4) 对于高速率(如1Mbps以上),建议增大缓冲区或改用FIFO+环形队列,减少中断频率。实测中,切换丢字节多因在TC中断里执行耗时操作(如printf),务必只做拷贝和标志置位。
mcuku 阿沐 · 2026-09-09

🧰 配套工具

🔗 波特率计算器