你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

嵌入式-单片机-STM32 EXTI中断

[复制链接]
flyingstar 发布时间:2025-12-22 15:26
STM32 的EXTI(外部中断 / 事件控制器) 是用于检测外部引脚电平变化并触发中断或事件的外设,支持19 个中断 / 事件线(EXTI0~EXTI15 对应 GPIO 引脚,EXTI16 对应 PVD,EXTI17 对应 RTC 闹钟,EXTI18 对应 USB OTG FS 唤醒,EXTI19 对应以太网唤醒),是 STM32 处理外部硬件触发的核心模块。
一、EXTI 核心特性
  • 中断与事件分离9 z& R  d1 |  q# u6 }5 |
    • 中断:触发后会向 NVIC(嵌套向量中断控制器)申请中断,执行中断服务函数。
    • 事件:仅产生硬件脉冲,用于触发其他外设(如定时器、DMA),不进入 CPU 中断。2 c4 R" E: j; r
  • 触发方式:支持上升沿触发、下降沿触发、双边沿触发、软件触发。
  • GPIO 映射:EXTI0~EXTI15 可映射到任意 GPIO 端口的对应引脚(如 EXTI0 可映射到 PA0、PB0、PC0…PG0),通过 SYSCFG 寄存器配置。
    2 b2 v. [# d8 Y, E# Q6 ~# [% G
二、EXTI 中断配置步骤
以STM32F103为例(F4/F7/H7 系列配置逻辑类似,仅库函数 / 寄存器命名略有差异),配置 GPIO 引脚触发 EXTI 中断的通用步骤:
1. 开启时钟
  • 开启GPIO 端口时钟(如 GPIOA)。
  • 开启SYSCFG 时钟(EXTI 的引脚映射需要 SYSCFG 支持,F1 系列 SYSCFG 挂载在 APB2 总线上)。
  • 开启EXTI 控制器时钟(部分系列 EXTI 时钟由内核自动使能,无需手动开启)。
    * W6 h* _# [/ k4 f. u2 r
  • // 以STM32F103为例,使用标准库
  • #include "stm32f10x.h"
  • // 开启GPIOA和SYSCFG时钟
  • RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SYSCFG, ENABLE);
    3 g; _7 S8 K& d' A+ t
2. 配置 GPIO 为输入模式EXTI 引脚需配置为浮空输入、上拉输入或下拉输入(不可为输出模式)。- Z; i+ `; e& A3 S% V3 Q  [
  • GPIO_InitTypeDef GPIO_InitStruct;
  • // 配置PA0为浮空输入
  • GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
  • GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
  • GPIO_Init(GPIOA, &GPIO_InitStruct);
    7 L3 @/ s: v& R* H/ C. t
3. 配置 SYSCFG_EXTICR 寄存器,映射 GPIO 引脚到 EXTI 线通过SYSCFG_EXTILineConfig函数将 GPIO 端口映射到对应的 EXTI 线(如 PA0 映射到 EXTI0)。
( m# U1 F! B! s
  • // 映射PA0到EXTI0线:参数1=EXTI线,参数2=GPIO端口
  • SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    4 m/ B0 t6 q! A1 ^4 T9 o% E
4. 配置 EXTI 中断触发方式和使能通过EXTI_InitTypeDef结构体配置 EXTI 线的触发方式(上升沿 / 下降沿)、中断使能。
+ K8 ^# I# R1 |, C$ e- s+ L' ^* x4 \8 J0 k  _0 l7 I% ]5 q# b) h

+ U7 T3 b$ W1 u3 V9 `6 X* H2 P
  • EXTI_InitTypeDef EXTI_InitStruct;
  • // 配置EXTI0线
  • EXTI_InitStruct.EXTI_Line = EXTI_Line0;          // 选择EXTI0线
  • EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式(事件模式为EXTI_Mode_Event)
  • EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发(下降沿:EXTI_Trigger_Falling;双边沿:EXTI_Trigger_Rising_Falling)
  • EXTI_InitStruct.EXTI_LineCmd = ENABLE;           // 使能EXTI0线
  • EXTI_Init(&EXTI_InitStruct);) I0 V4 E, r9 i, J* R' ?& R+ @
5. 配置 NVIC,使能 EXTI 中断通道EXTI 中断需通过 NVIC 配置优先级并使能,不同 EXTI 线对应不同的 NVIC 通道:
* [" [1 Q7 d) Z% J4 ~5 {
  • EXTI0~EXTI4:分别对应 NVIC 的 EXTI0_IRQn ~ EXTI4_IRQn。
  • EXTI5~EXTI9:共享 EXTI9_5_IRQn。
  • EXTI10~EXTI15:共享 EXTI15_10_IRQn。8 U" s6 P! q+ ?; `
  • NVIC_InitTypeDef NVIC_InitStruct;
  • // 配置EXTI0中断
  • NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;          // EXTI0中断通道
  • NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级(根据需求设置)
  • NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;        // 子优先级(根据需求设置)
  • NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;           // 使能中断通道
  • NVIC_Init(&NVIC_InitStruct);/ f; q3 R: P/ e) _) _) t. }$ y

/ X  o* p) ~; h0 b6 R2 O
6. 编写中断服务函数中断服务函数需清除 EXTI 中断标志位(通过EXTI_ClearITPendingBit),否则会反复触发中断。. M$ ~! u# X6 b! F( z& K$ B

# f5 d0 P9 e& t* p2 Z; ]- m) f! u
  • // EXTI0中断服务函数(函数名必须与启动文件中的中断向量表一致)
  • void EXTI0_IRQHandler(void)
  • {
  •     // 检查EXTI0中断标志位是否置位
  •     if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  •     {
  •         // *************************
  •         // 此处编写中断处理逻辑(如LED翻转、数据读取)
  •         // *************************
  •         EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位
  •     }
  • }1 S( R+ c& w0 l) q
8 S: |7 w* I  D7 a3 \# [
三、关键注意事项
  • 引脚映射限制:EXTI 线 n 只能映射到 GPIOx 的 n 号引脚(如 EXTI5 只能映射到 PA5、PB5、PC5 等)。
  • 中断标志位清除:必须在中断服务函数中清除 EXTI 的中断挂起位,否则中断会持续触发。
  • NVIC 优先级配置:需根据系统中断优先级规则合理设置抢占优先级和子优先级(注意 SCB->AIRCR 寄存器的优先级分组)。
  • 软件触发 EXTI:可通过EXTI_GenerateSWInterrupt函数手动触发 EXTI 中断,用于调试或软件模拟硬件触发。
    6 m4 u& X+ s3 r4 G5 f; m% A  L
  • // 软件触发EXTI0中断
  • EXTI_GenerateSWInterrupt(EXTI_Line0);
    : l- a( M- d8 q5 o5 ?
四、HAL 库配置示例(以 STM32F4 为例)若使用 STM32 HAL 库,配置逻辑更简洁,核心步骤如下:, n; `3 w0 M) m7 F1 E% K9 b/ w
  • GPIO_InitTypeDef GPIO_InitStruct = {0};
  • __HAL_RCC_GPIOA_CLK_ENABLE();
  • __HAL_RCC_SYSCFG_CLK_ENABLE();
  • // 配置PA0为上升沿触发的外部中断
  • GPIO_InitStruct.Pin = GPIO_PIN_0;
  • GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿中断模式
  • GPIO_InitStruct.Pull = GPIO_NOPULL;         // 浮空输入
  • HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);, Q( s, V1 f- J& U& P
  • 配置 NVIC:! g. L! ?. B' a+ r
  • HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  • HAL_NVIC_EnableIRQ(EXTI0_IRQn);! }8 N+ P# l) K
  • 中断服务函数与回调函数:HAL 库中,中断服务函数调用通用处理函数,最终通过回调函数执行业务逻辑:$ @. g5 T" f: n* b7 [+ H% d
  • // EXTI0中断服务函数
  • void EXTI0_IRQHandler(void)
  • {
  •     HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // 调用HAL库通用处理函数
  • }
  • // EXTI回调函数(重写此函数实现业务逻辑)
  • void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  • {
  •     if(GPIO_Pin == GPIO_PIN_0)
  •     {
  •         // 中断处理逻辑
  •     }
  • }$ a3 ^7 q- |0 _- c, [: y
五、EXTI 事件模式简介若配置为事件模式(EXTI_Mode_Event),EXTI 触发后不会向 NVIC 申请中断,而是通过硬件脉冲触发其他外设(如定时器的捕获、DMA 的启动)。配置时只需将EXTI_Mode设为EXTI_Mode_Event,无需配置 NVIC,也无需清除中断标志位。
- G7 \: S" H4 Q1 R. S+ x. n5 KEXTI 是 STM32 处理外部硬件触发的基础,掌握其配置流程对实现按键中断、传感器触发、外部设备通信等场景至关重要。
- ~3 V# }, A: M% g( L: ~
赞 收藏 评论0 发布时间:2025-12-22 15:26

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版