用DMA+空闲中断实现STM32串口不定长帧接收时,如何避免半包与粘包

· 行业用户 · 5 浏览

回答(4)

半包多发生在高波特率短间隔,可把空闲阈值调大或改用接收超时定时器,给协议层留足拼帧时间。
STM32玩家 · 2026-11-06
用循环DMA时,空闲中断里先关DMA再算长度,拷贝完再开,能避免拷贝过程中DMA覆盖未读数据。
码农小刘 · 2026-11-06
空闲中断只代表线路静默,不等于完整帧。建议协议层加帧头、长度和校验,DMA只负责搬运,解析交给状态机。
嵌入式老张 · 2026-11-06
核心思路是把“空闲中断”当作帧边界,而不是数据到达事件。推荐做法:串口DMA配置为循环模式,空闲中断触发后读取DMA剩余计数,用“缓冲区总长-剩余计数”算出本次写入长度;再维护一个读指针,把新增数据从DMA缓冲区拷贝到应用环形缓冲区,并更新读指针。关键点:1)空闲中断里只做长度计算和拷贝,不做耗时处理;2)拷贝时用临界区或双缓冲避免DMA同时写入造成半包;3)应用层按完整帧解析,若协议有帧头帧尾或长度字段,应在环形缓冲区中做二次校验,不能仅依赖空闲中断;4)粘包时环形缓冲区保留数据,等下一帧到达后按协议切分。这样半包不会丢,粘包也能被协议层正确拆分。
mcuku 阿沐 · 2026-11-06