Skip to content

EXTI (外部中断)

它的核心任务只有两件事:

  1. 选路: 决定去监视哪一个引脚。
  2. 甚至: 决定什么样的信号才算“异常情况”(上升沿/下降沿)。

我们需要解决三个核心问题:“边沿检测”“线路冲突”“中断与事件的区别”

三大关键特性

边沿检测

EXTI 不关心现在的电压是高是低,它只关心电压改变的那一瞬间。

  • 上升沿 (Rising Edge): 电压从 0 -> 1 的瞬间(比如松开按键)。
  • 下降沿 (Falling Edge): 电压从 1 -> 0 的瞬间(比如按下按键)。
  • 双边沿 (Both Edges): 只要变了就触发。

STM32 虽然有 GPIOA, GPIOB, GPIOC... 这么多组端口,但 EXTI 只有 16 条独立的线路 (Line 0 ~ Line 15)。

线路冲突 (GPIO 的 16 路复用)

这是 EXTI 最坑、也是新手最容易犯错的地方。

STM32 有很多 GPIO 口(PA, PB, PC... 每个都有 0~15 号引脚)。但是,EXTI 只有 16 个主要通道 (EXTI0 ~ EXTI15)

这就意味着:资源是不够分的。

  • 规则: 所有端口的 同号引脚,共用一条 EXTI 线路。
    • PA0, PB0, PC0, PD0 ... -> 只能选 1 个 连接到 EXTI0
    • PA1, PB1, PC1, PD1 ... -> 只能选 1 个 连接到 EXTI1
  • 比喻:
    • EXTI 是只有 16 个屏幕的监控室
    • 屏幕 #0 只能显示一个画面。你可以让它显示 正门(PA0) 的画面,也可以显示 后门(PB0) 的画面,但不能同时显示!
    • 这就需要 AFIO (复用功能 IO) 这个“视频切换器”来决定把哪路信号接到屏幕上。

结论: 你无法同时开启 PA0 和 PB0 的外部中断。如果你需要两个中断,请把硬件连接改到 PA0 和 PB1(不同号即可)。

  • Line 0: 只能接 PA0 或者 PB0 或者 PC0...
  • Line 1: 只能接 PA1 或者 PB1 或者 PC1...

你无法在同一时刻,既开启 PA0 的中断,又开启 PB0 的中断。它们会打架。你需要用 AFIO (复用功能 IO) 这个“路由器”来决定让谁连上 EXTI Line 0。

中断 vs 事件

  • 中断 (Interrupt):

    通向 CPU。触发软件回调函数 (IRQHandler)。 -> 这是你 99% 情况下用的。

    • 路径: EXTI -> NVIC -> CPU。
    • 动作: 打断 CPU,让 CPU 停下手里的活,去跑一段软件代码(中断服务函数)。
    • 比喻: 门铃响了,你(CPU)必须放下手里的游戏,去开门。
  • 事件 (Event):

    通向 其他外设(如 ADC、DMA)。不惊动 CPU,硬件之间自己搞定(比如:按钮一按 -> 触发 ADC 采集电压,CPU 全程不知道)。

    • 路径: EXTI -> 脉冲发生器 -> 其他外设 (DMA/ADC)。
    • 动作: 不打断 CPU。它直接发一个硬件信号给旁边的兄弟模块。
    • 比喻: 门口装了感应灯。人来了(EXTI),灯自动亮了(触发其他外设)。你(CPU)在屋里打游戏,根本不知道这事,也不需要你操心。

新手只要关注“中断”模式即可,“事件”模式通常用于低功耗唤醒或高级触发。

流程

当你在 PB14 上按了一下:

要让一个按键(比如接在 PA0)产生中断,你需要像“闯关”一样打通以下关节:

  1. 开启时钟:

    • 开启 GPIOA 时钟(因为要用 IO 口)。
    • 关键:开启 AFIO 时钟!(很多人忘了这个,导致中断没反应。因为需要 AFIO 来选引脚)。
  2. 配置 GPIO:

    • 设为输入模式(上拉/下拉/浮空)。
  3. 配置 AFIO (视频切换):

    • GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    • 意思: 告诉 AFIO,把 PA0 连通到 EXTI0 线路。
  4. 配置 EXTI (保安设定):

    • 线路:EXTI_Line0
    • 模式:EXTI_Mode_Interrupt (中断模式)
    • 触发:EXTI_Trigger_Falling (下降沿)
    • 使能:ENABLE
  5. 配置 NVIC (秘书通报):

    • 通道:EXTI0_IRQn
    • 优先级:设一个级别。
    • 使能:ENABLE
  6. GPIO (PB14): 感知到电压从 3.3V 变成了 0V。

  7. AFIO: 确认当前 Line 14 连的是 GPIOB。

  8. EXTI (Line 14): 检测到是一个 下降沿,符合设定,且中断没被屏蔽。

  9. NVIC: 给这个中断排个号(优先级),告诉 CPU:“别睡了,有急事!”

  10. CPU: 暂停当前的主程序,跳转到 EXTI15_10_IRQHandler 函数执行代码。

  11. 你: 在函数里翻转了 LED。

一句话总结:EXTI 就是让 GPIO 具备了“主动报警”的能力。