【STM32】03.中断和EXTI外设

一、EXTI简介

什么是 EXTI?(类比说明)

我们把 CPU 比作一个正在办公室专心写代码的程序员

  • 普通 GPIO(轮询模式,Polling) :就像程序员每隔 1 秒钟,就要跑到门口看一眼有没有人敲门。如果在没看的这 1 秒里刚好有人敲门,他就错过了。
  • EXTI(外部中断模式,Interrupt) :就像程序员在门口装了一个 "门铃(EXTI)" 。他安心在屋里写代码(执行主程序)。一旦有人按下门铃,门铃立刻响,CPU 会立刻把当前写的字保存一下,瞬间冲过去开门,处理完敲门的人,再回来继续写代码
    总结 :EXTI 就是让单片机能**"瞬间响应"**外部电平变化的机制。它不需要 CPU 一直盯着引脚看。

二、EXTI 的工作模式

1. 中断模式

  • 触发 CPU 中断执行 ISR(中断服务程序)
  • 用于需要立即处理的事件
    2. 事件模式
  • 唤醒 CPU 但不执行 ISR
  • 用于低功耗场景

三、EXTI 的触发方式

上升沿触发:信号从低电平到高电平
下降沿触发:信号从高电平到低电平
双边沿触发:上升沿和下降沿都触发

四、EXTI 系统架构

掌握了系统架构,对 EXTI 就有一个整体的把握,在编程时就思路就非常清晰。

1. EXTI 工作框图

触发信号由输入线进行输入:

2. EXTI 线路映射

EXTI有20个中断/事件线,每个GPIO都可以被设置为输入线,占用EXTI0至EXTI15。
值得注意的是:

  • 不同端口号,相同编号的引脚不能同时使用同一根输入线
  • 引脚编号决定连接哪根中断输入线,例如PA0只能连接到EXTI0、PB12只能连接到EXTI12。
  • 通过AFIO_EXTICRx配置GPIO线上的外部中断/事件,必须先使能AFIO时钟

    另外 4 个 EXTI 线的连接方式如下:

|-------------|-----------------|---------------------------------------|
| EXTI 线 | 连接到的外设事件 | 主要作用 |
| 线 16 EXTI16 | PVD 输出 | 电源电压监控。当供电电压低于或高于预设阈值时触发,用于掉电预警和数据保护。 |
| 线 17 EXTI17 | RTC 闹钟事件 | 绝对时间定点唤醒。在设定的具体日期和时间触发,用于执行定时任务。 |
| 线 18 EXTI18 | USB OTG FS 唤醒事件 | 全速USB远程唤醒。当检测到USB总线活动时,将系统从低功耗模式唤醒。 |
| 线 19 EXTI19 | 以太网唤醒事件 | 网络远程唤醒。当以太网收到唤醒数据包时触发,用于网络应用。 |
| 线 20 EXTI20 | USB OTG HS 唤醒事件 | 高速USB远程唤醒。功能同线18,但用于高速USB接口。 |

3. 关于中断标志

**在 STM32 中,中断标志是用于标识中断事件是否发生的状态位。当发生某中断时,对应的中断标志位则被置 1。**对于不同的中断线触发的中断,会将请求挂起寄存器对应的位置1,我们可以把这些对应的位理解成 EXTI 的中断标志位。

当发生中断时,运行中断服务函数后,需要手动清除中断标志位,不及时清除标志会产生严重后果:

  • 重复进入中断:导致系统卡死在同一个中断中
  • 系统崩溃:无法响应其他中断
  • 性能下降:CPU 时间被无效中断占用

五、EXTI 配置

以检测 KEY1 为例(当 KEY1 按下,会产生下降沿信号,因此我们要设置 EXTI 下降沿检测,触发中断):


2. 分析生成的代码


3. 中断服务程序

STM32CubeMX生成的中断服务程序是统一放到文件 stm32f1xx_it.c 的,PC12对应的中断服务程序为 EXTI15_10_IRQHandler() :

4. 定义自己的EXTI中断调用的函数

六、上述中断服务函数里运行延时函数说明

原则上,中断服务程序应该尽可能短小,避免任何阻塞操作,包括延时。

1. 为什么这里可以使用延时?

  1. 系统简单性
    如果这是一个单任务系统,没有其他重要中断 。
    这是一个学习/演示项目,对实时性要求不高
  2. 按键消抖的特殊需求
    机械按键会产生抖动,需要延时来确认稳定状态。
  3. 短时延时的可接受性
    15ms 在很多人机交互场景中是可接受的

2. 更好的解决方案

  • 定时器中断消抖
  • 硬件消抖(使用RC电路过滤抖动)

3. 建议

在学习阶段理解这种权衡,在实际项目中应采用更好的消抖方案。

七、EXTI 外部中断(hal_gpio.c 中断回调 + hal_exti.c)

1. HAL_GPIO_EXTI_IRQHandler

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);

  • 功能:EXTI中断服务函数入口,清除中断标志、调用中断回调
  • 参数:触发中断的引脚编号
  • 返回值:无
    使用:在stm32f1xx_it.c 对应EXTI中断函数内调用

2. HAL_GPIO_EXTI_Callback

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

  • 功能:弱函数,用户重写,外部中断触发后的业务处理逻辑
  • 参数:产生中断的引脚
  • 返回值:无
    重写示例:检测按键引脚执行对应操作

3. HAL_NVIC_EnableIRQ / HAL_NVIC_DisableIRQ

void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);

  • 功能:开启/关闭EXTI对应通道的NVIC中断
  • 参数:中断号,如EXTI0_IRQn、EXTI1_IRQn等
  • 返回值:无

4. HAL_NVIC_SetPriority

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);

  • 功能:配置EXTI中断抢占优先级、子优先级(F1仅2位抢占,2位子优先级)
  • 参数:IRQn:中断通道;PreemptPriority抢占优先级;SubPriority子优先级
  • 返回值:无
相关推荐
Wang's Blog2 小时前
PostgreSQL笔记34:索引优化策略全景解析——从B-tree到HOT的核心原理与实践
数据库·笔记·postgresql
金字塔頂の蝸牛2 小时前
商务日语口语实用手册
笔记·学习笔记·日语·外语
单片机杂货铺2 小时前
【单片机毕业设计选题】基于stm32单片机儿童公路车速度检测报警
stm32·单片机·嵌入式硬件·51单片机·硬件工程·课程设计
HwJack203 小时前
UIAbility 生命周期全链路:从冷启动到热启动的实战笔记
笔记·华为·harmonyos
九硕智慧建筑一体化厂家3 小时前
直流智能照明|全场景节能升级!打造安全低碳的智慧建筑光环境
运维·笔记·安全·智慧城市
振南的单片机世界3 小时前
看门狗硬核拆解:1.6秒不喂狗,硬件强制“掀桌子”
arm开发·stm32·单片机·嵌入式硬件
嵌入式阿蔡4 小时前
Linux_01:交叉编译与开发环境实战——从单片机跨到 Linux 的第一道坎
linux·运维·网络·单片机·嵌入式硬件·嵌入式实时数据库
NYFEA5 小时前
徕飞 FCA系列全面上新,一站式I/O扩展国产替代方案
单片机·嵌入式硬件
Wang's Blog6 小时前
PostgreSQL笔记36:执行计划基础解读与优化器成本模型
数据库·笔记·postgresql