当前位置: 首页 > news >正文

【STM32】外部中断

STM32 外部中断(EXTI)概述

这篇文章结合示例代码,系统性地讲述 STM32 外部中断(EXTI)实验的原理、以及配置流程。目的在于辅助读者掌握STM32F1 外部中断机制。

STM32F1xx官方资料:《STM32中文参考手册V10》-第9章 中断和事件

STM32的每个IO都可以作为外部中断输入。
STM32的中断控制器支持19个外部中断/事件请求:
线0~15:对应外部IO口的输入中断。
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),
STM32F103RCT6(51),那么中断线怎么跟io口对应呢?

在这里插入图片描述
如图所示,

GPIOx.0映射到EXTI0
GPIOx.1映射到EXTI1
…
GPIOx.15映射到EXTI15图20:AFIO_EXTICR 映射机制图:
每个 EXTI 线可通过 AFIO 寄存器选择映射到 GPIOA~GPIOG 的某一个引脚。
例如:EXTI3 可以绑定 PE3、PC3、PB3 等,只能绑定一个。
特性说明
可用中断线EXTI0 ~ EXTI15(共16条 IO 线)
+ EXTI16(PVD)、EXTI17(RTC)、EXTI18(USB)
可触发方式上升沿、下降沿、双边沿
可配置功能中断 / 事件
IO与EXTI映射通过 AFIO_EXTICR 寄存器设置
中断向量数量仅有 7 个中断服务函数(EXTI0~4,EXTI9_5,EXTI15_10)
中断线与中断函数映射关系

对于每个中断线,我们可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能。

那么,是不是16个中断线就可以分配16个中断服务函数呢?

IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数。
在这里插入图片描述
从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数,
外部中断线10~15分配一个中断向量,共用一个中断服务函数。

中断线中断服务函数是否共享中断
EXTI0EXTI0_IRQHandler
EXTI1EXTI1_IRQHandler
EXTI2EXTI2_IRQHandler
EXTI3EXTI3_IRQHandler
EXTI4EXTI4_IRQHandler
EXTI5~9EXTI9_5_IRQHandler是,需区分
EXTI10~15EXTI15_10_IRQHandler是,需区分

另外,补充一个知识点,线16、线17、线18 是 STM32 外部中断控制器(EXTI)中,与特定内部外设连接的特殊中断线。 它们不再对应 GPIO 引脚,而是与 STM32 内部某些模块直接相关。

EXTI 特殊中断线(EXTI16 ~ EXTI18)

EXTI16 — PVD(电源电压监测器)
EXTI17 — RTC Alarm(实时时钟闹钟)
EXTI18 — USB Wakeup(USB 唤醒)

中断线编号来源模块名称/用途中断触发条件常用用途
EXTI16PVD(电源监测)电压检测中断电压低于/高于设定阈值电源掉电、低电压预警
EXTI17RTC(实时时钟)RTC闹钟中断RTC 到达设定闹钟时间定时唤醒、定时事件处理
EXTI18USB(唤醒模块)USB 唤醒中断USB 活动信号唤醒 MCUUSB 唤醒低功耗模式

外部中断库函数设置

中断服务函数列表:

EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler

EXTI_Init函数
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
typedef struct
{uint32_t EXTI_Line;   //指定要配置的中断线           EXTIMode_TypeDef EXTI_Mode;   //模式:事件 OR中断EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发FunctionalState EXTI_LineCmd;  //使能 OR失能
}EXTI_InitTypeDef;EXTI_InitStructure.EXTI_Line=EXTI_Line2;	 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);	 	

EXTI 外部中断配置步骤(官方流程)

外部中断的一般配置步骤:

① 初始化IO口为输入。
GPIO_Init();
② 开启IO口复用时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
③ 设置IO口与中断线的映射关系。
void GPIO_EXTILineConfig();
④ 初始化线上中断,设置触发条件等。
EXTI_Init();
⑤ 配置中断分组(NVIC),并使能中断。
NVIC_Init();
⑥ 编写中断服务函数。
EXTIx_IRQHandler();
⑦ 清除中断标志位
EXTI_ClearITPendingBit();

EXTI线通过 AFIO_EXTICR1~4 映射 GPIO 引脚

  • EXTI0 可映射 PA0 ~ PG0
  • EXTI15 可映射 PA15 ~ PG15

在这里插入图片描述
在这里插入图片描述

中断向量表图说明:仅为 EXTI0~4、EXTI9_5、EXTI15_10 提供中断服务函数。多线共享的服务函数需在函数内判断是哪条线路触发。
🌟 配置步骤详解(以 KEY1 按键连接 PE3 → EXTI3 为例):

① 配置 GPIO 为输入模式

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 使能GPIOE时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;             // PE3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure);

② 使能 AFIO(复用功能模块)时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

③ 配置 EXTI 线映射(将 PE3 映射到 EXTI3)

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);

④ 配置 EXTI 中断线

EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line3;                  // EXTI3
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;         // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;     // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;                   // 使能
EXTI_Init(&EXTI_InitStructure);

⑤ 配置 NVIC 中断优先级并使能中断

NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // 使能
NVIC_Init(&NVIC_InitStructure);

⑥ 编写中断服务函数 EXTI3_IRQHandler

void EXTI3_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line3) != RESET){// 中断处理逻辑,比如点亮 LEDLED1_TOGGLE();  // 示例函数,用户自定义EXTI_ClearITPendingBit(EXTI_Line3); // 清除中断标志位}
}

按键硬件连接

战舰:
在这里插入图片描述
精英:
在这里插入图片描述
mini:
在这里插入图片描述
原理图说明(KEY0 ~ KEY2 与 PA0、PE3、PE4)(对照图解说明)

按键名称接口引脚对应 EXTI 线中断函数
KEY0PE4EXTI4EXTI4_IRQHandler
KEY1PE3EXTI3EXTI3_IRQHandler
KEY2PE2EXTI2EXTI2_IRQHandler
WK_UPPA0EXTI0EXTI0_IRQHandler
多个引脚使用同一个中断线时的处理(共享中断)

如图所示:
EXTI9_5_IRQHandler 处理 EXTI5EXTI9
EXTI15_10_IRQHandler 处理 EXTI10EXTI15

处理多个中断线:

void EXTI9_5_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line7) != RESET){// 处理 EXTI7 对应按键EXTI_ClearITPendingBit(EXTI_Line7);}if (EXTI_GetITStatus(EXTI_Line6) != RESET){// 处理 EXTI6 对应按键EXTI_ClearITPendingBit(EXTI_Line6);}
}

完整按键中断实验总结

📋 总体代码结构:

void KEY_Interrupt_Init(void)
{// 1. 初始化 GPIORCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOE, &GPIO_InitStructure);// 2. 映射 EXTI 线GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);// 3. 配置 EXTIEXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);// 4. 配置 NVICNVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

综上。

步骤
1️⃣ 配置 GPIO 为输入模式(上拉/下拉)
2️⃣ 使能 AFIO 时钟
3️⃣ 使用 GPIO_EXTILineConfig() 设置 EXTI 映射
4️⃣ 使用 EXTI_Init() 配置中断线触发方式
5️⃣ 使用 NVIC_Init() 设置中断优先级与使能
6️⃣ 编写 EXTIx_IRQHandler() 并清除中断标志位

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

http://www.lqws.cn/news/530677.html

相关文章:

  • HTTP协议-后端接收请求
  • CRON表达式编辑器与定时任务实现技术文档
  • Sonarqube:Jenkins触发sonar扫描出现UnsupportedClassVersionError错误处理
  • EXILIUM×亚矩云手机:重构Web3虚拟生存法则,开启多端跨链元宇宙自由征途
  • GEO引领品牌大模型种草:迈向Web3.0与元宇宙的认知新空间
  • 【算法深练】栈特性的解题密码:LIFO规则在题型中的灵活运用
  • 供应链管理:计划相关岗位及其岗位职责
  • 【C++】ATM机模拟系统 :完整窗口实现
  • 机器学习15-规则学习-知识加强
  • MySQL-主从复制分库分表
  • WebSocket 与 HTTP 的区别及 Spring Boot 实战应用
  • 如何将视频从 iPhone 发送到 Android 设备
  • Midscene.js:使用 LLMs.txt 快速生成 AI 自动化测试用例「喂饭教程」
  • pyhton自动化采集数据脚本
  • 实现Taro小程序+nut-ui左滑删除效果
  • Go 语言中的指针
  • Java+Vue开发的SRM企业招采管理系统,一站式管理招采,助力企业高效运营
  • VC formal document and examples
  • 先考 HCIA 还是直接考 HCIP?网络工程师认证选择指南
  • 深入剖析Nginx架构及其不同使用场景下的配置
  • 蜂鸟代理IP+云手机:跨境电商多账号运营的“隐形风控引擎”
  • 手机控车一键启动汽车智能钥匙
  • Java Lambda表达式
  • CMake实践:安装与配置
  • 基于vue3+ByteMD快速搭建自己的Markdown文档编辑器
  • MySQL 中的锁机制详解:原理、实现方式与实战解析!
  • MySQL多表关系
  • Nordic 电源管理nPM1300 EK评估板介绍
  • 大模型在慢性病毒性肝炎预测及诊疗方案制定中的应用研究
  • 频宽是什么: 0.35/Tr、0.5/Tr?