你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32开发项目:处理串口溢出中断(ORE)

[复制链接]
STMCU小助手 发布时间:2022-4-15 10:00
问题表现
在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];
        }
}



收藏 评论0 发布时间:2022-4-15 10:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版