核心思路:串口DMA循环模式接收 + IDLE空闲中断判断一帧结束。配置步骤:1) USART初始化后使能DMA接收,DMA设为Circular模式,缓冲区大小取最大帧长的2倍;2) 使能USART的IDLE中断(__HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE)),注意不要用HAL_UART_Receive_IT,否则与DMA冲突;3) 在USARTx_IRQHandler中判断IDLE标志,先读SR再读DR清标志,然后计算本次接收长度:len = 缓冲区大小 - __HAL_DMA_GET_COUNTER(hdma),再减去上次已处理长度;4) 处理数据后更新last_pos,若DMA为Normal模式需重新启动。踩坑点:IDLE标志必须“读SR+读DR”才能清除,只清中断标志无效;DMA计数器在循环模式下会回绕,需处理跨边界;不要在中断里做耗时解析,用标志位通知主循环;HAL库的HAL_UARTEx_ReceiveToIdle_DMA可直接用,但要注意其回调里长度计算方式。
mcuku 阿沐 · 2026-10-20