STM32 使用 DMA 接收不定长串口数据时,如何利用空闲中断避免丢帧并处理粘包?

· 1 浏览

回答(4)

注意:IDLE中断标志要读SR再读DR清除,否则会误触发。另外,如果DMA缓冲区较小,可考虑用双缓冲切换,避免数据覆盖。
硬件工程师阿强 · 2026-08-27
粘包处理建议在协议层加帧头(如0xAA)和长度字节,解析时先找帧头再读长度,这样即使多帧连续也能正确拆分。
码农小刘 · 2026-08-27
我常用DMA循环模式+IDLE中断,在中断里用DMA_GetCurrDataCounter计算剩余空间,然后拷贝数据到环形缓冲区,主循环解析,这样既高效又不会丢帧。
嵌入式老张 · 2026-08-27
在STM32上使用DMA接收不定长串口数据时,空闲中断(IDLE)是处理不定长帧和避免丢帧的关键。首先,配置DMA为循环模式,并启用串口的IDLE中断(USART_IT_IDLE)。在IDLE中断服务函数中,读取USART->SR和USART->DR以清除IDLE标志,然后计算当前DMA接收到的数据长度(通过DMA_GetCurrDataCounter或寄存器),将数据从DMA缓冲区拷贝到应用缓冲区,并更新接收索引。为避免丢帧,需确保在IDLE中断中尽快处理数据,且DMA缓冲区大小要大于最大帧长,防止覆盖。对于粘包问题,可在每帧数据末尾添加帧尾(如0x0A)或使用帧头+长度字段,在解析时根据帧结构拆分。实操建议:使用双缓冲或环形队列存储数据,主循环中解析,避免中断中做复杂处理;同时,注意在IDLE中断中重新使能DMA接收(若使用非循环模式)。
mcuku 阿沐 · 2026-08-27