STM32串口溢出中断问题

这篇具有很好参考价值的文章主要介绍了STM32串口溢出中断问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

应用原理

STM32单片机与传感器通过串口通信,单片机串口采用中断方式接收传感器数据,同时单片机控制传感器上电。
stm32串口溢出错误原因,MCU,stm32,单片机,嵌入式硬件

问题描述

在一批设备中,有些设备开机能够正常读取传感器数据,有一小部分读取不到传感器的数据,出现了异常情况。

问题排查

1.确定传感器是否正常发数据

示波器测量传感器的TX,波形正常。

2.在线调试

在线调试模式下,在串口接收中断中打断点,发现异常的设备无法进入串口中断。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint8_t res;
	if(huart->Instance == USART4)//
	{
		USART4_RX_Buff[Usart4_RX_Cnt] = RX4_Buffer;
		if(USART4_RX_Buff[0]==0xff)
		{
		  Usart4_RX_Cnt++;
			if(Usart4_RX_Cnt>8) 
			{
				Usart4_RX_Cnt = 0;
				Usart4_RX_Flag = 1;
			}
		}
		else
		{
		 Usart4_RX_Cnt = 0;
		 Usart4_RX_Flag = 0;
		}	 
	 HAL_UART_Receive_IT(&huart4,&RX4_Buffer,1);//再次开启接收中断 
	}
}

这个时候查看串口相关参数,ErrorCode的值是8.
stm32串口溢出错误原因,MCU,stm32,单片机,嵌入式硬件
在stm32g0xx_hal_uart.h文件中,ErrorCode值为8表示Overrun error(溢出错误)。

/** @defgroup UART_Error_Definition   UART Error Definition
  * @{
  */
#define  HAL_UART_ERROR_NONE             ((uint32_t)0x00000000U)    /*!< No error                */
#define  HAL_UART_ERROR_PE               ((uint32_t)0x00000001U)    /*!< Parity error            */
#define  HAL_UART_ERROR_NE               ((uint32_t)0x00000002U)    /*!< Noise error             */
#define  HAL_UART_ERROR_FE               ((uint32_t)0x00000004U)    /*!< Frame error             */
#define  HAL_UART_ERROR_ORE              ((uint32_t)0x00000008U)    /*!< Overrun error           */
#define  HAL_UART_ERROR_DMA              ((uint32_t)0x00000010U)    /*!< DMA transfer error      */
#define  HAL_UART_ERROR_RTO              ((uint32_t)0x00000020U)    /*!< Receiver Timeout error  */

查看程序,发现使用STM32CubeMX配置软件时USART4的溢出中断配置为enable(默认配置,没有动),下面是窗口中断代码。

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
 uint32_t isrflags   = READ_REG(huart->Instance->ISR);
  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
  uint32_t cr3its     = READ_REG(huart->Instance->CR3);

  uint32_t errorflags;
  uint32_t errorcode;

  /* If no error occurs */
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
  if (errorflags == 0U)
  {
    /* UART in mode Receiver ---------------------------------------------------*/
    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
            || ((cr3its & USART_CR3_RXFTIE) != 0U)))
    {
      if (huart->RxISR != NULL)
      {
        huart->RxISR(huart);
      }
      return;
    }
  }

  /* If some errors occur */
  if ((errorflags != 0U)
      && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
           || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
  {
    /* UART parity error interrupt occurred -------------------------------------*/
    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
    {
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);

      huart->ErrorCode |= HAL_UART_ERROR_PE;
    }

    /* UART frame error interrupt occurred --------------------------------------*/
    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
    {
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);

      huart->ErrorCode |= HAL_UART_ERROR_FE;
    }

    /* UART noise error interrupt occurred --------------------------------------*/
    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
    {
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);

      huart->ErrorCode |= HAL_UART_ERROR_NE;
    }

    /* UART Over-Run interrupt occurred -----------------------------------------*/
    if (((isrflags & USART_ISR_ORE) != 0U)
        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
            ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
    {
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);

      huart->ErrorCode |= HAL_UART_ERROR_ORE;
    }

    /* UART Receiver Timeout interrupt occurred ---------------------------------*/
    if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
    {
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);

      huart->ErrorCode |= HAL_UART_ERROR_RTO;
    }
    /*省略若干代码*/
    errorcode = huart->ErrorCode;
      if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
          ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
      {
        /* Blocking error : transfer is aborted
           Set the UART state ready to be able to start again the process,
           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
        UART_EndRxTransfer(huart);
         /*省略若干代码*/
        }
}

从上述代码可以看出如果串口一切正常,是能够进入中断接收函数的,进入中断后会先关闭中断,接收中断执行完成后再次打开中断。

 if (errorflags == 0U)
  {
    /* UART in mode Receiver ---------------------------------------------------*/
    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
            || ((cr3its & USART_CR3_RXFTIE) != 0U)))
    {
      if (huart->RxISR != NULL)
      {
        huart->RxISR(huart);//进入串口接收中断,进入回调函数
      }
      return;
    }
  }

但是一旦出现溢出错误,在溢出错误中断中关闭的RX中断,因为代码是在正常的串口中断回调函数中再次打开接收中断,所以当溢出错误中断关闭了RX接收中断后,就再也无法进入接收中断了。

出现溢出中断的原因

示波器测量传感器电源和单片机RX波形,发现RX在上电之初有一个下降沿,此时单片机的中断还没打开。
stm32串口溢出错误原因,MCU,stm32,单片机,嵌入式硬件
实际测量串口初始化与打开串口中断之间大约有40ms的间隔。

  MX_USART4_UART_Init();
  MX_RTC_Init();
  MX_IWDG_Init();//实际上是这一个操作耗时大约40ms
  /* Initialize interrupts */
  MX_NVIC_Init();
  HAL_UART_Receive_IT(&huart4,&RX4_Buffer,1);//开启接收中断 

出现溢出中断的原因就是串口初始化之后单片机的RX引脚出现了一个下降沿,单片机认为是一个起始位,开始接收数据,但是这个时候串口中断还没打开,所以造成了溢出中断。
STM32的数据手册是这样描述的:
stm32串口溢出错误原因,MCU,stm32,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-730431.html

解决方法(软件处理)

  1. 配置串口时,溢出中断配置为disenable,也就是说关闭溢出中断。
  2. 串口的RX引脚配置为上拉模式。
  3. 串口初始化之后立即打开中断。
    以上任意一种方式都可以解决,为了防止出现其他不可控问题,3条处理方式我都使用。

到了这里,关于STM32串口溢出中断问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • # STM32系列-串口-uart-软件引脚内部上拉 或者 外部电阻上拉-原因问题的搜寻

    最近,在调试uart串口的时候,被要求,要在串口初始化的时候,将引脚设为上拉。由此想到了为什么要上拉这个问题,但上网查了资料,发现大部分都是是说RX应该上拉,但是为什么上拉,没有什么人说的清楚,于是想深入找下原因。 预先假设问题,知道自己要问什么,缕清

    2024年02月01日
    浏览(42)
  • STM32_串口中断接收数据_空闲中断

    引言: 1、串口中断接收数据首先要保证完整性(设置串口中断优先级) 2、串口中断接收数据要保证实时性(打开串口空闲中断——空闲时间是2个字节的时间) 3、串口中断接收+DMA缓存,等到需要处理时候在进行处理数据 方法一:直接利用stm32的RXNE和IDLE中断进行接收不定字

    2024年02月13日
    浏览(51)
  • STM32(HAL)串口中断接收

    目录 1、简介 2 基础配置 2.1.1 SYS配置  2.1.2 RCC配置 2.2 串口外设配置  2.3 项目生成  3、KEIL端程序整合 本文对HAL串口中断函数进行介绍。 2.1.1 SYS配置  2.1.2 RCC配置 首先在main.c文件中进行接受变量声明。  接着在主函数的while循环中进行接收中断,如下所示:  最后在主函数

    2024年02月14日
    浏览(53)
  • STM32使用中断及串口通信

    采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。单片机除了基本的连线外,我们另外只接一只LED灯。 使用外部中断的基本步骤如下: 1.设置对应时钟 2.设置中断 3.初始化IO 4. 把特定IO口设置为中断线路进行初始化 5. 在中断通道的响应函数中中断函数

    2024年02月04日
    浏览(51)
  • # STM32中断方式实现串口通信(标准库)

    主要任务 : 1)当stm32接收到字符“s”时, 停止持续发送 “hello windows!”; 当接收到字符“t”时, 持续发送 “hello windows!”; 2)当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!” 实验工具: (1)软件 标

    2024年02月11日
    浏览(34)
  • STM32基于HAL库的串口接受中断和空闲中断

    在通信方面。UART由于全双工通信,可以同时接受数据和发送数据而被广泛使用。 而接受数据则又有很多种方法 比如: 1根据结束符判断,数据是字符串形式,所以一般串口接受的接受符就是 \\\"rn\\\"  换成16进制ascil码显示就是 0X0D   0X0A (对应rn)  2定时器中断,设计\\\"喂狗信号量

    2023年04月08日
    浏览(49)
  • 【STM32】HAL库 串口中断发送与接收

    【STM32】HAL库 新建MDK工程 【STM32】HAL库 串口轮询发送 使用stm32串口中断发送和中断接收 在主函数前开启中断,接受字节数为5 接受5个字节后,进入中断接收完成回调函数,重新再开启中断,并把接收到的数据返回 修改接收数组长度,改为开启串口空闲中断 接收事件回调函数

    2024年02月08日
    浏览(62)
  • STM32 HAL库 串口中断接收数据包

    目录 一、CUBEmx配置 1.设置系统时钟,配置SYS,配置时钟树  ​编辑  2.配置串口USART1 3.配置NVIC,开启串口中断 ​编辑4.点击GENERATE CODE输出文件即可 二、代码部分 0.串口重定向——printf 1.关于舵机 2.开启串口中断函数 3.编写串口回调函数 4.主函数部分 三、实验现象: 四、总

    2024年02月04日
    浏览(44)
  • stm32_断点调试无法进入串口接收中断

    先说结果,可能是stm32调试功能/keil软件/调试器(试过STLINK和JLINK两种)的问题,不是代码; 配置完串口后,可以发送数据到串口助手,但不能接收数据并做处理,所以第一步,想确定有没有接收到单个字节进入中断。 开始打断点调试,发现串口数据寄存器DR能收到数据,串

    2024年02月08日
    浏览(49)
  • 十、stm32-ESP8266(串口透传、MCU透传、控制LED亮灭)

    见博客:stm32f103c8t6新建固件库模板(可自取) 固件库模板 MDK5开发环境 stm32参考手册 UART串口协议 stm32中断概念 ESP8266模块资料 利用固件库模板点灯工程(下面第三行,手动狗头) CH340 USB→TTL模块 ESP8266模块 手机软件 实验程序已经发布到百度网盘,本文末有链接可以自取

    2023年04月19日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包