【STM32】中断控制(内核篇)

STM32:

  • 68个可屏蔽中断通道以及16个Cortex™-M3内核中断共84个中断;
  • 16个可编程的优先等级(4位中断优先级控制);

STM32F103系列:

  • 60个可屏蔽中断通道以及10个内核中断共70个中断;
  • 16个可编程的优先等级(4位中断优先级控制);

简单来说,一个中断系统的几个重要组成包括:

  • 中断源
  • 中断向量/中断向量表
  • 中断服务程序

中断处理过程大概可以描述为:

  1. 中断请求
  2. 中断判优
  3. 中断响应
  4. 执行中断服务程序
  5. 返回原程序进度

下面将从中断组成和中断处理两个方向分别介绍STM32F103系列中断系统。


中断组成

STM32F103系列具有70个中断,包括10个内核中断和60个可编程中断(如下表,表中优先级排列顺序为中断默认优先级)。

位置优先优先级优先级类型名称说明地址
---保留0x0000_0000
-3固定Reset复位0x0000_0004
-2固定NMI不可屏蔽中断 RCC 时钟安全系统 (CSS) 联接到 NMI 向量0x0000_0008
-1固定硬件失效 (HardFault)所有类型的失效0x0000_000C
0可设置存储管理 (MemManage)存储器管理0x0000_0010
1可设置总线错误 (BusFault)预取指失败,存储器访问失败0x0000_0014
2可设置错误应用 (UsageFault)未定义的指令或非法状态0x0000_0018
---保留0x0000_001C ~0x0000_002B
3可设置SVCall通过 SWI 指令的系统服务调用0x0000_002C
4可设置调试监控 (DebugMonitor)调试监控器0x0000_0030
---保留0x0000_0034
5可设置PendSV可挂起的系统服务0x0000_0038
6可设置SysTick系统嘀嗒定时器0x0000_003C
07可设置WWDG窗口定时器中断0x0000_0040
18可设置PVD连到 EXTI 的电源电压检测 (PVD) 中断0x0000_0044
29可设置TAMPER侵入检测中断0x0000_0048
310可设置RTC实时时钟 (RTC) 全局中断0x0000_004C
411可设置FLASH闪存全局中断0x0000_0050
512可设置RCC复位和时钟控制 (RCC) 中断0x0000_0054
613可设置EXTI0EXTI 线 0 中断0x0000_0058
714可设置EXTI1EXTI 线 1 中断0x0000_005C
815可设置EXTI2EXTI 线 2 中断0x0000_0060
916可设置EXTI3EXTI 线 3 中断0x0000_0064
1017可设置EXTI4EXTI 线 4 中断0x0000_0068
1118可设置DMA1 通道 1DMA1 通道 1 全局中断0x0000_006C
1219可设置DMA1 通道 2DMA1 通道 2 全局中断0x0000_0070
1320可设置DMA1 通道 3DMA1 通道 3 全局中断0x0000_0074
1421可设置DMA1 通道 4DMA1 通道 4 全局中断0x0000_0078
1522可设置DMA1 通道 5DMA1 通道 5 全局中断0x0000_007C
1623可设置DMA1 通道 6DMA1 通道 6 全局中断0x0000_0080
1724可设置DMA1 通道 7DMA1 通道 7 全局中断0x0000_0084
1825可设置ADC1_2ADC1 和 ADC2 的全局中断0x0000_0088
1926可设置USB_HP_CAN_TXUSB 高优先级或 CAN 发送中断0x0000_008C
2027可设置USB_LP_CAN_RX0USB 低优先级或 CAN 接收 0 中断0x0000_0090
2128可设置CAN_RX1CAN 接收 1 中断0x0000_0094
2229可设置CAN_SCECAN SCE 中断0x0000_0098
2330可设置EXTI9_5EXTI 线 [9:5] 中断0x0000_009C
2431可设置TIM1_BRKTIM1 刹车中断0x0000_00A0
2532可设置TIM1_UPTIM1 更新中断0x0000_00A4
2633可设置TIM1_TRG_COMTIM1 触发和通信中断0x0000_00A8
2734可设置TIM1_CCTIM1 捕获比较中断0x0000_00AC
2835可设置TIM2TIM2 全局中断0x0000_00B0
2936可设置TIM3TIM3 全局中断0x0000_00B4
3037可设置TIM4TIM4 全局中断0x0000_00B8
3138可设置I2C1_EVI²C1 事件中断0x0000_00BC
3239可设置I2C1_ERI²C1 错误中断0x0000_00C0
3340可设置I2C2_EVI²C2 事件中断0x0000_00C4
3441可设置I2C2_ERI²C2 错误中断0x0000_00C8
3542可设置SPI1SPI1 全局中断0x0000_00CC
3643可设置SPI2SPI2 全局中断0x0000_00D0
3744可设置USART1USART1 全局中断0x0000_00D4
3845可设置USART2USART2 全局中断0x0000_00D8
3946可设置USART3USART3 全局中断0x0000_00DC
4047可设置EXTI15_10EXTI 线 [15:10] 中断0x0000_00E0
4148可设置RTCAlarm连到 EXTI 的 RTC 闹钟中断0x0000_00E4
4249可设置USB 唤醒连到 EXTI 的 USB 待机唤醒中断0x0000_00E8
4350可设置TIM8_BRKTIM8 刹车中断0x0000_00EC
4451可设置TIM8_UPTIM8 更新中断0x0000_00F0
4552可设置TIM8_TRG_COMTIM8 触发和通信中断0x0000_00F4
4653可设置TIM8_CCTIM8 捕获比较中断0x0000_00F8
4754可设置ADC3ADC3 全局中断0x0000_00FC
4855可设置FSMCFSMC 全局中断0x0000_0100
4956可设置SDIOSDIO 全局中断0x0000_0104
5057可设置TIM5TIM5 全局中断0x0000_0108
5158可设置SPI3SPI3 全局中断0x0000_010C
5259可设置UART4UART4 全局中断0x0000_0110
5360可设置UART5UART5 全局中断0x0000_0114
5461可设置TIM6TIM6 全局中断0x0000_0118
5562可设置TIM7TIM7 全局中断0x0000_011C
5663可设置DMA2 通道 1DMA2 通道 1 全局中断0x0000_0120
5764可设置DMA2 通道 2DMA2 通道 2 全局中断0x0000_0124
5865可设置DMA2 通道 3DMA2 通道 3 全局中断0x0000_0128
5966可设置DMA2 通道 4_5DMA2 通道 4 和 DMA2 通道 5 全局中断0x0000_012C

其中,前3个中断为不可屏蔽中断,涉及CPU的正常工作,优先级最高,且均为负值,是固定且不可修改的。前10个中断为内核中断,其中断源均在内核部,且大部分在一般编程过程中少有涉及,唯有系统滴答定时器(Systick)作为一个Cortex-M系列内核芯片共有的定时器常被用于实际开发。

后面60个中断中断源在内核以外,涉及时钟、定时器、DMADMADMAI2CI^2CI2C等片上其他资源以及外部中断。

中断向量/中断向量表

每个中断都对应有一个入口地址(上表最后一栏),也即中断向量,当对应中断发生响应时,程序跳转到该入口地址。由上表可知,相邻两个入口地址之间只有4个程序字间隔,这通常用以实现向中断服务程序首地址跳转的操作。所有这些入口地址共同组成该单片机的中断向量表,中断向量表被分配在内存中的一块固定位置上,用以告知CPU中断优先级及中断服务程序入口地址等信息。

中断优先级

STM32中断优先级分为抢占优先级和响应优先级。

抢占优先级(优先级组 group priority)

  1. 当CPU正在运行中断服务函数时,若又一中断事件发生,触发中断请求,则通过对比正在运行的中断与新触发的中断抢占优先级的高低。若新触发中断抢占优先级更高,则停止当前程序,执行新中断的中断服务函数,形成中断嵌套,执行完毕后返回原中断的处理程序;若新触发中断抢占优先级与正在执行的相等或更低,则等待当前中断服务函数执行完毕,再进入新中断的中断处理程序。
  2. 当有2个或以上中断同时触发或等待被执行时,通过对比其抢占优先级高低,确定执行顺序。

响应优先级(子优先级sub priority)

  1. 响应优先级不会打断正在运行的中断,即不会引起中断嵌套的发生。该功能更多是对于抢占优先级中第2条的补充,即在2个或以上中断同时触发或等待被执行时,若其抢占优先级相等,则对比响应优先级高低,响应优先级高的先执行。
  2. 在2个或以上中断同时触发或等待被执行时,若其抢占优先级和响应优先级均相等,则根据上表中默认优先级排序先后执行。

中断处理

NVIC

NVIC作为中断控制的“总管”,全名嵌套向量中断控制器(Nested vectored interrupt controller, NVIC),与CM3内核直接联系,负责管理STM32的所有中断(内核异常、外部中断),是用于中断管理的核心组件。当中断事件送入时,NVIC根据中断优先级及当前CPU状态决定中断的响应。

CM3内核简单框图

CM3内核NVIC最多支持240个外部中断和16个系统异常中断,具体可由芯片厂商按需设定。STM32F1系列非互联型产品的NVIC支持60个外部中断输入和10个系统异常中断。

NVIC组件具有多个寄存器组,通过内存映射的方式访问,地址范围为0xE000E100 ~ 0xE000E4FF,分别对应中断控制、优先级判断等功能。下面提取部分常见寄存器做出说明。

NVIC寄存器组
中断使能寄存器(ISERx)与中断清除使能寄存器(ICERx)

使用使能与除能两组寄存器分别控制使能中断和清除使能中断,与传统的使用单一比特的两个状态表达使能与除使能不同。这种方式下使能/除能中断只需向使能寄存器/清除使能寄存器对应位写1即可,而向对应位写0的操作是无效的。通过这种方式,每个中断都可以在不干扰其他位的情况下设置(写0无效),即只需要单一写指令,而不需要读-写-改。这种方式实际上使用ISER和ICER两个控制输入寄存器结果输入给实际的使能控制寄存器,而这两个寄存器是一种特殊的输入触发寄存器,在没有输入的时候处于高阻态,因此是不能直接读取其状态的。这样,对于这种情况:之前已经向ISER特定位输入"1"使能中断,在此之后向ICER对应位输入"1"清除使能,如果需要再次使能,不需要在ISER和ICER对应位重新输入"0"复位后再在ISER对应位输入"1",而是直接在ISER对应位再次输入"1"即可。

Cortex - M内核最多可以控制240个外部输入中断,故有ISER[0]~ISER[7]以及ICER[0] ~ICER[7]每组8个32位寄存器控制。STM32F103系列保留了所有8个寄存器,但是由于只支持60个可屏蔽中断,故其他部分都被预留未作实现,具体分配如下表:

寄存器名称内存地址位范围对应中断编号功能说明
ISER[0]0xE000E1000~310~31每一位对应一个中断,向某一位写 1 时,使能对应中断(0~31);写 0 无效果
ISER[1]0xE000E1040~2732~59每一位对应一个中断,向某一位写 1 时,使能对应中断(32~59);写 0 无效果
ISER[1]0xE000E10428~31无对应中断未使用(STM32F103 系列最大支持 60 个可屏蔽中断,超出部分无实际意义)
ISER[2]0xE000E1080~31无对应中断未使用(超出 STM32F103 可屏蔽中断数量范围)
ISER[3]0xE000E10C0~31无对应中断未使用
ISER[4]0xE000E1100~31无对应中断未使用
ISER[5]0xE000E1140~31无对应中断未使用
ISER[6]0xE000E1180~31无对应中断未使用
ISER[7]0xE000E11C0~31无对应中断未使用
ICER[0]0xE000E1800~310~31每一位对应一个中断,向某一位写 1 时,清除对应中断(0~31)的使能状态;写 0 无效果
ICER[1]0xE000E1840~2732~59每一位对应一个中断,向某一位写 1 时,清除对应中断(32~59)的使能状态;写 0 无效果
ICER[1]0xE000E18428~31无对应中断未使用(STM32F103 系列最大支持 60 个可屏蔽中断,超出部分无实际意义)
ICER[2]0xE000E1880~31无对应中断未使用(超出 STM32F103 可屏蔽中断数量范围)
ICER[3]0xE000E18C0~31无对应中断未使用
ICER[4]0xE000E1900~31无对应中断未使用
ICER[5]0xE000E1940~31无对应中断未使用
ICER[6]0xE000E1980~31无对应中断未使用
ICER[7]0xE000E19C0~31无对应中断未使用

这里使能控制都是针对外部中断输入,对于内核中断,正常情况下一般很少配置,大部分通过系统控制块(SCB)的特殊功能寄存器实现。具体配置信息如下表:

内核中断(异常)编号使能配置方式能否禁用说明
复位(Reset)-15硬件触发,无软件使能位不可禁用系统上电 / 复位时自动触发,优先级最高
NMI-2硬件触发(如外部 NMI 引脚),无软件使能位不可禁用不可屏蔽,不受全局中断开关(PRIMASK)影响
硬故障(HardFault)-1无单独使能位,默认始终使能不可禁用响应严重错误(如总线错误、未定义指令),无法通过软件禁用
内存管理故障(MemManage)4通过SCB->SHCSRMEMFAULTENA位使能可配置响应存储器访问错误(如访问未授权区域)
总线故障(BusFault)5通过SCB->SHCSRBUSFAULTENA位使能可配置响应总线错误(如外设访问错误、预取指错误)
用法故障(UsageFault)6通过SCB->SHCSRUSGFAULTENA位使能可配置响应指令用法错误(如未对齐访问、未定义指令)
SVC(系统服务调用)11无使能位,由SVC指令直接触发无需使能用于用户态到内核态的系统调用,指令执行即触发
调试监控(DebugMonitor)12由调试器配置(如DBGMCU寄存器),内核层面无使能位可配置调试时触发(如断点、单步执行),通常由调试工具控制
PendSV(可挂起系统调用)14无使能位,通过SCB->ICSRPENDSVSET位置位触发无需使能用于低优先级任务切换,触发后等待当前高优先级任务完成后执行
SysTick(系统滴答定时器)15通过SysTick->CTRLTICKINT位使能可配置系统定时器中断,用于操作系统时钟或定时任务
中断挂起寄存器(ISPRx)与中断清除挂起寄存器(ICPRx)

首先了解一下什么是挂起:当一个中断触发(如外部引脚电平发生变化、定时器发生溢出等),NVIC将该中断标志为挂起状态。

  • 若该中断已被使能,且满足优先级条件,CPU即暂停当前任务,转而执行对应中断服务程序
  • 若该中断未被使能或者更高优先级的中断正在执行,则保持挂起状态,直到符合执行条件后响应中断。

可以把挂起理解为中断输入在内核控制层面的状态标志暂存。

ISPR和ICPR即为NVIC层面对应的的中断挂起控制寄存器,其作用方式和前面的使能寄存器相同,置"1"挂起/清除挂起,置"0"无效。值得注意的是,在中断执行后对应挂起状态不会自动清除,故若执行中断过程中没有对应步骤清除挂起,会导致中断服务程序被反复执行。

下面列出这两组寄存器对应的内存分配,由于只用到前两个寄存器,ISPR [2]~ISPR [7] 和 ICPR [2]~ICPR [7] 为预留状态,无实际功能,故未直接列出:

寄存器名称起始地址相对于 NVIC 基地址的偏移量管理的中断范围功能描述
ISPR[0]0xE000E1000x100中断 0 ~ 31设置中断 0~31 的挂起状态
ISPR[1]0xE000E1040x104中断 32 ~ 59设置中断 32~59 的挂起状态(高4位预留)
ICPR[0]0xE000E1800x180中断 0 ~ 31清除中断 0~31 的挂起状态
ICPR[1]0xE000E1840x184中断 32 ~ 59清除中断 32~59 的挂起状态(高4位预留)

对于内核中断,部分支持手动设置和清除挂起状态,同样通过SCB的特殊功能寄存器实现:

内核异常名称异常编号挂起控制寄存器操作方式
PendSV(可悬起系统调用)14SCB->ICSR(bit28)挂起:SCB->ICSR= SCB_ICSR_PENDSVSET_Msk
解挂:SCB->ICSR=SCB_ICSR_PENDSVCLR_Msk
SysTick(系统滴答定时器)15SysTick->CTRL(bit16)挂起:由定时器计数溢出自动触发,或通过SysTick->VAL强制清零触发
解挂:进入中断服务程序后自动清除(硬件行为)
SVC(系统服务调用)11无直接挂起位SVC指令直接触发,无需手动挂起,执行后自动清除
中断活动状态寄存器(IABRx)

IABR寄存器主要用于查询中断的当前执行状态,是只读寄存器,中断进入时对应位自动置位,中断退出时对应位清零。

对应内存映射为:

寄存器名称地址偏移(相对于 NVIC 基地址)完整内存地址管理的中断编号范围说明(STM32F103 实际使用情况)
IABR[0]0x2000xE000E3000 ~ 31覆盖 STM32F103 的内核中断和大部分基础外设中断
IABR[1]0x2040xE000E30432 ~ 63包含部分高级外设中断(如 USART1 等)
IABR[2]0x2080xE000E30864 ~ 95STM32F103 未使用(超出其最大中断数)
IABR[3]0x20C0xE000E30C96 ~ 127STM32F103 未使用
IABR[4]0x2100xE000E310128 ~ 159STM32F103 未使用
IABR[5]0x2140xE000E314160 ~ 191STM32F103 未使用
IABR[6]0x2180xE000E318192 ~ 223STM32F103 未使用
IABR[7]0x21C0xE000E31C224 ~ 255STM32F103 未使用
中断优先级寄存器(IPRx)

IPRx决定了外部输入中断的优先级顺序,通过20个32位寄存器(IPR [0]~IPR [19])管理这些中断。每个 IPR 寄存器为 32 位,分为 4 个独立的 8 位字段(bit [7:0]、bit [15:8]、bit [23:16]、bit [31:24]),每个 8 位字段对应一个中断的优先级配置。具体对应关系如下表:

IPR 寄存器管理的中断号8 位字段与中断的对应关系(32 位寄存器内)
IPR[0]0~3bit [7:0] → 中断 0;bit [15:8] → 中断 1;bit [23:16] → 中断 2;bit [31:24] → 中断 3
IPR[1]4~7bit [7:0] → 中断 4;bit [15:8] → 中断 5;bit [23:16] → 中断 6;bit [31:24] → 中断 7
…(以此类推,每寄存器递增 4 个中断号)
IPR[n]4n ~ 4n+3bit [7:0] → 中断 4n;bit [15:8] → 中断 4n+1;bit [23:16] → 中断 4n+2;bit [31:24] → 中断 4n+3

其中,根据Cortex-M3内核规定,IPR 的 8 位字段中高 4 位有效、低 4 位保留。即STM32F1的中断优先级通过4位二进制数表示,共可设置24=162^4 = 1624=16个优先级(0x0~0xf,数值越小,优先级越高)。

前面提到抢占优先级(优先级组)和响应优先级(子优先级)通过SCB->AIRCR寄存器的PRIGROUP字段配置,对应在IPR中分配相应位数给两者,具体关系如下表:

优先级分组(PRIGROUP)抢占优先级位数子优先级位数抢占优先级等级数子优先级等级数
0(111)041(仅 0 级)16(0~15)
1(110)132(0~1)8(0~7)
2(101)224(0~3)4(0~3)
3(100)318(0~7)2(0~1)
4(011)4016(0~15)1(仅 0 级)

其中抢占优先级在高位,响应优先级在低位。

内核中断优先级通过SHPRx(System Handler Priority Registers,系统异常优先级寄存器)配置。该寄存器同样被分为4个8位字段,每个字段高4位有效,低4位保留。SHPR与IPR共用同一优先级数值空间。其中部分优先级固定不可配置。具体对应关系如下:

寄存器地址对应异常
SHPR10xE000ED18MemManage、BusFault、UsageFault
SHPR20xE000ED1CSVCall
SHPR30xE000ED20DebugMonitor、PendSV、SysTick

其他3个内核中断属于不可配置的负优先级中断:

中断类型异常编号优先级特性优先级数值(相对值)配置方式 / 说明
Reset-15固定最高优先级最高(不可抢占)不可配置,由硬件触发,优先级高于所有其他中断。
NMI-2固定高优先级次高(不可屏蔽)不可配置,非屏蔽中断,仅可被复位中断打断。
HardFault-1固定高优先级高于所有可配置中断不可配置,处理严重错误(如内存访问违例),优先级固定为 - 1。
软件触发中断寄存器(STIR)

STIR(Software Triggered Interrupt Register,软件触发中断寄存器)允许通过软件方式模拟硬件触发中断,适用于中断测试、软件仿真硬件事件等,其内存地址映射为0xE000EF00,仅低8位有效。通过向低8位写入对应中断位号实现相应中断请求。

应用中断和复位控制寄存器(AIRCR)

AIRCR(Application Interrupt and Reset Control Register,应用中断和复位控制寄存器)主要负责配置中断优先级分组、触发系统复位以及管理调试相关的中断行为,它属于 Cortex-M3 内核的系统控制块(SCB) 寄存器组,映射内存地址为0xE000ED0C,且仅支持32位写操作,前面所提及的PRIGROUP就包括在该寄存器中。AIRCR功能段定义如下表:

位段名称 / 功能描述
bit31~bit16VECTKEY(向量键):写入时必须设置为0x05FA(密钥),否则写操作无效(用于防止误操作)。读操作时返回0xFA05(固定值)。
bit15ENDIANNESS:数据字节序标识(仅可读)。0表示小端模式(STM32F103 默认,数据低字节存于低地址);1表示大端模式(未使用,芯片默认小端)。
bit14~bit13保留位:写入无效,读出值为0
bit12~bit10PRIGROUP(优先级分组):配置中断优先级的分组方式(决定抢占优先级和子优先级的位数分配)。具体见下文。
bit9~bit8SYSRESETREQ(系统复位请求)1表示触发软件复位(复位整个系统,包括内核和外设);写1后由硬件自动清0
bit7~bit6VECTCLRACTIVE(向量清除激活):仅用于调试,1表示清除所有激活的中断(需配合调试工具使用,用户程序一般不操作)。
bit5STKALIGN(栈对齐):配置异常返回时的栈对齐方式。0表示不对齐(按当前栈指针);1表示 8 字节对齐(Cortex-M3 默认,推荐使用)。
bit4~bit0保留位:写入无效,读出值为0

中断处理过程

传入NVIC的中断可分为3类:

  • 内核中断
  • 片上外设中断
  • 外部中断

其中,内核中断中断源在内核部,输入到NVIC中特殊通道,通过NVIC的SHPR判断优先级顺序,最终决定是否执行中断;外部中断通过EXTI(外部中断事件控制器)输入到NVIC对应IRQn通道,通过ISER/ICER判断使能状态以及IPR判断优先级继而决定是否执行或挂起中断;片上外设输入到NVIC对应的IRQn通道,后续处理和外部中断输入一致,其框图如下:
中断处理

posted @ 2025-08-15 17:26  ONGround  阅读(121)  评论(0)    收藏  举报  来源