STM32串口中断卡死主循环一直进中断问题分析

发布者:太和清音最新更新时间:2022-08-08 来源: csdn关键字:STM32  串口中断  主循环 手机看文章 扫描二维码
随时随地手机看文章

在一项目中,使用STM32作为主控,程序运行一段时间后概率出现主循环卡死现象。


问题分析如下:

1、程序USART2不停接收并处理串口数据,波特率115200;

2、主循环卡死;

3、USART1中断及TIM2中断响应函数运行正常;(USART1及TIM2中断优先级均比USART2高)

4、出现现象后,拔掉USART2的接收数据线,现象不能回复正常;

5、出现现象后,拔掉后再插入USART2的接收数据线,现象不能回复正常;

6、并未出现HardFault现象;


基于以上4点,可能原因如下:

1、USART2接收中断标志没有清除;

2、堆栈数据溢出,导致程序异常;

        3、USART2中断重入导致异常;

4、USART2中断函数被异常响应;

        5、USART2中断ERR;

对于以上可能原因一一分析:

1、中断接收标志清楚问题:

(1)USART2接收中断响应函数如下:

void USART2_Istr(void)

    {  

        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)

        {   

            USART_ClearFlag(USART2, USART_FLAG_RXNE);

            USART_ClearITPendingBit(USART2, USART_IT_RXNE);

            Data = USART_ReceiveData(USART2);

            //Process Data

        }

    }


(2)出现现象后,通过Usart1中断获取到如下信息:

a. USART_GetITStatus(USART2,  USART_IT_RXNE)  == RESET

b. USART_GetFlagStatus(USART2,  USART_FLAG_RXNE)  == RESET

c. 执行USART_ClearFlag(USART2, USART_FLAG_RXNE)及 USART_ClearITPendingBit(USART2, USART_IT_RXNE)后无法恢复正常;

 结论:与USART2 RXNE中断标志无关。


2、堆栈数据溢出,导致程序异常;

(1)使用2倍栈空间,问题存在,概率不会降低;

(2)使用0.5倍栈空间,问题存在,概率不会提高;

(3)使用0.25倍栈空间,程序运行进入HardFault;

结论:与堆栈无关。


3、USART2中断重入导致异常;

(1)使用标志法,确认出现问题时,中断响应函数没有重入;

结论:中断响应函数没有重入。


4、USART2中断函数被异常响应;

(1)USART2中断函数可以被正常调用,只是不停进入中断响应函数,卡死主循环;

(2)检查程序Map,没发现与中断响应函数地址相同的函数;

(3)检查中断向量表,没发现异常;

结论:中断函数没有被异常调用;


5、USART2中断ERR;

(1)关闭USART2中断,主循环恢复正常;

(2)启动USART2中断,主循环卡死;

(3)获取到DR=0x0000;

(4)USART_GetITStatus取到:RXNE=0,PE=0,TXE=0,TC=0,IDLE=0,LBD=0,CTS=0,ERR=0,ORE=0,NE=0,FE=0;

(5)通过USART_ClearITPendingBit清除CTS,LBD,TXE,TC,RXNE,IDLE,ORE,NE,FE,PE均无法恢复正常;

(6)通过USART_GetFlagStatus:

  a.第一次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=1,ORE=1,NE=0,FE=0,PE=0

b.第二次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=0,ORE=0,NE=0,FE=0,PE=0

c.第三次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=0,ORE=0,NE=0,FE=0,PE=0

(7)通过USART_ClearFlag清除CTS,LBD,TXE,TC,RXNE,IDLE,ORE,NE,FE,PE均无法恢复正常;

分析:

(1)为什么通过USART_GetITStatus获取了所有中断标志,均为RESET(TC、TXE中断没开),还会进中断?

(2)为什么通过USART_ClearITPendingBit清除了所有中断标志,还会进入中断?

(3)为什么关闭USART2中断后再次启动它还会进入卡死状态?

(4)为什么通过USART_GetFlagStatus第一次和第二次读的不一样?而且USART_ClearFlag清掉所有Flag,也没法恢复正常?


带着以上几个疑问,查看了参考手册,才恍然大悟!如下:

(1)打开RXNEIE,默认会同时打开RXNE和ORE中断。


(2)必须第一时间清零RXNE,如没及时清零,下一帧数据过来时就会产生Overrun error!


(3)错误就是ORE导致的

出现错误时,读了RXNE=0,出错应该是上图打勾的情况,如下


(4)如文档说明,要清除ORE中断需要按顺序读取USART_SR和USART_DR寄存器

那就是说USART_ClearFlag清掉所有Flag后,还必须读一遍USART_DR寄存器!

      经过测试出现问题后依次读读取USART_SR和USART_DR,程序回复正常!


(5)那还有一个问题,为什么USART_GetITStatus读不到ORE中断标志?

读USART_GetITStatus函数就知道了,只有CR3的EIE置1且SR的ORE置1,读出来USART_GetITStatus(USART2,  USART_IT_ORE)  才是 SET。

见CR3的EIE位说明。


解决办法,出现通过接收时,通过USART_GetFlagStatus读取ORE,若不为RESET,则读取DR数据丢弃。

修改如下:


void USART2_NewIstr(void)

    {  

        if (USART_GetFlagStatus(USART2, USART_FLAG_PE) != RESET)

       {

           USART_ReceiveData(USART2);

         USART_ClearFlag(USART2, USART_FLAG_PE);

       }

        

       if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)

       {

           USART_ReceiveData(USART2);

         USART_ClearFlag(USART2, USART_FLAG_ORE);

       }

        

        if (USART_GetFlagStatus(USART2, USART_FLAG_FE) != RESET)

       {

           USART_ReceiveData(USART2);

          USART_ClearFlag(USART2, USART_FLAG_FE);

       }

        

        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)

        {   

            USART_ClearFlag(USART2, USART_FLAG_RXNE);

            USART_ClearITPendingBit(USART2, USART_IT_RXNE);

            Data = USART_ReceiveData(USART2);

        }

    }


总结:

1、看文档!看文档!还是看文档!(重要的事情要说3遍)

2、库函数用的时候,也要注意其实现,稍有不慎就可能用错。

3、注意USART_GetFlagStatus与USART_GetITStatus的区别,还有中断响应机制。

4、任意时候都要考虑出错处理。


关键字:STM32  串口中断  主循环 引用地址:STM32串口中断卡死主循环一直进中断问题分析

上一篇:STM32学习之CAN控制器简介
下一篇:STM32 CAN通信滤波设置问题

推荐阅读最新更新时间:2024-11-17 02:28

STM32技巧: Keil错误提示“ File Not Found”
1、文件已添加到工程目录但提示“file not found” 原因:仅添加到目录但未包含编译文件的路径 解决: Option- C/C++- Include Paths,添加提示缺失的文件所在路径。错误提示消失。
[单片机]
<font color='red'>STM32</font>技巧: Keil错误提示“ File Not Found”
STM32 | 基于STM32实现的普通灯泡调光控制器
功能 用STM32控制一个普通灯泡的亮度,一路开关控制普通灯泡电源的通断,另外两路开关分别控制普通灯泡亮度的增加和减小。 调光控制器的原理 通过STM32控制双向可控硅的导通来实现白炽灯(纯阻负载)亮度的调整。双向可控硅的特点是导通后即使触发信号去掉,它仍将保持导通;当负载电流为零(交流电压过零点)时,它会自动关断。 所以需要在交流电的个半波期间都要送出触发信号,触发信号的送出时间就决定了灯泡的亮度。 调光的实现方式就是在过零点后一段时间才触发双向可控硅开关导通,这段时间越长,可控硅导通的时间越短,灯的亮度就越低;反之,灯就越亮。这就需要提取出交流电压的过零点,并以此为基础,确定触发信号的送出时间,达到调光的目的。
[单片机]
<font color='red'>STM32</font> | 基于<font color='red'>STM32</font>实现的普通灯泡调光控制器
stm32之GPIO配置及库函数学习笔记——以流水灯为例
1.GPIO全称:gpio general-purpose input/output 通用输入/输出端口 2.GPIO寄存器中文名称与英文缩写对照表 3.GPIO_InitTypeDef结构体定义 typedef struct { uint16_t GPIO_Pin;//选择待设置的GPIO引脚 GPIOSpeed_TypeDef GPIO_Speed;//设置选中管脚的速率 GPIOMode_TypeDef GPIO_Mode;//设置选中管脚的工作状态(模式) }GPIO_InitTypeDef; 4.GPIO_Mode:端口的每个位可以分别配置成多种模式,中文名称与英文缩写对照表如下:
[单片机]
<font color='red'>stm32</font>之GPIO配置及库函数学习笔记——以流水灯为例
STM32串口中断接收和中断发送
先贴出中断函数: void USART1_IRQHandler(void){ if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_RXNE); USART1_Buffer =USART_ReceiveData(USART1); //USART1_Buffesh是一个自己定义的接收数组 if(i 3){ SendFlag = 1; } } if(USAR
[单片机]
STM32中为什么要引入链表?
1、为何引入链表 在程序中经常面临一个问题,我们需要保存一定数量的对象,但是对象数目是不确定的,或者说是随时增加或减少的。这时候最简单的方法是创建一个足够大的数组,用来存储这些对象。我最近开发一个项目就遇到类似的问题,下面我把问题简化一下。 需求:通过PC下发一些矩形的坐标和宽高信息,每个区域有个ID编号,并在这些矩形内填充一定的数据。 通常情况下,最简单易懂的做法是,限制最多5个区域,每个区域存储1K数据。因此设置了这样的一个结构体(类似于面向对象语言里说的成员属性)。 typedef struct Area_Inf{ uint8_t ID; uint8_t X; uint8_t Y; uint8_t Width;
[单片机]
在<font color='red'>STM32</font>中为什么要引入链表?
STM32 UART(接收 ,发送数据)
UART接收发送数据: 平台:STM32F401 discovery版 此代码用的UART6,TX,RX对应的PIN脚是PC6,PC7 如图: 代码如下: 步骤一:初始化串口的GPIO,USART,并且配置上UART的RX中断 void USART6_Config(void) { USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clock */ RCC_AHB1Per
[单片机]
<font color='red'>STM32</font> UART(接收 ,发送数据)
意法STM32系列获ARM RealView微控制器开发工具包支持
ARM公司日前宣布RealView微控制器开发工具包将支持意法半导体基于ARM Cortex-M3处理器的全新STM32F1xx系列器件。 STM32F101(接入行)和STM32F103(性能行)将是意法半导体首个基于ARM Cortex-M3处理器的器件系列,兼具卓越的高性能和低功耗。该系列器件拥有高达72MHz的CPU时钟速度、128Kbyte片上闪存ROM及20Kbyte片上RAM,还包括A/D、CAN、USB、SPI、I2C等众多外设及多达80个GPIO。 RealView微控制器开发工具包3.1可为新器件提供支持。这一最新版本保留了Keil Vision 3集成开发环境(IDE)易于使用的特性,并增加了针对STM3
[焦点新闻]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved