STM32——外部中断

一、外部中断 基础知识

1. 什么是外部中断

普通程序是顺序执行、循环轮询:单片机一直死循环挨个检测引脚电平,浪费 CPU 资源、响应还慢。

外部中断 :单片机正常跑自己的主程序,不去主动检测引脚 ;当外部引脚电平发生变化(高变低 / 低变高),硬件自动触发,立刻暂停当前主程序,跳转到专门的中断函数里执行,执行完再回到原来断点继续运行。

一句话:轮询是单片机主动一直盯着;中断是引脚有事主动通知单片机。

2. 外部中断能触发的信号类型

三种触发边沿,固定就这三种:

  1. 下降沿触发:高电平 → 低电平 瞬间触发
  2. 上升沿触发:低电平 → 高电平 瞬间触发
  3. 双边沿触发:上升、下降任意一种变化都触发

3. STM32 外部中断线路规则

STM32F1 系列有 16 根外部中断线 EXTI0 ~ EXTI15对应引脚编号 0~15:

  • EXTI0 对应 所有 GPIO 的第 0 脚:PA0/PB0/PC0...
  • EXTI1 对应 所有 GPIO 的第 1 脚:PA1/PB1/PC1...
  • ......
  • EXTI15 对应 所有 GPIO 的第 15 脚

重点规则 同一条中断线,同一时刻只能用一个引脚;比如 EXTI0 用了 PA0,就不能再同时用 PB0、PC0 做外部中断。

4. 外部中断整体工作流程

引脚电平变化 → 触发 EXTI 外设 → 申请中断 → NVIC 裁决是否放行 → 进入中断服务函数执行。

二、复用功能 AFIO

1. 什么是 GPIO 复用功能

STM32 的每个 GPIO 引脚不只有普通输入 / 普通输出这一种功能;一个引脚可以有多种身份:

  • 普通 GPIO 输入输出
  • 串口收发
  • SPI、I2C
  • 定时器 PWM
  • 外部中断输入

这种一个引脚具备多种硬件功能 ,就叫 复用功能(Alternate Function)

2. 为什么外部中断必须用到 AFIO

普通 GPIO 输入只做普通电平读取;要把 GPIO 引脚切换成外部中断功能 ,不属于普通 GPIO 模式,属于复用功能 ,必须由 AFIO 外设 来管理配置。

3. 关键必记知识点

  1. 只要用外部中断,必须开启 AFIO 外设时钟
  2. AFIO 不负责高低电平读取,只负责:
    • 引脚中断线选择
    • 引脚功能重映射
  3. 没有开启 AFIO 时钟,外部中断配置再对也进不去中断

三、重映射(引脚映射 / 中断线映射)

1. 什么是重映射

前面说了:PA0、PB0、PC0...... 都共用 EXTI0 这一根中断线。

单片机不知道你到底想用哪一个端口的第 0 脚 做中断;我们需要手动指定:把哪一个 GPIO 端口的引脚,绑定到对应的 EXTI 中断线上 这个指定绑定的过程,就叫重映射

2. 重映射的作用

  • 选择同一中断线下具体用哪个引脚(PAx / PBx / PCx)
  • 可以把部分外设功能切换到其他引脚(引脚功能重映射)
  • 解决引脚不够、布线不方便的问题

3. 核心逻辑

中断线是固定的 EXTI0~EXTI15;引脚是灵活的,可以通过重映射,任选同编号的一个 GPIO 引脚挂到这条中断线上

4. 重映射和普通 GPIO 的区别

普通 GPIO:直接配置模式即可;外部中断:除了配 GPIO 模式,必须多一步重映射,把引脚关联到 EXTI 中断线

四、中断嵌套控制器 NVIC

1. 什么是 NVIC

NVIC 是单片机内核自带的 嵌套向量中断控制器,是所有中断的 "大管家"。

EXTI 只是负责检测电平、产生中断请求能不能响应、谁先响应、能不能插队,全部由 NVIC 说了算。

2. NVIC 管哪三件事

  1. 开启 / 关闭 某个中断通道
  2. 设置中断优先级
  3. 处理中断嵌套(高优先级打断低优先级)

3. 两个优先级概念(重点,必须懂)

STM32 中断优先级分两层:

  1. 抢占优先级 级别高的中断,可以打断正在执行的低优先级中断,实现中断嵌套。数字越小,优先级越高。

  2. 子优先级 多个中断同时一起到来,谁先执行;不能打断别人,只做排队顺序。

4. 中断嵌套是什么意思

低优先级中断正在运行,此时来了一个抢占优先级更高 的中断;NVIC 允许高优先级插队,暂停当前低优先级,先执行高优先级中断,执行完再回来继续原来的。这就叫中断嵌套

5. NVIC 配置的意义

哪怕 EXTI 配置全对、引脚配置全对;NVIC 不开启通道、不设优先级,中断永远进不去

五、STM32 外部中断 EXTI 标准配置步骤

1、提前必配:中断分组(程序开头只调用一次)

放在 main 最开头,整个工程统一分组,只用这一种:

复制代码
// 设置中断分组2:2位抢占优先级,2位子优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

第 1 步:开启 GPIO 时钟

所有 GPIO 外设必须先开时钟,才能工作,这是 STM32 所有外设的通用规则。

复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

替换:GPIOAGPIOB/GPIOC

第 2 步:开启 AFIO 时钟

外部中断属于GPIO 复用功能 ,必须依赖 AFIO 外设;不开 AFIO 时钟,后面重映射、中断线配置全部无效,进不了中断。

复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

所有外部中断,这一句必加,不能省

第 3 步:配置 GPIO 输入模式

外部中断引脚只能配置为三种输入模式:

  • 上拉输入

  • 下拉输入

  • 浮空输入不能配成输出、复用输出,否则无法检测电平边沿变化。

    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; // 填你要用的引脚
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    // 可选:GPIO_Mode_IPD 下拉输入 / GPIO_Mode_IN_FLOATING 浮空输入

    GPIO_Init(GPIOA, &GPIO_InitStruct); // 对应端口

第 4 步:GPIO 中断线重映射

作用:把 某一组 GPIO 的某一号引脚,指定绑定到对应的 EXTIx 中断线上。规则:引脚编号 x 只能绑定 EXTIx 中断线,不能跨号绑定。

复制代码
// 把 GPIOA Pin0 映射到 EXTI0 中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

规则:

  • PinSource0 只能配 EXTI0
  • 引脚号和中断线号必须一致

第 5 步:配置 EXTI 外设

配置三件事:

  1. 选择触发方式:上升沿 / 下降沿 / 双边沿

  2. 选择工作模式:中断模式(不是事件模式)

  3. 使能对应 EXTI 中断线,允许它发出中断请求

    EXTI_InitTypeDef EXTI_InitStruct;

    EXTI_InitStruct.EXTI_Line = EXTI_Line0; // 对应中断线
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
    // 可选:EXTI_Trigger_Rising 上升沿 / EXTI_Trigger_Rising_Falling 双边沿
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStruct);

第 6 步:配置 NVIC 中断控制器

配置三件事:

  1. 选择对应的中断通道

  2. 设置抢占优先级子优先级

  3. 使能该中断通道,允许内核响应这个中断

    NVIC_InitTypeDef NVIC_InitStruct;

    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // 对应中断通道
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

第7步:中断服务函数模板(固定函数名,不能自己乱改)

写在任意 .c 文件里,不用声明,自动响应中断:

复制代码
void EXTI0_IRQHandler(void)
{
    // 检查是不是对应中断线触发
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 这里写中断触发后要执行的代码


        // 必须清除中断标志位,否则一直重复进中断
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

2、配置完硬件后必做一步

在工程里自行编写 中断服务函数固定规则:

  • 函数名不能自己乱起,要匹配芯片启动文件里的中断函数名
  • 函数内部写中断触发后要执行的逻辑
  • 不需要手动调用,硬件触发自动跳转执行

3、浓缩口诀

开 GPIO → 开 AFIO → 配输入 → 做重映射 → 配 EXTI → 配 NVIC → 写中断服务函数。

4、补充两个必记硬性规则

  1. 所有同编号引脚(PAx、PBx、PCx)共用一条 EXTIx 中断线,同一时间只能用一个
  2. 外部中断缺一不可:AFIO 时钟 + 重映射 + EXTI 配置 + NVIC 配置,少任何一步都进不去中断。

附:常用中断线 对应通道 & 函数名 对照表

中断线 NVIC 通道名 中断服务函数名
EXTI0 EXTI0_IRQn EXTI0_IRQHandler
EXTI1 EXTI1_IRQn EXTI1_IRQHandler
EXTI2 EXTI2_IRQn EXTI2_IRQHandler
EXTI3 EXTI3_IRQn EXTI3_IRQHandler
EXTI4 EXTI4_IRQn EXTI4_IRQHandler
EXTI5~9 EXTI9_5_IRQn EXTI9_5_IRQHandler
EXTI10~15 EXTI15_10_IRQn EXTI15_10_IRQHandler
相关推荐
踏着七彩祥云的小丑6 小时前
嵌入式——认识电子元器件——继电器系列
单片机·嵌入式硬件
智塑未来7 小时前
GJB电磁兼容标准对加固SSD有哪些要求?测试项目与合格指标
单片机·嵌入式硬件
IT_阿水7 小时前
基于STM32河流水质检测软件设计
stm32·单片机·嵌入式硬件
esmember7 小时前
电路研究12.1——保护电路设计指南
单片机·嵌入式硬件
Wave84520 小时前
基于 STM32 + ESP8266 + W25Q64 的双核 OTA 底层架构总结
stm32·嵌入式硬件·架构
xiangw@GZ21 小时前
WiFi 全世代(WiFi1~WiFi7)技术规范与核心参数总结
嵌入式硬件
振南的单片机世界21 小时前
CPU时钟:频率越高跑越快,但物理极限在“拖后腿”
stm32·单片机·嵌入式硬件
普中科技1 天前
【普中 51-Ai8051 开发攻略】-- 第 20 章 输入捕获实验
单片机·嵌入式硬件·输入捕获·pca·普中科技·ai8051u·aicube
d111111111d1 天前
直流电机位置式 PID 控制 和 舵机的区别
笔记·stm32·单片机·嵌入式硬件·学习