STM32 HAL库中DMA串口接收空闲中断与半满中断的配合使用及丢包排查

· 行业用户 · 5 浏览

回答(4)

回调里别直接解析协议,只记录Size和拷贝指针,主循环消费。中断里做printf或Flash操作是丢包重灾区。
硬件阿杰 · 2026-11-12
丢包先查ORE溢出:HAL_UART_ErrorCallback里必须HAL_UART_AbortReceive再重新ReceiveToIdle_DMA,否则DMA请求被清后永远收不到数据。
码农小陈 · 2026-11-12
半满中断本质是DMA传输过半,不是串口事件。若包长普遍小于缓冲区一半,半满几乎不触发,别指望它救场,重点还是空闲中断加及时重启。
嵌入式老张 · 2026-11-12
在STM32 HAL库中,串口DMA接收通常用HAL_UARTEx_ReceiveToIdle_DMA配合空闲中断实现不定长收包,同时HAL库会默认开启DMA半满中断。半满中断在缓冲区收到一半时触发,空闲中断在一帧结束总线空闲时触发,二者配合可降低大包延迟:半满时先处理前半段数据,空闲时处理剩余部分。排查丢包时重点看:1)回调中是否及时用HAL_UARTEx_GetRxEvent获取Size并重启接收,重启前不要做耗时操作;2)半满与空闲回调里对同一缓冲区的读写指针是否加临界区保护,避免主循环与中断竞争;3)DMA缓冲区是否过小导致半满频繁触发而空闲迟迟不来;4)检查UART错误标志ORE/FE/NE,HAL_UART_ErrorCallback中需清除并重启DMA,否则一次溢出后DMA停摆造成持续丢包;5)确认DMA通道优先级与中断优先级配置,避免高优先级中断长时间阻塞。建议用双缓冲或环形缓冲+空闲中断方案,并在回调中只置标志,主循环处理数据。
mcuku 阿沐 · 2026-11-12