中断与事件 原理
中断是什么,它有什么作用呢?
up的视频讲解:
1 中断与事件 原理
1.1 什么是中断?
举个例子: 你正在写作业, 但是你妈妈突然叫你去吃饭, 吃完饭后你再接着把作业写完.
- 写作业 -> 吃饭 -> 接着写作业
这个过程就叫中断, 那么对芯片而言呢?
1.2 中断四大阶段
- 中断请求
- 外设(按键、定时器、串口、ADC 等)满足触发条件后,向 CPU 发送中断请求信号
- 中断响应
-
CPU 检测到中断请求,且该中断未被屏蔽、优先级允许时
-
暂停当前正在执行的主程序
-
把当前寄存器、程序地址等现场数据压入栈保存
-
按照NVIC向量表地址, 跳转到对应中断的入口地址
- 中断处理
- CPU 执行专门用来处理该事件的代码,这段代码叫做中断服务函数。
- 中断返回
-
中断任务执行完毕后
-
从栈中恢复之前保存的寄存器、断点地址
-
CPU 回到被打断的主程序位置,继续往下执行
-
中断(Interrupt):
-
中断是CPU打断断开正在执行的程序, 去执行中断程序
-
进入NVIC,有相应的中断服务函数,需要CPU处理
-
-
事件(Event)
-
事件不强制打断CPU的运行, 只发出通知信号
-
不进入NVIC,仅用内部硬件自动控制,TIM,DMA,ADC等
-
1.3 中断优先级
STM32中断优先级基本概念:
-
抢占优先级(Preemption)
高抢占优先级(数值小)可以打断正在执行的低抢占优先级中断,实现中断嵌套。
-
响应优先级(Subpriority)
抢占优先级相同时,响应优先级高(数值小)的先执行;不能互相打断
-
自然优先级
由芯片硬件固定,对应中断向量表中的中断号(IRQn),编号越小优先级越高,软件不可改。
-
优先级数值规则 无论抢占还是响应,数值越小,优先级越高(0 最高)
-
同级仲裁规则 抢占优先级、响应优先级都相同时,自然优先级越高,先执行
2 NVIC
2.1 NVIC 中断控制器
NVIC(Nested Vectored Interrupt Controller): 嵌套向量中断控制器, 它在内核里面
-
NVIC属于是内核的器件(由ARM公司设计),M3 内核都是支持 256 个中断,其中包含了 16 个系统中断和 240 个外部中断,并且具有 256 级的可编程中断设置
-
但是对于ST公司来说,用不了M3内核中的所有中断以及中断优先级,进而对其进行了一定的裁剪。STM32中共有10个内核中断,60个外部中断,16个中断优先级;
-
我们可以从ST官方的(datasheet)数据手册中看到它

- 也可以在ARM官方Cortex-M3(Technical Reference)技术手册中看到它

2.2 NVIC 中断向量表
中断向量表定义在启动文件中,发生中断时,CPU会自动按照这张表的地址, 跳转到对应的中断服务函数
- 比如说这里的定时器向量, DMA中断向量, Uart串口中断等, 当然还有很多这里只是一部分

2.3 NVIC 寄存器
NVIC属于内核设备, 所以它的寄存器需要在Cortex-M3内核技术手册中找到, 这里写代码很少用到, 了解就行

ISER开启中断ICER关闭中断ISPR软件触发中断ICPR取消中断请求IABR看哪个中断在跑IPR设置中断优先级
2.4 NVIC 工作原理
-
内核中断由SHPR寄存器控制,SHPR与IPR寄存器属于同一级别
-
SHPRSystem Handler Priority Registers SCB(系统控制块)设置内核异常 -
AIRCRApplication Interrupt and Reset Control Register SCB(系统控制块)配置中断优先级分组、系统复位
-
-
外部中断,首先进入ICER、ISER寄存器,用于控制是否开对应的中断,
- 打开的中断进入IPR寄存器,进行中断优先级的判断
- IPR寄存器受AIRCR寄存器控制,最后按照中断优先级依次进入CPU被执行

:::
3 EXTI
3.1 EXTI 外部中断/事件
EXTI(External Interrupt/Event Controller): 外部中断/事件控制器
-
外部中断/事件, 来自芯片的外部, 通过引脚输入
-
内部中断/事件, 来自芯片内部, 通常由各外设发出如:
-
定时器中断:定时时间到了 → 中断
-
串口(UART)中断:收到数据 / 发完数据 → 中断
-
ADC 中断:模数转换完成 → 中断
-
DMA 中断:数据搬运完 → 中断
-
看门狗中断:超时报警 → 中断
-
3.2 EXTI 框架结构

Input Line: 多个 GPIO 引脚通过 AFIO 模块的多路选择器(MUX), 由AFIO_EXTICR寄存器控制, 分时复用到同一条 EXTI 中断线上, 然后进入外部中断/事件控制器
1 或门(OR): 一个输入有效时, 或门就会输出高电平请求信号
2 与门(AND): 两个输入都有效, 或门才会输出高电平请求信号
3.3 EXTI 寄存器

应当分为这3部分:
- 1 中断/事件 产生源 :
FTSR Falling trigger selection register(下降沿选择寄存器): 检测下降沿后, 产生一个脉冲信号(脉冲宽度为 1 个 PCLK2 周期)
RTSR Rising trigger selection register(上升沿选择寄存器)`: 检测到上升沿后, 产生一个脉冲信号
SWIER Software interrupt event register(软件中断事件寄存器): CPU 写该寄存器的对应位为 1, 即可强制产生一个中断 / 事件请求
- 2 生成 中断
PR Pending register(挂起请求寄存器): 该寄存器对应位置1, 表示中断请求已被挂起, 等待处理. 为 0时, 清除挂起状态
IMR Interrupt mask register(中断屏蔽寄存器): 若对应位为 0, 该中断请求会被屏蔽, 为 1 则允许
- 3 生成 事件 (不进入 NVIC)
EMR Event mask register(事件屏蔽寄存器): 同上
Pulse generator(脉冲发生器): 将电平信号转换为一个单周期的脉冲信号, 输出到片内外设(如定时器、ADC、DMA)
- 最顶上的APBbus, CPU就是通过该总线来访问这些寄存器的
3.4 EXTI 中断线
每个寄存器使用20位, 每一位对应一根外部中断线, 一共20根
-
0-15:对应GPIO_PIN 0-15中断
-
16:PVD输出
-
17:RTC闹钟事件
-
18:USB唤醒事件
-
19:连接到以太网唤醒事件

EXTI 线 0~15:对应外部 IO 口使用的中断线只有 16 个,但是 STM32F1 的 IO 口 却远远不止 16 个
-
所以 STM32 把 GPIO 管脚 GPIOx.0到GPIOx.15(x=A,B,C,D,E,F,G)通过
AFIO寄存器映射到中断线 0~15 -
以中断线线 EXTI0 为例:它对应了GPIOA.0、GPIOB.0、 GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0 和 GPIOG.0
-
而中断线每次只能连接到 1 个 IO 口上, 这样就需要通过配置决定对应的中断线配置到哪个 GPIO 上了

4 中断的使用
4.1 中断的使用步骤
EXIT的配置步骤
-
设置GPIO的模式
-
设置GPIO与EXIT映射关系
-
设置EXIT触发方式
-
设置NVIC中断优先级
-
设置中断服务函数

4.2 中断服务函数
HAL 库为了用户使用方便,提供了一个中断通用入口函数 HAL_GPIO_EXTI_IRQHandler
-
在该函数内部直接调用中断回调函数 HAL_GPIO_EXTI_Callback()
-
用户只要在中断回调函数中写程序即可