STM32---外部中断EXTI
目录
一、中断向量表
二、EXTI工作原理图
三、NVIC模块
四、GPIO设置为EXTI的结构
五、C语言示例代码
在STM32中,中断是一个非常重要的结构,他能让我们在执行主函数的时候,由硬件检测一些外部或内部产生的中断信号,跳转到中断函数,从而提高CPU用于运算的时间占比,提高了效率。举个例子,如果没有中断的存在,则CPU需要一直循环遍历每一个寄存器,查看是否产生了某些信号,就无法专心处理运算逻辑。
一、中断向量表
中断向量表(Interrupt Vector Table, IVT)是嵌入式系统(尤其是ARM Cortex-M系列处理器)中用于管理中断的核心数据结构(函数指针数组)。它通过固定地址映射将中断号与中断服务函数(ISR, Interrupt Service Routine)关联,确保中断发生时处理器能快速跳转到正确的处理逻辑。
我们写的中断服务函数是保存在Flash中的,当一个外部中断信号来临的时候,CPU会跳转到该函数并执行。这是什么原理呢?

由于硬件原因CPU只能从某些特定的地址处访问中断函数,即只能从中断向量表中的地址去访问。所以一定要把中断服务函数和中断号一一对应,否则就会出问题,中断源触发跳转到错误的函数的问题。(因为编译器是根据中断号来找到数组下标,填写函数的地址的)
举个例子如果将 EXTI0_IRQHandler 配置到中断号 5,而硬件上的中断号 5 对应的是另一个中断源(如 RTC Alarm),那么当该中断触发时,CPU 会错误地调用 EXTI0_IRQHandler,二EXTI0发生中断的时候,会到表中找,发现并没有任何函数地址被填写进来,导致程序行为异常。
中断触发流程
- 中断发生:外设或异常触发中断。
- 中断号确定:处理器根据中断源确定中断号。
- 向量表查询:处理器从向量表中读取对应中断号的条目,获取中断服务函数的地址。
- 跳转执行:处理器跳转到该地址,执行中断服务函数。
- 返回:中断处理完成后,处理器返回主程序继续执行。
二、EXTI工作原理图

其中按照控制功能划分,共分为4个部分;有两条主线,一条是由输入线到 NVIC 中断控制器,一条是由输入线到脉冲发生器。
输入线:是线路的信息输入端,它可以通过配置寄存器设置为任何一个 GPIO 口,或者是一些外设的事件。输入线一般都是存在电平变化的信号。
(1)上升/下降沿触发选择寄存器:对边沿检测电路进行设置,当输入线有信号的时候并不会走到这里,他仅仅是在信号来临之前进行配置。
(2)边沿检测电路:对信号进行检测,符合上一条配置的则向或门输出1
(3)或门电路:两个信号输入端分别是软件中断事件寄存器和边沿检测电路的输入信号。或门电路只要输入端有信号1,就会输出1。所以可以同时检测软件中断和硬件中断。
(4)与门电路(标号3):两个信号输入端分别是中断屏蔽寄存器和标号2电路信号。如果中断屏蔽寄存器设置为 0 时,不管从标号2电路输出的信号特性如何,最终标号3电路输出的信号都是 0;假如中断屏蔽寄存器设置为 1 时,最终标号3电路输出的信号才由标号2电路输出信号决定,这样子就可以简单控制 中断屏蔽寄存器 来实现屏蔽或者开放中断的目的。
(5)与门电路(标号4):输入端来自标号2电路以及来自于事件屏蔽寄存器。可以简单的控制事件屏蔽寄存器来实现是否产生事件的目的。标号4电路输出有效信号 1 就会使脉冲发生器电路产生一个脉冲,而无效信号就不会使其产生脉冲信号。脉冲信号产生可以给其他外设电路使用,例如定时器,模拟数字转换器等,这样的脉冲信号一般用来触发 TIM 或者 ADC 开始转换。
产生中断线路目的使把输入信号输入到 NVIC或者其他外设,进一步运行中断服务函数,实现功能。
三、NVIC模块
NVIC位于处理器的核心外围设备中,负责接收来自各种外设的中断请求,并根据预设的优先级对这些请求进行排序和处理。它使用向量表来记录每个中断源的中断服务程序(ISR)的地址,确保中断发生时能迅速跳转到正确的处理位置。
当中断信号来临的时候,首先会交付给NVIC模块,由NVIC裁决(看你的优先级是否足够高)选择是交付给CPU,还是挂起在NVIC等待队列中。

这幅图表示了各种外设产生中断信号的时候,首先要交付给NVIC,经过裁决才能交付给CPU。
注意:NVIC可以设置优先级为抢占优先级和排队优先级。抢占优先级可以进行中断嵌套,如果抢占优先级相同则只能在NVIC中排队。但是如果排队优先级比别人高,是可以插队的。所以STM32的中断优先级不遵循先来后到,而是谁紧急优先处理谁。
四、GPIO设置为EXTI的结构
从下图中可以看到如果GPIO被设置为中断源的话,需要经过AFIO进行引脚选择的,而同为外部中断的其他几个模块(PVD、RTC、USB、ETH)则不需要经过AFIO,直接连接到EXTI边沿检测模块。
当EXTI从左端收到了中断信号之后,会向下层NVIC传递到CPU、或者通过脉冲发射器向其他外设(取决于你配置的是中断还是事件)。

AFIO设置EXTI0的示意图:

配置GPIO为EXTI外部中断的过程图示:

五、C语言示例代码
void EXTI_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟,外部中断必须开启AFIO的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB14引脚初始化为上拉输入/*AFIO选择中断引脚*/GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚/*EXTI初始化*/EXTI_InitTypeDef EXTI_InitStructure; //定义结构体变量EXTI_InitStructure.EXTI_Line = EXTI_Line14; //选择配置外部中断的14号线EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定外部中断线使能EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定外部中断线为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //指定外部中断线为下降沿触发EXTI_Init(&EXTI_InitStructure); //将结构体变量交给EXTI_Init,配置EXTI外设/*NVIC中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2//即抢占优先级范围:0~3,响应优先级范围:0~3//此分组配置在整个工程中仅需调用一次//若有多个中断,可以把此代码放在main函数内,while循环之前//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择配置NVIC的EXTI15_10线NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1NVIC_Init(&NVIC_InitStructure); //将结构体变量交给NVIC_Init,配置NVIC外设
}
void EXTI15_10_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line14) == SET) //判断是否是外部中断14号线触发的中断{/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){//这里填入处理逻辑}EXTI_ClearITPendingBit(EXTI_Line14); //清除外部中断14号线的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}
在这里给出csdn上别人封装的代码链接:STM32外部中断封装函数_如何封装stm32的中断,进行更高级的抽象-CSDN博客
相关文章:
STM32---外部中断EXTI
目录 一、中断向量表 二、EXTI工作原理图 三、NVIC模块 四、GPIO设置为EXTI的结构 五、C语言示例代码 在STM32中,中断是一个非常重要的结构,他能让我们在执行主函数的时候,由硬件检测一些外部或内部产生的中断信号,跳转到中断…...
Itext进行PDF的编辑开发
这周写了一周的需求,是制作一个PDF生成功能,其中用到了Itext来制作PDF的视觉效果。其中一些功能不是很懂,仅作记录,若要学习请仔细甄别正确与否。 开始之前,我还是想说,这傻福需求怎么想出来的,…...
Hibernate的组件映射
在实际的开发中,使用的是非常多的,还有几种比较特殊的关系映射: 组件映射继承映射 先看一下组件映射: 组件映射中, 组件也是一个类, 但是这个类它不独立称为一个实体, 也就是说, 数据库中没有一个表格单独的和它对应, 具体情况呢, 看演示:...
C++ 操作符重载Operator
C可以重载大多数操作符,如算术运算符号,-号。 位操作符<<,>> 下标符号[]等都可以重载。 重载的意思,是让这些符号,按你定义的行为来执行代码,但是这种自定义,是有限制的,必须有一…...
Docker 镜像、容器和 Docker Compose的区别
前言:Docker 的镜像、容器和 Docker Compose 是容器化技术的核心组件,以下是对它们的详细解析及使用场景说明。 1、Docker 镜像(Image) 定义: 镜像是只读模板,包含运行应用程序所需的代码、…...
Linux深度探索:进程管理与系统架构
1.冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。 截至目前,我们所认识的计算机,都是由⼀个个的硬件组件组成。 输入设备:键盘,鼠标…...
一段式端到端自动驾驶:VAD:Vectorized Scene Representation for Efficient Autonomous Driving
论文地址:https://github.com/hustvl/VAD 代码地址:https://arxiv.org/pdf/2303.12077 1. 摘要 自动驾驶需要对周围环境进行全面理解,以实现可靠的轨迹规划。以往的方法依赖于密集的栅格化场景表示(如:占据图、语义…...
17.整体代码讲解
从入门AI到手写Transformer-17.整体代码讲解 17.整体代码讲解代码 整理自视频 老袁不说话 。 17.整体代码讲解 代码 import collectionsimport math import torch from torch import nn import os import time import numpy as np from matplotlib import pyplot as plt fro…...
把dll模块注入到游戏进程的方法_基于文件修改的注入方式
1、概述 本文主要是介绍两种基于文件修改的注入方式,一种是“DLL劫持”,另一种是“修改导入表”。这两种注入方式都是利用操作系统加载PE时的特点来实现的,我们在实现这两种注入方式时只需专注于注入dll的实现,而不用花费额外的精力去关注注入器的实现。要想深入了解这两种…...
4月21日星期一今日早报简报微语报早读
4月21日星期一,农历三月廿四,早报#微语早读。 1、女子伸腿阻止列车关门等待同行人员,被深圳铁路警方行政拘留; 2、北理工再通报:开除宫某党籍,免去行政职务,解除聘用关系; 3、澳门…...
Spark(20)spark和Hadoop的区别
Apache Spark 和 Apache Hadoop 都是广泛使用的开源大数据处理框架,但它们在设计理念、架构、性能和适用场景等方面存在显著区别。以下是它们的主要区别: ### **1. 架构设计** - **Hadoop**: - **HDFS(Hadoop Distributed File…...
Kubeflow 快速入门实战(二) - Pipelines / Katib / KServer
承接前文博客 Kubeflow 快速入门实战(一) Kubeflow 快速入门实战(一) - 简介 / Notebooks-CSDN博客文章浏览阅读441次,点赞19次,收藏6次。本文主要介绍了 Kubeflow 的主要功能和能力,适用场景,基本用法。以及Notebook,…...
【JavaEE初阶】多线程重点知识以及常考的面试题-多线程进阶(一)
本篇博客给大家带来的是多线程中常见的所策略和CAS知识点. 🐎文章专栏: JavaEE初阶 🚀若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅🚀 要开心要快…...
ECA 注意力机制:让你的卷积神经网络更上一层楼
ECA 注意力机制:让你的卷积神经网络更上一层楼 在深度学习领域,注意力机制已经成为提升模型性能的重要手段。从自注意力(Self-Attention)到各种变体,研究人员不断探索更高效、更有效的注意方法。今天我们要介绍一种轻…...
基于定时器查询模式的LED闪烁(STC89C52单片机)
#include <reg52.h> sbit LED P0^0; sbit ADDR0 P1^0; sbit ADDR1 P1^1; sbit ADDR2 P1^2; sbit ADDR3 P1^3; sbit ENLED P1^4; void main() { unsigned char cnt 0; //定义一个计数变量,记录T0溢出次数 ENLED 0; //使能U3,选择…...
SAP系统生产跟踪报表入库数异常
生产跟踪报表入库数异常 交库21820,入库43588是不可能的 原因排查: 报表的入库数取值,是取移动类型321 (即系检验合格后过账到非限制使用)的数. 查凭证,101过账2次21807,321过账了2次21794,然后用102退1次21794.就是说这批物料重复交库了. 解决: 方案一:开发增强设…...
Kubernetes控制平面组件:调度器Scheduler(一)
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
08-DevOps-向Harbor上传自定义镜像
harbor创建完成,往harbor镜像仓库中上传自定义的镜像,包括新建项目、docker配置镜像地址、镜像重命名、登录harbor、推送镜像这几个步骤,具体操作如下: harbor中新建项目 访问级别公开,代表任何人都可以拉取仓库中的镜…...
Vue v-for 循环DOM 指定dom个数展示一行
在Vue.js中,如果想根据v-for循环的结果来控制哪些元素应该在一行中展示,你可以通过计算属性或者方法来实现。这里使用CSS改变样式和js脚本两种方式做到这一点,根据你的具体需求选择适合的方法。 方法1:使用计算属性 如果你想要基…...
mysql控制单表数据存储及单实例表创建
1. 单表数据存储不要过大 主流建议 保守建议。100万以内保持最佳性能其他。不超过2000万 理论依据。 B树层级可能变多。从3增加到4。导致索引查询路径边长,增加IO开销 优化 加索引。对高频查询字段增加索引。避免全表扫描低频历史数据通过分区表或归档隔离。足够的…...
极验4滑块笔记:整理思路--填坑各种问题
最近在研究某验4逆向分析,以前没弄过这种,所以爬了很多坑,就是把分享给大家~ 1.这个gcaptcha4.js需要逆向,我的方法很笨就是将_ᕶᕴᕹᕶ()这个蝌蚪文打印处来,全局替换一下,然后Unicode这种代码࿰…...
LX3-初识是单片机
初识单片机 一 什么是单片机 单片机:单片微型计算机单片机的组成:CPU,RAM(内存),flash(硬盘),总线,时钟,外设…… 二 Coretex-M系列介绍 了解ARM公司与ST公司ARM内核系列: A 高性能应用,如手机,电脑…R 实时性强,如汽车电子,军工…M 超低功耗,如消费电子,家电,医疗器械 三…...
2025年渗透测试面试题总结-拷打题库10(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 2025年渗透测试面试题总结-拷打题库10 1. CSRF成因及防御措施 | 非Token防御 2. XSS Worm原理 3. Co…...
Linux系统下docker 安装 MySQL
踩坑解决: 1、docker安装mysql,不需要执行search 2、pull时,需要指定版本号 3、连接Navicat需要看阿里云端口号是否开启 在拉取镜像的时候,如果不使用代理服务器,docker search mysql不需要执行 本人在未使用代理服…...
配置 VS Code 使用 ESLint 格式化
1、在设置里面搜索Default Formatter,下拉框里选择eslint 2、并勾选Enables ESlint as a formatter 3、再在settings.json文件中添加配置代码,如下所示: 1) 、打开 VS Code 设置 快捷键:Ctrl ,(Mac: ⌘ ,…...
从代码实现理解Vision Permutator:WeightedPermuteMLP模型解析
从代码实现理解Vision Permutator:WeightedPermuteMLP模型解析 随着人工智能的快速发展,视觉识别任务变得越来越重要。最近提出的Vision Permutator架构为这一领域带来了新的思路,它通过可学习的排列操作重新定义了特征交互的方式。 今天我…...
Web开发:ABP框架10——使用数据库存储文件,完成文件的下载和上传
一、简要介绍 字节数组:字节数组是存储数据的字节序列,常用于二进制数据(如图片、音视频、文档等)的表示。 文件和字节的关系:文件是由字节构成,字节是文件内容的基本单位。 文件以字节形式存储在服务器数…...
SystemVerilog语法之内建数据类型
简介:SystemVerilog引进了一些新的数据类型,具有以下的优点:(1)双状态数据类型,更好的性能,更低的内存消耗;(2)队列、动态和关联数组,减少内存消耗…...
NestJS-Knife4j
文章目录 前言✅ 一、什么是 Knife4j?✅ 二、Knife4j 与 Swagger 对比✅ 三、NestJS-Knife4j 集成1. 安装依赖2. 配置 Swagger 与 Knife4j3. 启动应用并访问接口文档 ✅ 四、功能增强1. **接口分组**2. **请求/响应示例**3. **接口文档的美化** ✅ 五、总结 前言 N…...
【项目管理】成本类计算 笔记
项目管理-相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应&…...
