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

2023-10-30

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

问题分析如下:
1、程序USART2不停接收并处理串口数据,波特率115200;

2、主循环卡死;

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

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

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

6、并未出现HardFault现象;
基于以上几点,可能原因如下:

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均无法恢复正常;

分析:

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

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

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

  • 为什么通过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、任意时候都要考虑出错处理。

原文:https://blog.csdn.net/origin333/article/details/49992383

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32串口中断卡死主循环一直进中断问题分析-2021-10-05 的相关文章

  • GCC - 如何停止链接 malloc?

    我正在努力将我的代码缩减到最小的骨架大小 我使用的是只有 32k 闪存的 STM32F0 需要很大一部分闪存用于数据存储 我的代码已经有大约 20k 闪存大小 其中一些是由于使用了 STM32 HAL 函数 我可以在以后需要时对其进行解释和
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • STM32 GPIO工作原理详解

    STM32 GPIO介绍 1 STM32引脚说明 GPIO是通用输入 输出端口的简称 是STM32可控制的引脚 GPIO的引脚与外部硬件设备连接 可实现与外部通讯 控制外部硬件或者采集外部硬件数据的功能 以STM32F103ZET6芯片为例
  • SHT10温湿度传感器——STM32驱动

    实验效果 硬件外观 接线 3 3V供电 IIC通讯 代码获取 查看下方 END
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • 算法——树查找算法

    树查找 对于层次结构的树 需要遍历其节点 根据遍历方式不同 可分为广度优先和深度优先 对于如下树结构 class TreeNode
  • 入门级题解:剑指 Offer 09. 用两个栈实现队列

    题目 用两个栈实现一个队列 队列的声明如下 请实现它的两个函数 appendTail 和 deleteHead 分别完成在队列尾部插入整数和在队列头部删除整数的功能 若队列中没有元素 deleteHead 操作返回 1 读题 队列 先入先出
  • mnist数据集彩色图像_使用MNIST数据集构建多类图像分类模型。

    mnist数据集彩色图像 Below are the steps to build a model that can classify handwritten digits with an accuracy of more than 95
  • 大数据的关键技术

    在大数据时代 传统的数据处理方法还适用吗 大数据环境下的数据处理需求 大数据环境下数据来源非常丰富且数据类型多样 存储和分析挖掘的数据量庞大 对数据展现的要求较高 并且很看重数据处理的高效性和可用性 传统数据处理方法的不足 传统的数据采集来
  • 记深度学习框架安装血泪史

    记深度学习框架安装血泪史 1 pytorch pytorch安装成功测试 查看pytorch版本 pytorch指定版本安装 pytorch降级 2 caffe 基于Anaconda安装 编译python接口 后记 关于Anaconda安装
  • python3.8安装urllib库_urllib库的基本使用

    学习爬虫的目的便是模拟浏览器向服务器发出请求 进而获取所需数据 爬虫可以分为抓取页面 分析页面和存储数据三步 每一步中 python都有强大的模块来让我们使用 今天先来学习请求库urllib的基本使用 python的安装请参考python开
  • 深度学习基础--池化--空间金字塔池化(spatial pyramid pooling,SPP)

    空间金字塔池化 spatial pyramid pooling SPP 解决的问题 先前方法 输入图片会经过裁切 Crop 或者变形缩放 Warp 这都在一定程度上导致图片信息的丢失和变形 限制了识别精确度 SPP可以输入任意大小的图片 不
  • Python - OpenCV识别条形码、二维码(已封装,拿来即用)

    此代码可识别条形码和二维码 已封装好 拿来即用 import cv2 import pyzbar pyzbar as pyzbar import numpy from PIL import Image ImageDraw ImageFont
  • Google Colab 如何使用step by step 简介

    1条消息 Colab使用 maox9629的博客 CSDN博客 colabhttps blog csdn net maox9629 article details 120757922
  • vue3搜索功能

    目录 设置数据和搜索词 创建计算属性 实现搜索功能 在Vue 3中实现搜索功能可以通过以下步骤进行 假设你已经有一个包含数据列表的组件 并且你想要在该列表中实现搜索功能 设置数据和搜索词 首先 在你的组件中定义一个用于存储数据和搜索词的变量
  • 1- OpenCV+TensorFlow 入门人工智能图像处理-课程介绍

    人工智能最火的两个方向 自然语言处理和计算机视觉 OpenCV的图像处理 TensorFlow的使用 mark 供需关系理论 有需求所以才有提供 招聘网站 图像算法两万以上 都需要的技能 OpenCV TensorFlow 人工智能时代之计
  • xss闯关详解

    文章目录 xss闯关详解 level 1 level 2 level 3 level 4 level 5 level 6 level 7 level 8 level 9 level 10 level 11 开始使用burpsuite lev
  • [xbttracker] linux 下 xbt tracker环境搭建(ubuntu)

    系统环境 Ubuntu x64 20 04 操作系统 win10 xbt源码 https github com dangwei 90 xbt 参考文档 http xbtt sourceforge net tracker 官网 注 官网 xb
  • 86篇!近3年顶会上的语义分割重磅论文

    语义分割技术在众多领域得到应用 包括 环境感知 自动驾驶 机器人导航等 随着计算机视觉领域的不断发展 语义分割技术成为从事相关学习和研究人员需要了解和掌握的技能 这次我邀请了上市公司高级算法工程师 张老师 用1个小时带大家一起去探索语义分割
  • 基于OpenCV的两种圆弧长度测量方法

    基于OpenCV的两种圆弧长度测量方法 OpenCV是广泛使用的计算机视觉库 在图像处理中 圆弧的长度是一个非常重要的参数 本文将会介绍两种基于OpenCV的圆弧长度测量方法 一种是通过弧度法测量圆弧长度 另一种则是通过插值法测量圆弧长度
  • jar包打不开怎么处理?

    第一种情况 首先win R 输入cmd打开命令行窗口 输入javac 检查一下是否有问题 正常的情况应该是下图这种 如果不是这种的 重新弄配置下你的环境变量 第二种情况 找到jdk目录下的bin文件夹 用里面的javaw打开 可以设置为默认
  • 约瑟夫问题

    约瑟夫问题 约瑟夫问题一般有两种解决方法 一种数组 一种链表 本次采用数组方式说明解决 规则 n个人围成一个圈 每个人分别标注为1 2 n 要求从1号从1开始报数 报到k的人出圈 接着下一个人又从1开始报数 如此循环 直到只剩最后一个人时
  • eclipse web项目目录结构

    按照 Java EE 规范的规定 一个典型的 Web 应用程序有四个部分 1 公开目录 2 WEB INF web xml 文件 发布描述符 必选 3 WEB INF classes 目录 编译后的 Java类文件 可选 4 WEB INF
  • Vue实现动态锚点

    前几天做项目的时候 需要实现一个动态锚点的效果 如果是传统项目 这个效果就非常简单 但是放到 Vue 中 就有两大难题 1 在没有 jQuery 的 animate 方法的情况下 如何实现平滑滚动 2 如何监听页面滚动事件 在浏览了大量文章
  • STM32串口中断卡死主循环一直进中断问题分析-2021-10-05

    在一项目中 使用STM32作为主控 程序运行一段时间后概率出现主循环卡死现象 问题分析如下 1 程序USART2不停接收并处理串口数据 波特率115200 2 主循环卡死 3 USART1中断及TIM2中断响应函数运行正常 USART1及T