一、外部中断 基础知识1. 什么是外部中断普通程序是顺序执行、循环轮询单片机一直死循环挨个检测引脚电平浪费 CPU 资源、响应还慢。外部中断单片机正常跑自己的主程序不去主动检测引脚当外部引脚电平发生变化高变低 / 低变高硬件自动触发立刻暂停当前主程序跳转到专门的中断函数里执行执行完再回到原来断点继续运行。一句话轮询是单片机主动一直盯着中断是引脚有事主动通知单片机。2. 外部中断能触发的信号类型三种触发边沿固定就这三种下降沿触发高电平 → 低电平 瞬间触发上升沿触发低电平 → 高电平 瞬间触发双边沿触发上升、下降任意一种变化都触发3. STM32 外部中断线路规则STM32F1 系列有16 根外部中断线 EXTI0 ~ EXTI15对应引脚编号 0~15EXTI0 对应 所有 GPIO 的第 0 脚PA0/PB0/PC0...EXTI1 对应 所有 GPIO 的第 1 脚PA1/PB1/PC1...……EXTI15 对应 所有 GPIO 的第 15 脚重点规则同一条中断线同一时刻只能用一个引脚比如 EXTI0 用了 PA0就不能再同时用 PB0、PC0 做外部中断。4. 外部中断整体工作流程引脚电平变化 → 触发 EXTI 外设 → 申请中断 → NVIC 裁决是否放行 → 进入中断服务函数执行。二、复用功能 AFIO1. 什么是 GPIO 复用功能STM32 的每个 GPIO 引脚不只有普通输入 / 普通输出这一种功能一个引脚可以有多种身份普通 GPIO 输入输出串口收发SPI、I2C定时器 PWM外部中断输入这种一个引脚具备多种硬件功能就叫复用功能Alternate Function。2. 为什么外部中断必须用到 AFIO普通 GPIO 输入只做普通电平读取要把 GPIO 引脚切换成外部中断功能不属于普通 GPIO 模式属于复用功能必须由AFIO 外设来管理配置。3. 关键必记知识点只要用外部中断必须开启 AFIO 外设时钟AFIO 不负责高低电平读取只负责引脚中断线选择引脚功能重映射没有开启 AFIO 时钟外部中断配置再对也进不去中断。三、重映射引脚映射 / 中断线映射1. 什么是重映射前面说了PA0、PB0、PC0…… 都共用 EXTI0 这一根中断线。单片机不知道你到底想用哪一个端口的第 0 脚做中断我们需要手动指定把哪一个 GPIO 端口的引脚绑定到对应的 EXTI 中断线上这个指定绑定的过程就叫重映射。2. 重映射的作用选择同一中断线下具体用哪个引脚PAx / PBx / PCx可以把部分外设功能切换到其他引脚引脚功能重映射解决引脚不够、布线不方便的问题3. 核心逻辑中断线是固定的 EXTI0~EXTI15引脚是灵活的可以通过重映射任选同编号的一个 GPIO 引脚挂到这条中断线上。4. 重映射和普通 GPIO 的区别普通 GPIO直接配置模式即可外部中断除了配 GPIO 模式必须多一步重映射把引脚关联到 EXTI 中断线。四、中断嵌套控制器 NVIC1. 什么是 NVICNVIC 是单片机内核自带的嵌套向量中断控制器是所有中断的 “大管家”。EXTI 只是负责检测电平、产生中断请求能不能响应、谁先响应、能不能插队全部由 NVIC 说了算。2. NVIC 管哪三件事开启 / 关闭 某个中断通道设置中断优先级处理中断嵌套高优先级打断低优先级3. 两个优先级概念重点必须懂STM32 中断优先级分两层抢占优先级级别高的中断可以打断正在执行的低优先级中断实现中断嵌套。数字越小优先级越高。子优先级多个中断同时一起到来谁先执行不能打断别人只做排队顺序。4. 中断嵌套是什么意思低优先级中断正在运行此时来了一个抢占优先级更高的中断NVIC 允许高优先级插队暂停当前低优先级先执行高优先级中断执行完再回来继续原来的。这就叫中断嵌套。5. NVIC 配置的意义哪怕 EXTI 配置全对、引脚配置全对NVIC 不开启通道、不设优先级中断永远进不去。五、STM32 外部中断 EXTI 标准配置步骤1、提前必配中断分组程序开头只调用一次放在main最开头整个工程统一分组只用这一种// 设置中断分组22位抢占优先级2位子优先级 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);第 1 步开启 GPIO 时钟所有 GPIO 外设必须先开时钟才能工作这是 STM32 所有外设的通用规则。RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);替换GPIOA→GPIOB/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 外设配置三件事选择触发方式上升沿 / 下降沿 / 双边沿选择工作模式中断模式不是事件模式使能对应 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 中断控制器配置三件事选择对应的中断通道设置抢占优先级、子优先级使能该中断通道允许内核响应这个中断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、补充两个必记硬性规则所有同编号引脚PAx、PBx、PCx共用一条 EXTIx 中断线同一时间只能用一个。外部中断缺一不可AFIO 时钟 重映射 EXTI 配置 NVIC 配置少任何一步都进不去中断。附常用中断线 对应通道 函数名 对照表中断线NVIC 通道名中断服务函数名EXTI0EXTI0_IRQnEXTI0_IRQHandlerEXTI1EXTI1_IRQnEXTI1_IRQHandlerEXTI2EXTI2_IRQnEXTI2_IRQHandlerEXTI3EXTI3_IRQnEXTI3_IRQHandlerEXTI4EXTI4_IRQnEXTI4_IRQHandlerEXTI5~9EXTI9_5_IRQnEXTI9_5_IRQHandlerEXTI10~15EXTI15_10_IRQnEXTI15_10_IRQHandler