STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)
一、中断概述
-
中断:在主程序运行过程中,出现了特定事件,使得 CPU 暂停当前正在运行的程序,转而去处理这个事件,等这个事件处理完成之后,CPU 再回到刚才被打断的位置继续处理
-
中断源:打断 CPU 执行的特定事件
-
断点:被中断源打断的位置
-
执行中断处理程序:处理特定事件的过程
-
中断嵌套:在执行中断程序的时候,这个时候有可能被另外一个中断源给中断,CPU 转而去执行另外一个中断源的中断处理程序
-
中断优先级:优先级高的可以打断优先级低的,优先级低的无法打断优先级高的
-
外部中断源与内部中断源:中断源可以是外部的,也可以是内部的
二、STM32 的中断
-
Cortex-M3
内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置 -
一般情况下,芯片厂商会对
Cortex-M3
的中断进行裁剪 -
STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级
-
STM32F103 系列有 70 个中断,有 10 个内核中断和 60 个可编程的外部中断
三、NVIC 嵌套向量中断控制器
1、概述
-
NVIC(Nested Vectored Interrupt Controller)嵌套向量中断控制器,是用于管理中断的核心模块
-
NVIC 可以高效处理多优先级中断,支持低延迟响应
-
NVIC 管理着包括内核异常,外部中断等所有中断,由 NVIC 决定哪个中断的处理程序交给 CPU 来执行
-
每一个外部中断都可以被使能或者禁止,并且可以被设置为挂起状态或者清除状态
-
处理器的中断可以是电平形式的,也可以是脉冲形式的,这样 NVIC 就可以处理任何中断源
-
16 个 IO 的中断与 PVD(电源电压检测),RTC(实时时钟),USB,以太网检测这 20 个外部中断会通过 EXTI 来控制,然后交给 NVIC,其他中断都是直接交给 NVIC 来处理
2、中断优先级
- NVIC 为了方便管理中断,可以通过软件给每个中断设置优先级,NVIC 用 4 个位来控制优先级,值小的优先级高,把优先级分为两种:抢占优先级与响应优先级
-
优先级值越小,优先级越高
-
如果不设置优先级,则默认优先级为 0
-
先比较抢占优先级,抢占优先级高的可以打断抢占优先级低的
-
若抢占优先级一样,再比较响应优先级,但是响应优先级不会导致中断嵌套
-
若抢占优先级一样的同时挂起,则优先处理响应抢占优先级高的
-
若挂起的优先级(抢占和响应)都一样,则查找中断向量表,值小的先响应
- NVIC 对优先级分了 5 组,在程序中先对中断进行分组,而且分组只能分一次,若多次分,只有最后一次生效
分组 | 抢占优先级 | 响应优先级 |
---|---|---|
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 |
四、外部中断配置寄存器组
typedef struct
{__IO uint32_t EVCR;__IO uint32_t MAPR;__IO uint32_t EXTICR[4];uint32_t RESERVED0;__IO uint32_t MAPR2;
} AFIO_TypeDef;
-
其中,
EXTICR[4]
是外部中断配置寄存器组 -
它由 4 个 32 位寄存器组成,每个寄存器控制 4 个外部中断线的配置
-
外部中断配置寄存器组用于将 GPIO 引脚连接到对应的 EXTI 中断线
寄存器 | 地址偏移 | 管理的中断线 |
---|---|---|
EXTICR[0] | 0x08 | EXTI0 ~ EXTI3 |
EXTICR[1] | 0x0C | EXTI4 ~ EXTI7 |
EXTICR[2] | 0x10 | EXTI8 ~ EXTI11 |
EXTICR[3] | 0x14 | EXTI12 ~ EXTI15 |
- 例如,
EXTICR[0]
就是控制EXTI0 ~ EXTI3
这 4 个外部中断线的配置
位域 | 功能 | 对应 GPIO 端口 |
---|---|---|
EXTI3[15:11] | 选择 EXTI3 的 GPIO 端口(PA3 ~ PI3) | 0000 : PA30001 : PB30010 : PC30011 : PD30100 : PE30101 : PF30110 : PG30111 : PH31000 : PI3 |
EXTI2[11:8] | 选择 EXTI2 的 GPIO 端口(PA2 ~ PI2) | 0000 : PA20001 : PB20010 : PC20011 : PD20100 : PE20101 : PF20110 : PG20111 : PH21000 : PI2 |
EXTI1[7:4] | 选择 EXTI1 的 GPIO 端口(PA1 ~ PI1) | 0000 : PA10001 : PB10010 : PC10011 : PD10100 : PE10101 : PF10110 : PG10111 : PH11000 : PI1 |
EXTI0[3:0] | 选择 EXTI0 的 GPIO 端口(PA0 ~ PI0) | 0000 : PA00001 : PB00010 : PC00011 : PD00100 : PE00101 : PF00110 : PG00111 : PH01000 : PI0 |
五、EXTI 外部中断控制器
基本介绍
-
EXTI,全称 External Interrupt/Event Controller,即外部中断控制器
-
EXTI 是 STM32 中用于管理外部中断和事件的模块,它负责检测 GPIO 引脚、外设或软件触发的中断 / 事件请求,并将其传递给 NVIC 或直接触发事件响应
typedef struct
{__IO uint32_t IMR;__IO uint32_t EMR;__IO uint32_t RTSR;__IO uint32_t FTSR;__IO uint32_t SWIER;__IO uint32_t PR;
} EXTI_TypeDef;
寄存器 | 地址偏移 | 功能 |
---|---|---|
IMR | 0x00 | 中断屏蔽寄存器 |
EMR | 0x04 | 事件屏蔽寄存器 |
RTSR | 0x08 | 上升沿触发选择寄存器 |
FTSR | 0x0C | 下降沿触发选择寄存器 |
SWIER | 0x10 | 软件中断事件寄存器 |
PR | 0x14 | 中断挂起寄存器 |
IMR
-
IMR 全称 Interrupt Mask Register,即中断屏蔽寄存器
-
IMR 控制是否允许外部中断线产生中断请求,即屏蔽或使能
位域 | 说明 |
---|---|
[31:20] | 保留,必须始终保持为复位状态(0) |
[19:0] | 线 x 上的中断屏蔽 0:屏蔽来自线 x 上的中断请求 1:开放来自线 x 上的中断请求 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
EMR
-
EMR 全称 Event Mask Register,即事件屏蔽寄存器
-
EMR 控制是否允许外部中断线产生事件请求,即屏蔽或使能
位域 | 说明 |
---|---|
[31:20] | 保留,必须始终保持为复位状态(0) |
[19:0] | 线 x 上的事件屏蔽 0:屏蔽来自线 x 上的事件请求 1:开放来自线 x 上的事件请求 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
RTSR
-
RTSR 全称 Rising Trigger Selection Register,即上升沿触发选择寄存器
-
RTSR 配置外部中断 / 事件的触发条件为信号上升沿,即从低电平跳变到高电平
位域 | 说明 |
---|---|
[31:19] | 保留,必须始终保持为复位状态(0) 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
[18:0] | 线 x 上的上升沿触发选择 0:禁止来自线 x 上的上升沿触发 1:开放来自线 x 上的上升沿触发 |
FTSR
-
FTSR 全称 Falling Trigger Selection Register,即下降沿触发选择寄存器
-
FTSR 配置外部中断 / 事件的触发条件为信号下降沿,即从低电平跳变到高电平
位域 | 说明 |
---|---|
[31:19] | 保留,必须始终保持为复位状态(0) 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
[18:0] | 线 x 上的下降沿触发选择 0:禁止来自线 x 上的下降沿触发 1:开放来自线 x 上的下降沿触发 |
SWIER
-
SWIER 全称 Software Interrupt Event Register,即软件中断事件寄存器
-
SWIER 通过软件写入模拟外部中断 / 事件的触发,即无需实际电平变化
位域 | 说明 |
---|---|
[31:19] | 保留,必须始终保持为复位状态(0) 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
[18:0] | 线 x 上的软件中断 / 事件 当该位为 0 时,写 1 将设置 PR 中相应的挂起位,如果在 IMR 和 EMR 中允许产生该中断 / 事件,则此时将产生一个中断 / 事件 通过清除 PR 的对应位,即写 1 到 PR,可以间接清除该位为 0 |
PR
-
PR 全称 Pending Register,即中断挂起寄存器
-
OR 标志请求是否已触发且未处理(挂起状态)
位域 | 说明 |
---|---|
[31:19] | 保留,必须始终保持为复位状态(0) 注:位 19 只适用于互联型产品,对于其它产品为保留位 |
[18:0] | 线 x 上的挂起位 0:没有发生触发请求 1:发生了选择的触发请求 当在外部中断线上发生了选择的边沿事件,该位被置 1,在该位中写入 1 可以清除它,也可以通过改变边沿检测的极性清除 |
六、实例实操
- 使用按钮 PE4 作为按键输入,通过外部中断控制 LED 灯 PB5
#include "stm32f10x.h"int main()
{// RCC APB2 使能RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 使能 GPIOB 时钟RCC->APB2ENR |= RCC_APB2ENR_IOPEEN; // 使能 GPIOE 时钟RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // 使能 AFIO 时钟(用于外部中断配置)// 清除 PB5 配置GPIOB->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);// 清除 PE4 配置GPIOE->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);// 设置 PB5 为推挽输出模式,最大速度为 50MHGPIOB->CRL |= GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1;// 设置 PE4 为输入模式,上拉GPIOE->CRL |= GPIO_CRL_CNF4_0;GPIOE->ODR |= GPIO_ODR_ODR4;// 点亮 PB5GPIOB->ODR &= ~GPIO_ODR_ODR5;// 清除 EXTI4 配置AFIO->EXTICR[1] &= ~AFIO_EXTICR2_EXTI4; // 清除 EXTI4 的连接EXTI->IMR &= ~EXTI_IMR_MR4; // 禁用EXTI4中断屏蔽EXTI->FTSR &= ~EXTI_FTSR_TR4; // 禁用EXTI4下降沿触发// 设置 EXTI4 配置AFIO->EXTICR[1] |= AFIO_EXTICR2_EXTI4_PE; // 将 PE4 连接到 EXTI4EXTI->IMR |= EXTI_IMR_MR4; // 使能 EXTI4 中断屏蔽EXTI->FTSR |= EXTI_FTSR_TR4; // 使能 EXTI4 下降沿触发// 设置 EXTI4 中断优先级为15NVIC_SetPriority(EXTI4_IRQn, 0x0F);// 使能 EXTI4 中断通道NVIC_EnableIRQ(EXTI4_IRQn);while (1);
}void EXTI4_IRQHandler(void)
{// 检查中断标志if (EXTI->PR & EXTI_PR_PR4){EXTI->PR = EXTI_PR_PR4;// 软件消抖for (volatile uint32_t i = 0; i < 720000; i++);// 翻转 PB5GPIOB->ODR ^= GPIO_ODR_ODR5;}
}