STM32H750串口一直进IRQ问题解决

STM32H750串口一直进IRQ问题解决
问题 void USART2_IRQHandler(void) { UART2_XSP26A_IRQ();}就是我如果打过断点那么程序就一直仅在这个IRQ函数里面里面运行不打断点就可以一直在外部运行为什么解决 UART 中断里不要用 HAL_UART_Receive()改成直接读寄存器RDR中断里只做“收字节、置标志、清标志”解析放主循环。这样断点调试会稳定很多。 主要是“非阻塞接收”修复的。 之前的问题核心是HAL_UART_Receive(huart2_xsp26a, …, 1U, 1000U);这个函数是阻塞式的放在中断里不合适。你打断点后串口硬件继续跑等继续运行时中断标志、接收状态、超时状态容易堆在一起表现成一直进IRQ。 现在改成 uint8_t rx_data (uint8_t)(huart2_xsp26a.Instance-RDR 0xFFU); 读 RDR 是立即完成的不等待、不超时、不走 HAL 的接收状态机所以中断很快退出之前“卡在 IRQ里”的问题就没了。 ORE/FE/NE 清除是辅助修复 防止已经产生的错误标志一直挂着。 防止溢出/噪声/帧错误导致中断反复进入。对调试断点场景尤其有帮助。 所以结论 主要原因中断里用了阻塞式 HAL_UART_Receive() 主要修复改成中断里直接读 RDR辅助修复清除 ORE/FE/NE 错误标志 如果只清 ORE/FE/NE但继续在 IRQ 里用HAL_UART_Receive()问题大概率还会出现。/*OREOverrun Error溢出错误。新字节来了但上一个字节还没及时从 RDR 读走硬件接收寄存器被覆盖或丢数据。 FEFraming Error帧格式错误。常见原因是波特率不匹配、停止位异常、线被干扰。 NENoise Error噪声错误。RX 线上有干扰采样不稳定。 */voidUART2_XSP26A_IRQ(void){if(__HAL_UART_GET_IT(huart2_xsp26a,UART_IT_RXNE)!RESET){uint8_trx_data(uint8_t)(huart2_xsp26a.Instance-RDR0xFFU);if((uart2_xsp26a_tr.uart_rx.recv_flag0U)(uart2_xsp26a_tr.uart_rx.rx_lenRX_SIZE)){uart2_xsp26a_tr.uart_rx.rx_buffer[uart2_xsp26a_tr.uart_rx.rx_len]rx_data;uart2_xsp26a_tr.uart_rx.rx_len;}else{(void)rx_data;uart2_xsp26a_tr.uart_rx.rx_len0U;uart2_xsp26a_tr.uart_rx.recv_flag0U;}}if(__HAL_UART_GET_IT(huart2_xsp26a,UART_IT_IDLE)!RESET){__HAL_UART_CLEAR_IDLEFLAG(huart2_xsp26a);if((uart2_xsp26a_tr.uart_rx.rx_len0U)(uart2_xsp26a_tr.uart_rx.recv_flag0U)){uart2_xsp26a_tr.uart_rx.recv_flag1U;}}if(__HAL_UART_GET_FLAG(huart2_xsp26a,UART_FLAG_ORE)!RESET){__HAL_UART_CLEAR_OREFLAG(huart2_xsp26a);}if(__HAL_UART_GET_FLAG(huart2_xsp26a,UART_FLAG_FE)!RESET){__HAL_UART_CLEAR_FEFLAG(huart2_xsp26a);}if(__HAL_UART_GET_FLAG(huart2_xsp26a,UART_FLAG_NE)!RESET){__HAL_UART_CLEAR_NEFLAG(huart2_xsp26a);}}