
问题表现 在MCU系统负载较重、串口收发数据频率很高、多个中断存在(如同时有定时器更新中断、外部中断、DMA中断、串口接收中断)的情况下,容易出现串口溢出错误(ORE)。该错误的主要显现形式是:程序莫名卡死在串口中断之中(单片机失去响应)。 解决方法 ORE标志位在USART_SR寄存器,当我们打开串口接收中断时,同时也就打开了ORE中断,串口的overload错误会导致程序反复进入串口中断服务程序。在中断服务程序中增加处理overload的处理,顺序执行对USART_SR和USART_DR寄存器的读操作可以复位ORE位,以防止程序反复进入串口中断服务程序。示例代码如下: 在STM32中断函数增加USART_IT_ORE等异常中断的处理,执行USART_GetFlagStatus(USART1, USART_FLAG_ORE),会对USART_SR进行了一次读操作,然后再执行USART_ReceiveByte(USART1),会对USART_DR进行一次读操作,从而复位了ORE位。 /** * @brief Checks whether the specified USART flag is set or not. * @param USARTx: Select the USART or the UART peripheral. * This parameter can be one of the following values: * USART1, USART2, USART3, UART4 or UART5. * @param USART_FLAG: specifies the flag to check. * This parameter can be one of the following values: * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) * @arg USART_FLAG_LBD: LIN Break detection flag * @arg USART_FLAG_TXE: Transmit data register empty flag * @arg USART_FLAG_TC: Transmission Complete flag * @arg USART_FLAG_RXNE: Receive data register not empty flag * @arg USART_FLAG_IDLE: Idle Line detection flag * @arg USART_FLAG_ORE: OverRun Error flag * @arg USART_FLAG_NE: Noise Error flag * @arg USART_FLAG_FE: Framing Error flag * @arg USART_FLAG_PE: Parity Error flag * @retval The new state of USART_FLAG (SET or RESET). */ FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) { FlagStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_FLAG(USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */ if (USART_FLAG == USART_FLAG_CTS) { assert_param(IS_USART_123_PERIPH(USARTx)); } if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) { bitstatus = SET; } else { bitstatus = RESET; } return bitstatus; } /** * @brief Returns the most recent received data by the USARTx peripheral. * @param USARTx: Select the USART or the UART peripheral. * This parameter can be one of the following values: * USART1, USART2, USART3, UART4 or UART5. * @retval The received data. */ uint16_t USART_ReceiveByte(USART_TypeDef* USARTx) { /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); /* Receive Data */ return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); } void USART1_IRQHandler(void) { /** * 如果使能串口接收中断,那么ORE为1时也会产生中断。 * 在应用中对ORE标志进行处理,当判断发生ORE中断的时候, * 我们再读一次USART_DR的值, * 这样如果没有新的Overrun 溢出事件发生的时候,ORE会被清除, * 然后程序就不会因为ORE未被清除而一直不断的进入串口中断 */ //没有使能USART_IT_ERR中断时,ORE中断只能使用USART_GetFlagStatus(USART1, USART_FLAG_ORE)读到 if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) { //(void)USARTx->SR; //(vois)USARTx->DR; //先读SR再读DR寄存器 USART_ReceiveByte(USART1); //USART_ClearFlag(USART1, USART_FLAG_ORE); } //处理接收到的数据(示例为FIFO缓冲队列) if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_RXNE); *USART_RevPointer[0][0] = (u8) USART_ReceiveByte(USART1); USART_RevPointer[0][0]++; USART_RevCount[0]++; if (USART_RevPointer[0][0] >= USART_RevBuffer[0] + USART_BufferSize[0]) USART_RevPointer[0][0] = USART_RevBuffer[0]; } } |
【下载有礼】STM32 Finder华为应用商店正式上线!移动选型工具助力开发效率升级
【2025·STM32峰会】GUI解决方案实训分享5-调通板载的NRF24L01 SPI接口并使用模块进行无线通信(发送和接收)
【2025·STM32峰会】GUI解决方案实训分享2-编译运行TouchGFX咖啡机例程(含桌面仿真)
实战经验 | Keil工程使用NEAI库的异常问题
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命