STM32H7串口DMA空闲中断数据采集异常
- 代号
- 问题描述
- 原因
- 解决方法
代号
主机:STM32H7单片机
从机:其他串口模块(固定频率盲发输出)
问题描述
主机和从机通过串口进行通信,主机串口使用DMA+空闲中断进行数据接收,从机定时发数据给主机。现在主机先启动,从机后启动,串口接收异常;主机后启动,从机先启动,开始工作异常,从机端重启后,主机串口工作又异常了(串口中断无法响应)
原因
STM32H7 的 USART 一旦出现 ORE(溢出错误),硬件会永久停止向 DMA 发请求,并关闭串口中断; 而其他模块上电 瞬间噪声 / 毛刺 → 极易触发 ORE 。 ORE(Overrun Error)是 串口收到新字节,但RDR 寄存器 / 硬件 FIFO 里的旧数据还没被 DMA 搬走的情况。 且必须 手动清除 ORE 标志,硬件才会恢复工作 。
解决方法
调用 HAL_UART_ErrorCallback ,在其中实现清异常标志位,以及重启串口接收 。
// An highlighted blockvoidUART_DMA_Restart(UART_HandleTypeDef*huart,uint8_t*buf,uint16_tlen){// 1. 停止 DMAHAL_UART_DMAStop(huart);// 2. 【核心】强制清除所有硬件错误标志(H7 必须手动清!)__HAL_UART_CLEAR_FLAG(huart,UART_FLAG_ORE|UART_FLAG_FE|UART_FLAG_NE|UART_FLAG_RXNE|UART_FLAG_IDLE);// 3. 禁用再启用 UART 硬件(彻底解锁状态机)__HAL_UART_DISABLE(huart);__HAL_UART_ENABLE(huart);// 4. 重新启动 DMAHAL_UARTEx_ReceiveToIdle_DMA(huart,buf,len);}voidHAL_UART_ErrorCallback(UART_HandleTypeDef*huart){if(huart->Instance==UART8)// 串口{// 出错直接重启!UART_DMA_Restart(&huart8,uart_handle[COM_UART8].p_rx_buf,UART_BUF_SIZE);}else{}}