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

· 1 浏览

回答(4)

若帧头固定,可在IDLE中断中校验帧头合法性,非法则重置DMA指针,防止错位数据污染后续帧。
硬件工程师阿杰 · 2026-08-27
开启DMA传输完成中断(TC)作为辅助,当NDTR归零时切换缓冲,配合IDLE中断可处理连续多帧场景,减少丢帧概率。
码农小飞 · 2026-08-27
用环形队列管理双缓冲,接收中断只入队,主循环出队解析,可彻底避免覆盖。注意队列容量需覆盖最坏情况下的DMA延迟。
嵌入式老周 · 2026-08-27
核心思路:用双缓冲+空闲中断(IDLE)实现不定长帧的完整接收,并配合DMA的循环模式。具体做法:配置两个缓冲区buf1和buf2,DMA设为循环模式,使能USART的IDLE中断。在IDLE中断中,读取DMA的NDTR寄存器判断当前数据写入位置,从而确定哪个缓冲区已满或正在接收。处理时,先暂停DMA(清除EN位),拷贝已满缓冲区数据到应用层,再恢复DMA。关键点:1)缓冲区大小需大于最大帧长,且为2的幂便于取模;2)在IDLE中断中快速切换标志位,避免在中断里做耗时处理;3)若帧间隔小于DMA搬运时间,可增加超时机制(如定时器)兜底。实操建议:使用HAL库时,在UART_IdleCallback中调用HAL_UART_DMAStop()再处理,处理完重新启动DMA,并注意清除IDLE标志(先读SR再读DR)。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器