【STM32】中断控制(内核篇)
STM32:
- 68个可屏蔽中断通道以及16个Cortex™-M3内核中断共84个中断;
- 16个可编程的优先等级(4位中断优先级控制);
STM32F103系列:
- 60个可屏蔽中断通道以及10个内核中断共70个中断;
- 16个可编程的优先等级(4位中断优先级控制);
简单来说,一个中断系统的几个重要组成包括:
- 中断源
- 中断向量/中断向量表
- 中断服务程序
中断处理过程大概可以描述为:
- 中断请求
- 中断判优
- 中断响应
- 执行中断服务程序
- 返回原程序进度
下面将从中断组成和中断处理两个方向分别介绍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 | |
| 0 | 7 | 可设置 | WWDG | 窗口定时器中断 | 0x0000_0040 |
| 1 | 8 | 可设置 | PVD | 连到 EXTI 的电源电压检测 (PVD) 中断 | 0x0000_0044 |
| 2 | 9 | 可设置 | TAMPER | 侵入检测中断 | 0x0000_0048 |
| 3 | 10 | 可设置 | RTC | 实时时钟 (RTC) 全局中断 | 0x0000_004C |
| 4 | 11 | 可设置 | FLASH | 闪存全局中断 | 0x0000_0050 |
| 5 | 12 | 可设置 | RCC | 复位和时钟控制 (RCC) 中断 | 0x0000_0054 |
| 6 | 13 | 可设置 | EXTI0 | EXTI 线 0 中断 | 0x0000_0058 |
| 7 | 14 | 可设置 | EXTI1 | EXTI 线 1 中断 | 0x0000_005C |
| 8 | 15 | 可设置 | EXTI2 | EXTI 线 2 中断 | 0x0000_0060 |
| 9 | 16 | 可设置 | EXTI3 | EXTI 线 3 中断 | 0x0000_0064 |
| 10 | 17 | 可设置 | EXTI4 | EXTI 线 4 中断 | 0x0000_0068 |
| 11 | 18 | 可设置 | DMA1 通道 1 | DMA1 通道 1 全局中断 | 0x0000_006C |
| 12 | 19 | 可设置 | DMA1 通道 2 | DMA1 通道 2 全局中断 | 0x0000_0070 |
| 13 | 20 | 可设置 | DMA1 通道 3 | DMA1 通道 3 全局中断 | 0x0000_0074 |
| 14 | 21 | 可设置 | DMA1 通道 4 | DMA1 通道 4 全局中断 | 0x0000_0078 |
| 15 | 22 | 可设置 | DMA1 通道 5 | DMA1 通道 5 全局中断 | 0x0000_007C |
| 16 | 23 | 可设置 | DMA1 通道 6 | DMA1 通道 6 全局中断 | 0x0000_0080 |
| 17 | 24 | 可设置 | DMA1 通道 7 | DMA1 通道 7 全局中断 | 0x0000_0084 |
| 18 | 25 | 可设置 | ADC1_2 | ADC1 和 ADC2 的全局中断 | 0x0000_0088 |
| 19 | 26 | 可设置 | USB_HP_CAN_TX | USB 高优先级或 CAN 发送中断 | 0x0000_008C |
| 20 | 27 | 可设置 | USB_LP_CAN_RX0 | USB 低优先级或 CAN 接收 0 中断 | 0x0000_0090 |
| 21 | 28 | 可设置 | CAN_RX1 | CAN 接收 1 中断 | 0x0000_0094 |
| 22 | 29 | 可设置 | CAN_SCE | CAN SCE 中断 | 0x0000_0098 |
| 23 | 30 | 可设置 | EXTI9_5 | EXTI 线 [9:5] 中断 | 0x0000_009C |
| 24 | 31 | 可设置 | TIM1_BRK | TIM1 刹车中断 | 0x0000_00A0 |
| 25 | 32 | 可设置 | TIM1_UP | TIM1 更新中断 | 0x0000_00A4 |
| 26 | 33 | 可设置 | TIM1_TRG_COM | TIM1 触发和通信中断 | 0x0000_00A8 |
| 27 | 34 | 可设置 | TIM1_CC | TIM1 捕获比较中断 | 0x0000_00AC |
| 28 | 35 | 可设置 | TIM2 | TIM2 全局中断 | 0x0000_00B0 |
| 29 | 36 | 可设置 | TIM3 | TIM3 全局中断 | 0x0000_00B4 |
| 30 | 37 | 可设置 | TIM4 | TIM4 全局中断 | 0x0000_00B8 |
| 31 | 38 | 可设置 | I2C1_EV | I²C1 事件中断 | 0x0000_00BC |
| 32 | 39 | 可设置 | I2C1_ER | I²C1 错误中断 | 0x0000_00C0 |
| 33 | 40 | 可设置 | I2C2_EV | I²C2 事件中断 | 0x0000_00C4 |
| 34 | 41 | 可设置 | I2C2_ER | I²C2 错误中断 | 0x0000_00C8 |
| 35 | 42 | 可设置 | SPI1 | SPI1 全局中断 | 0x0000_00CC |
| 36 | 43 | 可设置 | SPI2 | SPI2 全局中断 | 0x0000_00D0 |
| 37 | 44 | 可设置 | USART1 | USART1 全局中断 | 0x0000_00D4 |
| 38 | 45 | 可设置 | USART2 | USART2 全局中断 | 0x0000_00D8 |
| 39 | 46 | 可设置 | USART3 | USART3 全局中断 | 0x0000_00DC |
| 40 | 47 | 可设置 | EXTI15_10 | EXTI 线 [15:10] 中断 | 0x0000_00E0 |
| 41 | 48 | 可设置 | RTCAlarm | 连到 EXTI 的 RTC 闹钟中断 | 0x0000_00E4 |
| 42 | 49 | 可设置 | USB 唤醒 | 连到 EXTI 的 USB 待机唤醒中断 | 0x0000_00E8 |
| 43 | 50 | 可设置 | TIM8_BRK | TIM8 刹车中断 | 0x0000_00EC |
| 44 | 51 | 可设置 | TIM8_UP | TIM8 更新中断 | 0x0000_00F0 |
| 45 | 52 | 可设置 | TIM8_TRG_COM | TIM8 触发和通信中断 | 0x0000_00F4 |
| 46 | 53 | 可设置 | TIM8_CC | TIM8 捕获比较中断 | 0x0000_00F8 |
| 47 | 54 | 可设置 | ADC3 | ADC3 全局中断 | 0x0000_00FC |
| 48 | 55 | 可设置 | FSMC | FSMC 全局中断 | 0x0000_0100 |
| 49 | 56 | 可设置 | SDIO | SDIO 全局中断 | 0x0000_0104 |
| 50 | 57 | 可设置 | TIM5 | TIM5 全局中断 | 0x0000_0108 |
| 51 | 58 | 可设置 | SPI3 | SPI3 全局中断 | 0x0000_010C |
| 52 | 59 | 可设置 | UART4 | UART4 全局中断 | 0x0000_0110 |
| 53 | 60 | 可设置 | UART5 | UART5 全局中断 | 0x0000_0114 |
| 54 | 61 | 可设置 | TIM6 | TIM6 全局中断 | 0x0000_0118 |
| 55 | 62 | 可设置 | TIM7 | TIM7 全局中断 | 0x0000_011C |
| 56 | 63 | 可设置 | DMA2 通道 1 | DMA2 通道 1 全局中断 | 0x0000_0120 |
| 57 | 64 | 可设置 | DMA2 通道 2 | DMA2 通道 2 全局中断 | 0x0000_0124 |
| 58 | 65 | 可设置 | DMA2 通道 3 | DMA2 通道 3 全局中断 | 0x0000_0128 |
| 59 | 66 | 可设置 | DMA2 通道 4_5 | DMA2 通道 4 和 DMA2 通道 5 全局中断 | 0x0000_012C |
其中,前3个中断为不可屏蔽中断,涉及CPU的正常工作,优先级最高,且均为负值,是固定且不可修改的。前10个中断为内核中断,其中断源均在内核部,且大部分在一般编程过程中少有涉及,唯有系统滴答定时器(Systick)作为一个Cortex-M系列内核芯片共有的定时器常被用于实际开发。
后面60个中断中断源在内核以外,涉及时钟、定时器、DMADMADMA、I2CI^2CI2C等片上其他资源以及外部中断。
中断向量/中断向量表
每个中断都对应有一个入口地址(上表最后一栏),也即中断向量,当对应中断发生响应时,程序跳转到该入口地址。由上表可知,相邻两个入口地址之间只有4个程序字间隔,这通常用以实现向中断服务程序首地址跳转的操作。所有这些入口地址共同组成该单片机的中断向量表,中断向量表被分配在内存中的一块固定位置上,用以告知CPU中断优先级及中断服务程序入口地址等信息。
中断优先级
STM32中断优先级分为抢占优先级和响应优先级。
抢占优先级(优先级组 group priority)
- 当CPU正在运行中断服务函数时,若又一中断事件发生,触发中断请求,则通过对比正在运行的中断与新触发的中断抢占优先级的高低。若新触发中断抢占优先级更高,则停止当前程序,执行新中断的中断服务函数,形成中断嵌套,执行完毕后返回原中断的处理程序;若新触发中断抢占优先级与正在执行的相等或更低,则等待当前中断服务函数执行完毕,再进入新中断的中断处理程序。
- 当有2个或以上中断同时触发或等待被执行时,通过对比其抢占优先级高低,确定执行顺序。
响应优先级(子优先级sub priority)
- 响应优先级不会打断正在运行的中断,即不会引起中断嵌套的发生。该功能更多是对于抢占优先级中第2条的补充,即在2个或以上中断同时触发或等待被执行时,若其抢占优先级相等,则对比响应优先级高低,响应优先级高的先执行。
- 在2个或以上中断同时触发或等待被执行时,若其抢占优先级和响应优先级均相等,则根据上表中默认优先级排序先后执行。
中断处理
NVIC
NVIC作为中断控制的“总管”,全名嵌套向量中断控制器(Nested vectored interrupt controller, NVIC),与CM3内核直接联系,负责管理STM32的所有中断(内核异常、外部中断),是用于中断管理的核心组件。当中断事件送入时,NVIC根据中断优先级及当前CPU状态决定中断的响应。

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] | 0xE000E100 | 0~31 | 0~31 | 每一位对应一个中断,向某一位写 1 时,使能对应中断(0~31);写 0 无效果 |
| ISER[1] | 0xE000E104 | 0~27 | 32~59 | 每一位对应一个中断,向某一位写 1 时,使能对应中断(32~59);写 0 无效果 |
| ISER[1] | 0xE000E104 | 28~31 | 无对应中断 | 未使用(STM32F103 系列最大支持 60 个可屏蔽中断,超出部分无实际意义) |
| ISER[2] | 0xE000E108 | 0~31 | 无对应中断 | 未使用(超出 STM32F103 可屏蔽中断数量范围) |
| ISER[3] | 0xE000E10C | 0~31 | 无对应中断 | 未使用 |
| ISER[4] | 0xE000E110 | 0~31 | 无对应中断 | 未使用 |
| ISER[5] | 0xE000E114 | 0~31 | 无对应中断 | 未使用 |
| ISER[6] | 0xE000E118 | 0~31 | 无对应中断 | 未使用 |
| ISER[7] | 0xE000E11C | 0~31 | 无对应中断 | 未使用 |
| ICER[0] | 0xE000E180 | 0~31 | 0~31 | 每一位对应一个中断,向某一位写 1 时,清除对应中断(0~31)的使能状态;写 0 无效果 |
| ICER[1] | 0xE000E184 | 0~27 | 32~59 | 每一位对应一个中断,向某一位写 1 时,清除对应中断(32~59)的使能状态;写 0 无效果 |
| ICER[1] | 0xE000E184 | 28~31 | 无对应中断 | 未使用(STM32F103 系列最大支持 60 个可屏蔽中断,超出部分无实际意义) |
| ICER[2] | 0xE000E188 | 0~31 | 无对应中断 | 未使用(超出 STM32F103 可屏蔽中断数量范围) |
| ICER[3] | 0xE000E18C | 0~31 | 无对应中断 | 未使用 |
| ICER[4] | 0xE000E190 | 0~31 | 无对应中断 | 未使用 |
| ICER[5] | 0xE000E194 | 0~31 | 无对应中断 | 未使用 |
| ICER[6] | 0xE000E198 | 0~31 | 无对应中断 | 未使用 |
| ICER[7] | 0xE000E19C | 0~31 | 无对应中断 | 未使用 |
这里使能控制都是针对外部中断输入,对于内核中断,正常情况下一般很少配置,大部分通过系统控制块(SCB)的特殊功能寄存器实现。具体配置信息如下表:
| 内核中断(异常) | 编号 | 使能配置方式 | 能否禁用 | 说明 |
|---|---|---|---|---|
| 复位(Reset) | -15 | 硬件触发,无软件使能位 | 不可禁用 | 系统上电 / 复位时自动触发,优先级最高 |
| NMI | -2 | 硬件触发(如外部 NMI 引脚),无软件使能位 | 不可禁用 | 不可屏蔽,不受全局中断开关(PRIMASK)影响 |
| 硬故障(HardFault) | -1 | 无单独使能位,默认始终使能 | 不可禁用 | 响应严重错误(如总线错误、未定义指令),无法通过软件禁用 |
| 内存管理故障(MemManage) | 4 | 通过SCB->SHCSR的MEMFAULTENA位使能 | 可配置 | 响应存储器访问错误(如访问未授权区域) |
| 总线故障(BusFault) | 5 | 通过SCB->SHCSR的BUSFAULTENA位使能 | 可配置 | 响应总线错误(如外设访问错误、预取指错误) |
| 用法故障(UsageFault) | 6 | 通过SCB->SHCSR的USGFAULTENA位使能 | 可配置 | 响应指令用法错误(如未对齐访问、未定义指令) |
| SVC(系统服务调用) | 11 | 无使能位,由SVC指令直接触发 | 无需使能 | 用于用户态到内核态的系统调用,指令执行即触发 |
| 调试监控(DebugMonitor) | 12 | 由调试器配置(如DBGMCU寄存器),内核层面无使能位 | 可配置 | 调试时触发(如断点、单步执行),通常由调试工具控制 |
| PendSV(可挂起系统调用) | 14 | 无使能位,通过SCB->ICSR的PENDSVSET位置位触发 | 无需使能 | 用于低优先级任务切换,触发后等待当前高优先级任务完成后执行 |
| SysTick(系统滴答定时器) | 15 | 通过SysTick->CTRL的TICKINT位使能 | 可配置 | 系统定时器中断,用于操作系统时钟或定时任务 |
中断挂起寄存器(ISPRx)与中断清除挂起寄存器(ICPRx)
首先了解一下什么是挂起:当一个中断触发(如外部引脚电平发生变化、定时器发生溢出等),NVIC将该中断标志为挂起状态。
- 若该中断已被使能,且满足优先级条件,CPU即暂停当前任务,转而执行对应中断服务程序
- 若该中断未被使能或者更高优先级的中断正在执行,则保持挂起状态,直到符合执行条件后响应中断。
可以把挂起理解为中断输入在内核控制层面的状态标志暂存。
ISPR和ICPR即为NVIC层面对应的的中断挂起控制寄存器,其作用方式和前面的使能寄存器相同,置"1"挂起/清除挂起,置"0"无效。值得注意的是,在中断执行后对应挂起状态不会自动清除,故若执行中断过程中没有对应步骤清除挂起,会导致中断服务程序被反复执行。
下面列出这两组寄存器对应的内存分配,由于只用到前两个寄存器,ISPR [2]~ISPR [7] 和 ICPR [2]~ICPR [7] 为预留状态,无实际功能,故未直接列出:
| 寄存器名称 | 起始地址 | 相对于 NVIC 基地址的偏移量 | 管理的中断范围 | 功能描述 |
|---|---|---|---|---|
| ISPR[0] | 0xE000E100 | 0x100 | 中断 0 ~ 31 | 设置中断 0~31 的挂起状态 |
| ISPR[1] | 0xE000E104 | 0x104 | 中断 32 ~ 59 | 设置中断 32~59 的挂起状态(高4位预留) |
| ICPR[0] | 0xE000E180 | 0x180 | 中断 0 ~ 31 | 清除中断 0~31 的挂起状态 |
| ICPR[1] | 0xE000E184 | 0x184 | 中断 32 ~ 59 | 清除中断 32~59 的挂起状态(高4位预留) |
对于内核中断,部分支持手动设置和清除挂起状态,同样通过SCB的特殊功能寄存器实现:
| 内核异常名称 | 异常编号 | 挂起控制寄存器 | 操作方式 |
|---|---|---|---|
| PendSV(可悬起系统调用) | 14 | SCB->ICSR(bit28) | 挂起:SCB->ICSR= SCB_ICSR_PENDSVSET_Msk解挂: SCB->ICSR=SCB_ICSR_PENDSVCLR_Msk |
| SysTick(系统滴答定时器) | 15 | SysTick->CTRL(bit16) | 挂起:由定时器计数溢出自动触发,或通过SysTick->VAL强制清零触发解挂:进入中断服务程序后自动清除(硬件行为) |
| SVC(系统服务调用) | 11 | 无直接挂起位 | 由SVC指令直接触发,无需手动挂起,执行后自动清除 |
中断活动状态寄存器(IABRx)
IABR寄存器主要用于查询中断的当前执行状态,是只读寄存器,中断进入时对应位自动置位,中断退出时对应位清零。
对应内存映射为:
| 寄存器名称 | 地址偏移(相对于 NVIC 基地址) | 完整内存地址 | 管理的中断编号范围 | 说明(STM32F103 实际使用情况) |
|---|---|---|---|---|
| IABR[0] | 0x200 | 0xE000E300 | 0 ~ 31 | 覆盖 STM32F103 的内核中断和大部分基础外设中断 |
| IABR[1] | 0x204 | 0xE000E304 | 32 ~ 63 | 包含部分高级外设中断(如 USART1 等) |
| IABR[2] | 0x208 | 0xE000E308 | 64 ~ 95 | STM32F103 未使用(超出其最大中断数) |
| IABR[3] | 0x20C | 0xE000E30C | 96 ~ 127 | STM32F103 未使用 |
| IABR[4] | 0x210 | 0xE000E310 | 128 ~ 159 | STM32F103 未使用 |
| IABR[5] | 0x214 | 0xE000E314 | 160 ~ 191 | STM32F103 未使用 |
| IABR[6] | 0x218 | 0xE000E318 | 192 ~ 223 | STM32F103 未使用 |
| IABR[7] | 0x21C | 0xE000E31C | 224 ~ 255 | STM32F103 未使用 |
中断优先级寄存器(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~3 | bit [7:0] → 中断 0;bit [15:8] → 中断 1;bit [23:16] → 中断 2;bit [31:24] → 中断 3 |
| IPR[1] | 4~7 | bit [7:0] → 中断 4;bit [15:8] → 中断 5;bit [23:16] → 中断 6;bit [31:24] → 中断 7 |
| … | … | …(以此类推,每寄存器递增 4 个中断号) |
| IPR[n] | 4n ~ 4n+3 | bit [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) | 0 | 4 | 1(仅 0 级) | 16(0~15) |
| 1(110) | 1 | 3 | 2(0~1) | 8(0~7) |
| 2(101) | 2 | 2 | 4(0~3) | 4(0~3) |
| 3(100) | 3 | 1 | 8(0~7) | 2(0~1) |
| 4(011) | 4 | 0 | 16(0~15) | 1(仅 0 级) |
其中抢占优先级在高位,响应优先级在低位。
内核中断优先级通过SHPRx(System Handler Priority Registers,系统异常优先级寄存器)配置。该寄存器同样被分为4个8位字段,每个字段高4位有效,低4位保留。SHPR与IPR共用同一优先级数值空间。其中部分优先级固定不可配置。具体对应关系如下:
| 寄存器 | 地址 | 对应异常 |
|---|---|---|
| SHPR1 | 0xE000ED18 | MemManage、BusFault、UsageFault |
| SHPR2 | 0xE000ED1C | SVCall |
| SHPR3 | 0xE000ED20 | DebugMonitor、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~bit16 | VECTKEY(向量键):写入时必须设置为0x05FA(密钥),否则写操作无效(用于防止误操作)。读操作时返回0xFA05(固定值)。 |
| bit15 | ENDIANNESS:数据字节序标识(仅可读)。0表示小端模式(STM32F103 默认,数据低字节存于低地址);1表示大端模式(未使用,芯片默认小端)。 |
| bit14~bit13 | 保留位:写入无效,读出值为0。 |
| bit12~bit10 | PRIGROUP(优先级分组):配置中断优先级的分组方式(决定抢占优先级和子优先级的位数分配)。具体见下文。 |
| bit9~bit8 | SYSRESETREQ(系统复位请求):1表示触发软件复位(复位整个系统,包括内核和外设);写1后由硬件自动清0。 |
| bit7~bit6 | VECTCLRACTIVE(向量清除激活):仅用于调试,1表示清除所有激活的中断(需配合调试工具使用,用户程序一般不操作)。 |
| bit5 | STKALIGN(栈对齐):配置异常返回时的栈对齐方式。0表示不对齐(按当前栈指针);1表示 8 字节对齐(Cortex-M3 默认,推荐使用)。 |
| bit4~bit0 | 保留位:写入无效,读出值为0。 |
中断处理过程
传入NVIC的中断可分为3类:
- 内核中断
- 片上外设中断
- 外部中断
其中,内核中断中断源在内核部,输入到NVIC中特殊通道,通过NVIC的SHPR判断优先级顺序,最终决定是否执行中断;外部中断通过EXTI(外部中断事件控制器)输入到NVIC对应IRQn通道,通过ISER/ICER判断使能状态以及IPR判断优先级继而决定是否执行或挂起中断;片上外设输入到NVIC对应的IRQn通道,后续处理和外部中断输入一致,其框图如下:


浙公网安备 33010602011771号