中断系统
- 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得 CPU 暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行
- 中断优先级:当有多个中断源同时申请中断时,CPU 会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源
- 中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU 再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回
中断系统的 "作用 + 好处":
就像你正在追剧(主程序),突然外卖到了(中断触发)------ 你暂停追剧(暂停主程序),先去拿外卖(处理中断),拿完再回来接着看(回到主程序)
- 好处 1:不用傻等:比如等按键按下时,不用一直循环检测 "按没按",有按键按了才会被 "叫过去处理",节省 CPU 资源;
- 好处 2:急事优先:比如设备突然故障(高优先级中断),能立刻暂停手头的事去处理故障,避免出问题;
- 好处 3:同时顾多件事:能 "并行" 处理多个突发情况(比如一边跑程序,一边响应按键、传感器信号)。
没有中断系统会怎么样?
相当于你追剧时,得每隔 1 分钟暂停一下,自己跑去门口看外卖到没到
- 要么效率极低:CPU 大部分时间在 "空等"(比如等按键),干不了别的;
- 要么错过急事:如果故障突然发生,你没正好 "检测" 到,就会一直没反应;
- 要么只能干一件事:没法同时处理多个任务(比如一边显示数据,一边响应按键)
简单说:中断是单片机的 "紧急呼叫器",有了它能又快又稳地处理突发情况;没它,单片机就会又笨又慢
这个是中断执行的流程图:遇到断点所有程序停止,然后断点向中断程序执行完成后回到断点进行之后的主函数

STM32 中断
- 68 个可屏蔽中断通道,包含 EXTI、TIM、ADC、USART、SPI、I2C、RTC 等多个外设
- 使用 NVIC 统一管理中断,每个中断通道都拥有 16 个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级
补充外设全称
- EXTI:External Interrupt(外部中断,用于检测 GPIO 引脚的电平变化 / 边沿触发)
- TIM:Timer(定时器,用于定时、计数、PWM 输出等功能的中断)
- ADC:Analog-to-Digital Converter(模数转换器,用于模拟信号转数字信号的中断)
- USART:Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步 / 异步收发器,用于串口通信的中断)
- SPI:Serial Peripheral Interface(串行外设接口,用于高速同步通信的中断)
- I2C:Inter-Integrated Circuit(集成电路总线,用于低速设备间通信的中断)
- RTC:Real-Time Clock(实时时钟,用于计时、闹钟等功能的中断)

NVIC是嵌套中断向量控制器,作用就是管理这些中断外设,可以说的上cpu的小助手,右边只有一个输出口给CPU,它会根据优先级来判断是先进行哪一个。
NVIC 优先级分组
- NVIC 的中断优先级由优先级寄存器的 4 位(0~15)决定,这 4 位可以进行切分,分为高 n 位的抢占优先级和低 4-n 位的响应优先级
- 抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号(可以上网查一下中断号顺序这里略过)排队
| 分组方式 | 抢占优先级 | 响应优先级 |
|---|---|---|
| 分组 0 | 0 位,取值为 0 | 4 位,取值为 0~15 |
| 分组 1 | 1 位,取值为 0~1 | 3 位,取值为 0~7 |
| 分组 2 | 2 位,取值为 0~3 | 2 位,取值为 0~3 |
| 分组 3 | 3 位,取值为 0~7 | 1 位,取值为 0~1 |
| 分组 4 | 4 位,取值为 0~15 | 0 位,取值为 0 |
补充说明(大白话解释)
-
医院排队等号就是按照号码先后来排队,但是有的病人后来的但是病情严重就可以插队等待里面的病人出来就可以上,如果是抢占优先级的话哪怕是正在看病的人都可以先让他罚站一会等待他先看完再说
-
4 位优先级的切分逻辑:NVIC 用 4 个二进制位(共 16 种组合)表示优先级,通过 "分组" 把这 4 位分成两部分:
- 前 n 位 = 抢占优先级(决定 "能不能打断别人");
- 后 (4-n) 位 = 响应优先级(决定 "排队谁先上")
抢占优先级 vs 响应优先级 :
- 抢占优先级:值越小,优先级越高。高抢占优先级的中断,可以打断正在执行的低抢占优先级中断(对应 "中断嵌套")
- 响应优先级:值越小,优先级越高。抢占优先级相同的情况下,响应优先级高的中断会先执行;如果两者都相同,就按 "中断号"(硬件默认的序号)排队
EXTI 简介
- EXTI(Extern Interrupt)外部中断
- EXTI 可以监测指定 GPIO 口的电平信号,当其指定的 GPIO 口产生电平变化时,EXTI 将立即向 NVIC 发出中断申请,经过 NVIC 裁决后即可中断 CPU 主程序,使 CPU 执行 EXTI 对应的中断程序
- 支持的触发方式:上升沿 / 下降沿 / 双边沿 / 软件触发
- 支持的 GPIO 口:所有 GPIO 口,但相同的 Pin 不能同时触发中断
- 通道数:16 个 GPIO_Pin,外加 PVD 输出、RTC 闹钟、USB 唤醒、以太网唤醒
- 触发响应方式:中断响应 / 事件响应
每个名词的功能作用
-
EXTI(外部中断)
- 功能:STM32 中专门用来 "监测 GPIO 引脚电平变化" 的外设,是连接 GPIO 和中断系统的 "桥梁"。
- 作用:让单片机不用一直循环检测 GPIO 电平,引脚电平变了会主动 "喊 CPU 处理"。
-
触发方式(上升沿 / 下降沿 / 双边沿 / 软件触发)
- 上升沿触发:GPIO 引脚从低电平变高电平(比如按键松开时),触发中断;
- 下降沿触发:GPIO 引脚从高电平变低电平(比如按键按下时),触发中断;
- 双边沿触发:上升沿和下降沿都触发(比如按键按下 + 松开都触发);
- 软件触发:不用硬件电平变化,直接通过代码 "手动触发" EXTI 中断(用于调试或软件控制)。
-
支持的 GPIO 口(所有 GPIO 口,但相同 Pin 不能同时触发)
- 功能:EXTI 可以接 STM32 所有 GPIO 组(A~G 等)的引脚;
- 限制:比如 "PA0" 和 "PB0" 不能同时用 EXTI 监测(因为它们都是 Pin0,EXTI 的 Pin 通道是共用的)。
-
通道数(16 个 GPIO_Pin + 其他)
- 16 个 GPIO_Pin:对应 GPIO 的 Pin0~Pin15(每个 Pin 对应一个 EXTI 通道);
- 额外通道(这几个了解就可以)(PVD/RTC/USB/ 以太网):
- PVD 输出:电源电压监测(电压异常时触发);
- RTC 闹钟:RTC 时钟的闹钟时间到了触发;
- USB 唤醒:USB 设备休眠时,外部信号唤醒的触发;
- 以太网唤醒:以太网模块休眠时的唤醒触发。
-
触发响应方式(中断响应 / 事件响应)
- 中断响应:EXTI 触发后,向 NVIC 发中断请求,CPU 暂停主程序去执行中断函数(我们常用的 "中断处理");
- 事件响应:EXTI 触发后,不发中断请求,而是通过 "事件线" 直接触发其他外设(比如触发 ADC 采样),不占用 CPU 资源 (硬件级的快速联动)

这里有许多GPIO的外设但是其中会经过AFIO中断引脚进行选择,其中比如GPIOA和GPIOB这两个外设如果有一个相同的pin比如是GPIOA_pin0和GPIOB_pin0那么AFIO就会进行选择然后决定让谁过去。然后经过EXTI的检测过后就会有16个引脚外加上下面的事件响应通道进入NVIC和其他外设中。
还有就是因为NVIC 的中断通道数量比 EXTI 通道少,所以STM32采用 EXTI 中断通道的 "合并分组" 设计,核心是 "多个 EXTI 通道共用一个 NVIC 中断入口"
具体解释:
- EXTI 通道有 20 个左右 (Pin0~Pin15 + PVD/RTC 等),但NVIC 的中断入口数量有限,没法给每个 EXTI 通道单独分配一个中断入口;
- 所以把 "连续的 EXTI 通道" 合并成一组,共用一个 NVIC 中断入口:
EXTI9_5:代表 EXTI5、EXTI6、EXTI7、EXTI8、EXTI9 这 5 个通道,它们共用一个 NVIC 中断服务函数;EXTI15_10:代表 EXTI10 到 EXTI15 这 6 个通道,也共用一个 NVIC 中断服务函数;- 而 EXTI0~EXTI4 是 "每个通道单独对应一个 NVIC 入口"(因为数量少)
- 然后5到9和10到15这两个区间,每一个区间就只有一个中断函数,而0到4就各自有一个
AFIO

AFIO 复用 IO 口
- AFIO 主要用于引脚复用功能的选择和重定义
- 在 STM32 中,AFIO 主要完成两个任务:复用功能引脚重映射、中断引脚选择
1. AFIO(Alternate Function I/O,复用 IO 口)
- 核心作用:是 STM32 中管理 "引脚复用功能" 的外设 ------STM32 的 GPIO 引脚不仅能当普通输入输出用,还能 "复用" 成外设功能(比如 USART 的收发脚、SPI 的通信脚),AFIO 就是负责 "切换引脚的功能模式" 的 "开关"。
2. 复用功能引脚重映射
- 概念:把外设默认的引脚,重新分配到其他 GPIO 引脚上(比如 USART1 默认用 PA9/PA10,通过重映射可以改成 PB6/PB7)
- 作用细节 :
- 解决 "引脚冲突":比如多个外设默认引脚重叠时,用重映射换个引脚;
- 方便硬件布局:PCB 布线时,把外设引脚调整到更方便焊接的位置。
- 举例:TIM2 定时器默认引脚是 PA0~PA3,通过 AFIO 重映射,可以改成 PB10~PB13。
3. 中断引脚选择(对应 EXTI 中断)
- 概念:EXTI 外部中断需要监测 GPIO 引脚的电平变化,但 EXTI 的 "Pin 通道" 是共用的(比如 EXTI0 通道可以接 PA0、PB0、PC0...),AFIO 负责 "选择 EXTI 通道对应的具体 GPIO 组"。
- 作用细节 :
- 比如要让 EXTI0 中断监测 PB0 的电平变化,就需要通过 AFIO 设置 "EXTI0 通道关联 GPIOB 组";
- 如果不配置 AFIO,EXTI 通道默认只关联 GPIOA 组的引脚。
EXTI模式图


到底什么设备需要用到中断?又有什么好处呢?
一、需要用外部中断的设备
是 **"状态会突然变化、需要单片机立刻响应" 的外部设备 **,比如:
- 按键:按下 / 松开是瞬间的电平变化,需要立刻触发(比如按一下切换 LED 状态);
- 传感器:如红外传感器(检测到物体时电平突变)、触摸传感器(触摸时电平变化);
- 外部触发信号:如其他设备的电平信号(比如电机故障时的报警电平)。
二、用外部中断的好处
核心是 **"不用傻等,立刻响应"**,具体:
- 省 CPU 资源:不用一直循环检测设备状态(比如不用每隔 1ms 就查 "按键按了没"),设备变了才会 "喊" 单片机处理;
- 响应速度快:设备状态变化的瞬间就能触发中断,不会有延迟(比如按键按下 0.1ms 内就能响应,比循环检测快得多);
- 能同时处理多设备:可以给多个设备(比如多个按键)分别配中断,不用排队检测。

旋转编码器介绍
- 旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向
- 类型:机械触点式 / 霍尔传感器式 / 光栅式
详细讲解
一、旋转编码器的核心作用
是 **"把'旋转动作'转换成'电信号'" 的传感器 **------ 你转它的轴,它输出对应的方波(高低电平交替的信号),单片机读这个信号就能知道:
- 你往哪个方向转(顺时针 / 逆时针);
- 转了多快(速度);
- 转了多少角度 / 圈数(位置)。
二、怎么通过方波信号判断 "方向、速度"?
旋转编码器一般有A、B 两路输出信号(双相方波):
-
判断方向:看 A、B 信号的 "相位差"------
- 顺时针转:A 信号比 B 信号 "超前" 半个周期;
- 逆时针转:B 信号比 A 信号 "超前" 半个周期;单片机通过对比 A、B 的先后跳变,就能知道旋转方向。
-
判断速度:看方波的 "频率"------转得越快,方波交替的频率越高;转得越慢,频率越低。单片机统计单位时间内的方波个数,就能算出旋转速度。
三、三种类型的区别(怎么选)
| 类型 | 原理 | 优点 | 缺点 | 常用场景 |
|---|---|---|---|---|
| 机械触点式 | 旋转时内部金属触点通断 | 成本低、结构简单 | 触点易磨损、寿命短 | 低成本设备(比如小玩具) |
| 霍尔传感器式 | 旋转时磁场变化触发霍尔元件 | 无触点、寿命长、抗干扰强 | 精度中等 | 电机测速、家电旋钮 |
| 光栅式 | 旋转时遮挡 / 透过光栅,光电感应 | 精度极高、分辨率高 | 成本高、怕灰尘 | 工业设备、高精度仪器 |
硬件电路

这是旋转编码器的硬件电路(左边是详细电路,右边是模块接线图),分两部分详细讲:
一、左边的详细电路(元件作用)
这是机械触点式旋转编码器的外围电路(编码器是图里的 "带开关的旋转部件"),每个元件的作用:
- 编码器主体 :
- 有 3 个输出端(对应右边的 A、B、C):A、B 是旋转时的双相方波输出,C 是编码器自带按键的输出(按下时 C 接地)。
- R1、R2(10K 上拉电阻):机械编码器的触点是 "开漏输出",需要上拉电阻把电平拉到 VCC(否则输出信号不稳定)。
- R3、R4(10K 电阻)+ C1、C2(0.1uF 电容) :组成RC 滤波电路------ 机械触点旋转时会有 "抖动"(电平反复跳变),RC 滤波能消除抖动,让 A、B 信号更稳定。
- VCC/GND:给编码器供电(通常接 3.3V 或 5V,和单片机电压匹配)。
二、右边的模块接线图(实际怎么接)
这是把左边电路做成 "模块化" 后的接线方式,直接连单片机:
- VCC:接单片机的 3.3V 电源;
- GND:接单片机的 GND;
- A、B:接单片机的 GPIO 引脚(用来读旋转的双相方波);
- C:接单片机的 GPIO 引脚(用来读按键按下的信号);
- 图里的 "PA0、PA1" 是示例引脚,实际可以接任意 GPIO
核心作用
这个电路的目的是让旋转编码器的输出信号稳定、能被单片机正确读取------ 解决了机械触点的 "电平不稳定""抖动" 问题,同时把编码器的信号转换成单片机能识别的 GPIO 电平