STM32 gpio外部中断详解

news2024/11/9 4:42:01

什么是中断?

打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断

中断的作用和意义在这里插入图片描述

中断的意义:高效处理紧急程序,不会一直占用CPU资源

STM32 GPIO外部中断简图

在这里插入图片描述

NVIC

什么是 NVIC?NVIC 即嵌套向量中断控制器,全称 Nested vectored interrupt controller。它
是内核的器件。
M3/M4/M7 内核都是支持 256 个中
断,其中包含了 16 个系统中断和 240 个外部中断,并且具有 256 级的可编程中断设置。然而芯
片厂商一般不会把内核的这些资源全部用完,如 STM32F407 的系统中断有 10 个,外部中断有
82 个。在这里插入图片描述
关于 82 个外部中断部分在《STM32F4xx 参考手册_V4(中文版).pdf》的 10.2 小节有详细
的列表,这里就不列出来了。STM32F407 的中断向量表在 stm32f407xx.h 文件中被定义。

NVIC 寄存器

NVIC 相关的寄存器定义了可以在 core_cm4.h 文件中找到。我们直接通过程序的定义来分
析 NVIC 相关的寄存器,其定义如下:

typedef struct
{
  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
        uint32_t RESERVED0[24U];
  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
        uint32_t RSERVED1[24U];
  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
        uint32_t RESERVED2[24U];
  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
        uint32_t RESERVED3[24U];
  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
        uint32_t RESERVED4[56U];
  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
        uint32_t RESERVED5[644U];
  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
}  NVIC_Type;

STM32F407 的中断在这些寄存器的控制下有序的执行的。只有了解这些中断寄存器,才能
方便的使用 STM32F407 的中断。下面重点介绍这几个寄存器:
ISER[8]:ISER 全称是:Interrupt Set Enable Registers,这是一个中断使能寄存器组。上面
说了 CM4 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。但是
STM32F407 的可屏蔽中断最多只有 82 个,所以对我们来说,有用的就是两个(ISER[0~3]),总
共可以表示 128 个中断。而 STM32F407 只用了其中的 82 个。ISER[0]的 bit0~31 分别对应中断
0~31;ISER[1]的 bit0~31 对应中断 32~63; ISER[2]的 bit0~16 对应中断 64~81,这样总共 82 个
中断就可以分别对应上了。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能
(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。
具体每一位对应哪个中断,请参考 stm32f407xx.h 里面的第 68 行。
ICER[8]:全称是:Interrupt Clear Enable Registers,是一个中断除能寄存器组。该寄存器组
与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ISER 一样。
这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄
存器都是写 1 有效的,写 0 是无效的。
ISPR[8]:全称是:Interrupt Set Pending Registers,是一个中断使能挂起控制寄存器组。每
个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高
级别的中断。写 0 是无效的。
ICPR[8]:全称是:Interrupt Clear Pending Registers,是一个中断解挂控制寄存器组。其作
用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断解挂。写 0 无效。
IABR[8]:全称是:Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。对应位
所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄
存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
IP [240]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄
存器组相当重要!STM32F407 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit
的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32F407
只用到了其中的 82 个。IP[81]~IP[0]分别对应中断 81~0。而每个可屏蔽中断占用的 8bit 并没有
全部使用,而是只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子
优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。关
于中断优先级控制的寄存器组我们下面详细讲解。

中断优先级

STM32 中的中断优先级可以分为:抢占式优先级和响应优先级,响应优先级也称子优先级,
每个中断源都需要被指定这两种优先级。抢占式优先级和响应优先级的区别:

抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。
响应优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断

还有一种情况就是当两个或者多个中断的抢占式优先级和响应优先级相同时,那么就遵循
自然优先级,看中断向量表的中断排序,数值越小,优先级越高。

在 NVIC 中由寄存器 NVIC_IPR0-NVIC_IPR59 共 60 个寄存器控制中断优先级,每个寄存器的每 8 位又分为一组,可以分 4 组,所以就有了 240 组宽度为 8bit 的中断优先级控制寄存器,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高。但是实际上 M3 /M4/M7 芯片为了精简设计,只使用了高四位[7:4],低四位取零,这样以至于最多只有 16 级中断嵌套,即 2^4=16。
在这里插入图片描述
通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系,例如优先级分组设置为 3,
那么此时所有的 82 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,
低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优
先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
结合实例说明一下:假定设置中断优先级分组为 2,然后设置中断 3(RTC_WKUP 中断)的
抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。
中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:
中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互
打断!

NVIC 相关函数

ST 公司把 core_cm4.h 文件的 NVIC 相关函数封装到 stm32f4xx_hal_cortex.c 文件中,下面
列出我们较为常用的函数进行.

1. HAL_NVIC_SetPriorityGrouping 函数

HAL_NVIC_SetPriorityGrouping 是设置中断优先级分组函数。其声明如下:
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
⚫ 函数描述:
用于设置中断优先级分组。
⚫ 函数形参:
形参 1 是中断优先级分组号,可以选择范围:NVIC_PRIORITYGROUP_0 到
NVIC_PRIORITYGROUP_4(共 5 组)。
⚫ 函数返回值:无
⚫ 注意事项:
这个函数在一个工程里基本只调用一次,而且是在程序 HAL 库初始化函数里面已经被调
用,后续就不会再调用了。因为当后续调用设置成不同的中断优先级分组时,有可能造成前面
设置好的抢占优先级和响应优先级不匹配。

2. HAL_NVIC_SetPriority 函数

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority,
uint32_t SubPriority);
⚫ 函数描述:
用于设置中断的抢占优先级和响应优先级(子优先级)。
⚫ 函数形参:
形参 1 是中断号,可以选择范围:IRQn_Type 定义的枚举类型,定义在 stm32f407xx.h。
形参 2 是抢占优先级,可以选择范围:0 到 15。
形参 3 是响应优先级,可以选择范围:0 到 15。

3. HAL_NVIC_EnableIRQ 函数

id HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
⚫ 函数描述:
用于使能中断。
⚫ 函数形参:
形参 1 是中断号,可以选择范围:IRQn_Type 定义的枚举类型,定义在 stm32f407xx.h。
⚫ 函数返回值:无

4. HAL_NVIC_DisableIRQ 函数

HAL_NVIC_DisableIRQ 是中断失能函数。其声明如下:
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
⚫ 函数描述:
用于中断除能。
⚫ 函数形参:无形参
⚫ 函数返回值:无

5. HAL_NVIC_SystemReset 函数

HAL_NVIC_SystemReset 是系统复位函数。其声明如下:
void HAL_NVIC_SystemReset(void);
⚫ 函数描述:
用于软件复位系统。
⚫ 函数形参:无形参
⚫ 函数返回值:无

EXTI 简介

EXTI 即是外部中断和事件控制器,它是由 20 个产生事件/中断请求的边沿检测器组成。每
一条输入线都可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或
者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

在这里插入图片描述
从 EXTI 功能框图可以看到有两条主线,一条是由输入线到 NVIC 中断控制器,一条是由
输入线到脉冲发生器。这就恰恰是 EXTI 的两大部分功能,产生中断与产生事件,两者从硬件
上就存在不同。

下面让我们看一下 EXTI 功能框图的产生中断的线路,最终信号是流入 NVIC 控制器中。输入线是线路的信息输入端,它可以通过配置寄存器设置为任何一个 GPIO 口,或者是一些外设的事件。输入线一般都是存在电平变化的信号。

标号①:====是一个边沿检测电路,包括边沿检测电路,上升沿触发选择寄存器(EXTI_RTSR)和
下降沿触发选择寄存器(EXTI_FTSR)。边沿检测电路以输入线作为信号输入端,如果检测到有
边沿跳变就输出有效信号‘1’,就输出有效信号‘1’到标号②部分电路,否则输入无效信号‘0’。
边沿跳变的标准在于开始的时候对于上升沿触发选择寄存器或下降沿触发选择寄存器对应位的
设置,对应位的设置可以参照一下表 16.1.2.1。
标号②:是一个或门电路,它的两个信号输入端分别是软件中断事件寄存器(EXTI_SWIER)和边沿检测电路的输入信号。或门电路只要输入端有信号‘1’,就会输出‘1’,所以就会输出‘1’到标号③电路和标号④电路。通过对软件中断事件寄存器的读写操作就可以启动中断/事
件线,即相当于输出有效信号‘1’到或门电路输入端。
标号③:是一个与门电路,它的两个信号输入端分别是中断屏蔽寄存器(EXTI_IMR)和标号②电路输出信号。与门电路要求输入都为‘1’才输出‘1’,这样子的情况下,如果中断屏蔽寄存器(EXTI_IMR)设置为 0 时,不管从标号②电路输出的信号特性如何,最终标号③电路输出的信
号都是 0;假如中断屏蔽寄存器(EXTI_IMR)设置为 1 时,最终标号③电路输出的信号才由标号
②电路输出信号决定,这样子就可以简单控制 EXTI_IMR 来实现中断的目的。标号④电路输出
‘1’就会把请求挂起寄存器(EXTI_PR)对应位置 1。
最后,请求挂起寄存器(EXTI_PR)的内容就输出到 NVIC 内,实现系统中断事件的控制。
接下来我们看看 EXTI 功能框图的产生事件的线路。产生事件线路是从标号 2 之后与中断线路有所不用,之前的线路都是共用的。标号④是一个与门,输入端来自标号 2 电路以及来自于事件屏蔽寄存器(EXTI_EMR)。如果 EXTI_EMR 寄存器设置为 0,那不管标号 2 电路输出的信号是‘0’还是‘1’,最终标号 4 输出的是‘0’;如果 EXTI_EMR 寄存器设置为 1,最终标号④电路输出信号就由标号③电路输出的信号决定,这样子就可以简单的控制 EXTI_EMR 来实现是否产生事件的目的。
标号④:电路输出有效信号 1 就会使脉冲发生器电路产生一个脉冲,而无效信号就不会使其产生脉冲信号。脉冲信号产生可以给其他外设电路使用,例如定时器,模拟数字转换器等,这样的脉冲信号一般用来触发 TIM 或者 ADC 开始转换。

产生中断线路目的使把输入信号输入到 NVIC,进一步运行中断服务函数,实现功能。而产
生事件线路目的是传输一个脉冲信号给其他外设使用,属于硬件级功能。
EXTI 支持 23 个外部中断/事件请求,这些都是信息输入端,也就是上面提及到了输入线
具体如下:
EXTI 线 0~15:对应外部 IO 口的输入中断
EXTI 线 16:连接到 PVD 输出
EXTI 线 17:连接到 RTC 闹钟事件
EXTI 线 18:连接到 USB 唤醒事件
EXTI 线 19:连接到以太网唤醒事件
EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件
EXTI 线 21:连接到 RTC 入侵和时间戳事件
EXTI 线 22:连接到 RTC 唤醒事件

从上面可以看出,STM32F407 供给 IO 口使用的中断线只有 16 个,但是 STM32F407 的 IO
口却远远不止 16 个,所以 STM32 把 GPIO 管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应
中断线 0~15。这样子每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、
GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0 和 GPIOG.0。而中断线每次只能连接到 1 个
IO 口上,这样就需要通过配置决定对应的中断线配置到哪个 GPIO 上了。

如何使用中断

在这里插入图片描述

STM32 EXTI的配置步骤(外部中断)

在这里插入图片描述

STM32 EXTI的HAL库设置步骤(外部中断)

在这里插入图片描述

通用外设驱动模型(四步法)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/420709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JSTL标签库

英文全称&#xff1a;Java Standard Tag Lib&#xff08;Java标准的标签库&#xff09; 使用目的&#xff1a;JSTL标签库通常结合EL表达式一起使用。目的是让JSP中的java代码消失。 使用位置&#xff1a;JSTL标签是写在JSP当中的&#xff0c;但实际上最终还是要执行对应的jav…

Ubuntu 开机启动 通过crontab定时器去检查脚本 实现

有个项目的程序需要实现开机启动 通过添加一个qmcy.service服务的方法 发现 确实执行脚本了 但是脚本的程序缺并没有起来 但是如果手动执行这个脚本 程序是能起来的 不知道为啥 没办法 网上搜了下 可以通过 crontab定时器去检查 程序是否启动 没启动的话去 执行对应的脚…

【毕业设计】基于程序化生成和音频检测的生态仿真与3D内容生成系统----程序化生成多图层地形贴图的算法设计

(2条消息) 【开发日志】2023.04 ZENO----Image Processing----CompositeCV、Composite2、Composite3_EndlessDaydream的博客-CSDN博客 (2条消息) 【开发日志】2023.04 ZENO----Image Processing----ImageEdit、EditRGB、EditHSV_EndlessDaydream的博客-CSDN博客 (2条消息) 【…

telegraf在iiot领域的基本应用(Modbus,OPC)

熟悉telegraf是因为influxdb缘故&#xff0c;当时telegraf主要是作为granfa监控的agent一环&#xff0c;很多文章有相关的介绍&#xff0c;但作为java开发对telegraf&#xff08;go语言开发&#xff09;也仅仅只是适用级别&#xff0c;这边文章也只讲到一些简单的应用。希望能帮…

<STM32>STM32CubeMX-CAN通信(扫描读取数据方式)(5)

&#xff1c;STM32&#xff1e;STM32CubeMX-CAN通信&#xff08;扫描读取数据方式&#xff09;&#xff08;5&#xff09; 本节主要讲解CAN通信的功能&#xff0c;主要采用扫面检测接收数据的方式&#xff1b; CAN的详细解说可参考《STM32F4XXX中文参考手册》&#xff0c;资料有…

CDH 之 Kerberos 安全认证和 Sentry 权限控制管理(一)

一、Kerberos 和 Sentry 概述 1.1 什么是 Kerberos Kerberos是一种计算机网络授权协议&#xff0c;用来在非安全网络中&#xff0c;对个人通信以安全的手段进行身份认证。这个词又指麻省理工学院为这个协议开发的一套计算机软件。软件设计上采用客户端/服务器结构&#xff0c;…

java微服务商城高并发秒杀项目--011.授权规则和系统规则

授权规则在shop-order-server中新建RequestOriginParserDefinition.java,定义请求来源如何获取Component public class RequestOriginParserDefinition implements RequestOriginParser {Overridepublic String parseOrigin(HttpServletRequest request) {/*** 定义从请求的什么…

文本分类论文阅读

1.ChineseBERT: Chinese Pretraining Enhanced by Glyph and Pinyin Information&#xff08;ACL2021&#xff09; 字形嵌入根据汉字的不同字体获得&#xff0c;能够从视觉特征中捕捉汉字语义&#xff0c;拼音嵌入表征汉字的发音&#xff0c;解决了汉语中非常普遍的异义异义现…

四、vue基础-指令(一)、vscode代码片段

一、vscode代码片段 我们在前面联系Vue的过程中&#xff0c;有些代码片段是需要经常写的&#xff0c;我们再VSCode中我们可以生成一个代码片段&#xff0c;方便我们快速生成。VSCode中的代码片段有固定的格式&#xff0c;所以我们一般会借助于一个在线工具来完成。 具体步骤如…

01_什么是Uboot

目录 U-Boot简介 获取Uboot U-Boot初次编译 U-Boot烧写与启动 U-Boot简介 Linux系统要启动就必须需要一个bootloader程序(裸机程序),也就说芯片上电以后先运行一段bootloader程序。这段bootloader程序会先初始化DDR等外设,然后将Linux镜像从flash(NAND,NOR FLASH,SD,EMMC等…

【防止恶意用户注册】-- 手机在网状态 API 的防欺诈应用解析

简介 手机在网状态 API 支持传入手机号码&#xff0c;查询手机号在网状态&#xff0c;返回在网、在网不可用、不在网&#xff08;销号/未启用/停机&#xff09;等多种状态&#xff0c;查询手机号在网状态之后&#xff0c;可以根据具体的业务需求来进行不同的处理。 本文主要介…

EA的使用---文档的生成

EA中文档的自动生成 1.找到如下界面 2.选择第一个 3.设置存储的位置 4.点击Generate 5.查看生成的文档

ViT Vision Transformer进行猫狗分类

文章目录依赖准备数据集合残差结构PatchEmbed模块Attention模块MLPBlockVisionTransformer结构模型定义定义一个模型训练VISION TRANSFORMER简称ViT&#xff0c;是2020年提出的一种先进的视觉注意力模型&#xff0c;利用transformer及自注意力机制&#xff0c;通过一个标准图像…

【C++STL精讲】string的模拟实现

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;定义string类&#x1f337;构造函数&#x1f337;拷贝构造函数&#x1f337;赋值重载&#x1f337;析构函数&#x1f337;[]操作符重载&#x1f337;比较运算符重载&#x1f337;c_str、size、capacity&#x…

模板学堂|DataEase图表样式解析

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场&#xff08;https://dataease.io/templates/&#xff09;。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板&#xff0c;方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&#xff0c;并…

「VS」Visual Studio 常用小技巧

目录指定代码不编译设置选中项目为启动项代码区显示行号新建垂直文档组生成后将dll复制到指定目录指定代码不编译 说明&#xff1a;在项目开发时&#xff0c;有时候已经将代码加入到项目中&#xff0c;但有不想要编译时可以一下操作。 文件处右键→属性→常规→从生成中排除→选…

快速解决CentOS中yum下载慢的问题(更换成阿里云)

目录1、备份自带的YUM源2、下载新的yum源3、清除旧的 yum 缓存4、更新yum缓存4、查看更换的阿里云镜像的仓库是否生效。为了下载速度快&#xff0c;每次都要做好镜像的更改&#xff0c;既然次数多&#xff0c;懒得每次还来查资料&#xff0c;就自己写一篇博客加强自己的记忆。 …

Docker环境安装

Docker环境安装Docker简介Docker工作原理Docker的应用场景Docker 的优点CentOS Docker 安装与配置Docker 安装Docker 配置Docker容器概念Docker容器操作拉取镜像删除镜像容器相关命令创建并启动容器停止和恢复容器删除容器Docker简介 Docker 是一个开源的应用容器引擎&#xf…

4年外包上岸,我只能说这类公司能不去就不去

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是4年。现在终于跳槽到了互联网公司了&#xff0c;我想说的是&#xff0c;但凡有点机会&#xff0c;千万…

ChatGPT背后的AI背景、技术门道和商业应用(万字长文,建议收藏)

作者&#xff1a;京东科技 李俊兵 各位看官好&#xff0c;我是球神&#xff08;江湖代号&#xff09;。 自去年11月30日ChatGPT问世以来&#xff0c;迅速爆火出圈。 起初我依然以为这是和当年Transformer, Bert一样的“热点”模型&#xff0c;但是当一篇篇文章/报告不断推送…