STM32 使用 DMA 与环形缓冲区接收不定长串口数据时,如何精确处理帧边界与超时判断?

· 1 浏览

回答(4)

如果协议有固定帧头,可以在DMA接收时用硬件比较器或空闲中断后扫描帧头,但更简单的是在IDLE中断里直接解析,超时用定时器,别用阻塞延时。
硬件控阿杰 · 2026-08-27
环形缓冲区要处理好回绕,计算帧长度时用 (写指针 - 读指针 + 缓冲区大小) % 缓冲区大小。另外,DMA的CNDTR是递减的,别搞反了。
码农小刘 · 2026-08-27
用DMA+IDLE中断最省CPU,但IDLE有时会漏(如连续字节间隔略长),建议加一个1ms定时器中断,在IDLE时清零,定时器溢出则视为帧尾,双重保险。
嵌入式老张 · 2026-08-27
处理不定长串口帧的关键在于区分“字节间超时”和“帧间超时”。推荐使用DMA接收+空闲中断(IDLE)检测帧结束,同时配合定时器实现超时兜底。具体做法:1)配置DMA为循环模式,接收数据写入环形缓冲区;2)使能USART的IDLE中断,当总线空闲时(即一帧数据结束),在中断中记录当前DMA接收位置,并计算本次帧长度(当前位置减去上次帧尾位置,注意环形回绕);3)若帧间间隔较长(如RS485半双工切换),可额外启动一个基本定时器,在IDLE中断中重置定时器,若定时器溢出(如10ms)则强制认为帧结束,防止IDLE漏检。帧边界处理时,需在环形缓冲区中维护读指针和写指针,写指针由DMA更新(通过DMA_GetFlagStatus或直接读取DMA->CNDTR),读指针由协议解析代码维护。注意:DMA循环模式下,CNDTR递减,需用缓冲区大小减去CNDTR得到当前写位置。超时判断建议用硬件定时器而非软件延时,避免阻塞。最后,解析帧时先检查帧长度是否有效(如包含帧头帧尾校验),再处理数据,防止半帧。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器