STM32 中断分组解析 说明,以及优先级

STM32 中断分组与优先级解析

STM32 的中断优先级管理是嵌入式开发中核心知识点之一,其设计兼顾了灵活性和确定性,核心围绕抢占优先级响应优先级(也叫子优先级)展开

一、核心概念
1. 中断优先级的两个维度

STM32 将中断优先级分为两级,目的是解决中断嵌套同优先级中断排队的问题:

  • 抢占优先级(Preemption Priority)

    决定中断能否 "打断" 正在执行的中断(即中断嵌套)。

    • 抢占优先级数值越小,优先级越高;

    • 高抢占优先级的中断可以打断低抢占优先级的中断执行。

  • 响应优先级(Sub Priority)

    仅当多个中断抢占优先级相同时生效,决定中断的响应顺序(排队执行)。

    • 响应优先级数值越小,排队越靠前;

    • 同抢占优先级的中断,响应优先级高的先执行,但无法嵌套(因为抢占优先级相同)。

2. 中断分组(NVIC_PriorityGroup)

STM32 的中断优先级寄存器是 4 位宽(共 16 级优先级),通过 "中断分组" 将这 4 位拆分给 "抢占优先级" 和 "响应优先级",共分 5 个分组(Group0~Group4),具体拆分规则如下:

|---------|---------|---------|---------|---------|
| 中断分组 | 抢占优先级位数 | 响应优先级位数 | 抢占优先级范围 | 响应优先级范围 |
| Group 0 | 0 位 | 4 位 | 仅 0 级 | 0~15 |
| Group 1 | 1 位 | 3 位 | 0~1 | 0~7 |
| Group 2 | 2 位 | 2 位 | 0~3 | 0~3 |
| Group 3 | 3 位 | 1 位 | 0~7 | 0~1 |
| Group 4 | 4 位 | 0 位 | 0~15 | 仅 0 级 |

关键规则:

  1. 整个系统只能选择一个中断分组(全局配置),所有中断都遵循该分组规则;

  2. 4 位总位数固定,抢占优先级位数越多,响应优先级位数越少,反之亦然;

  3. 数值越小,优先级越高(无论是抢占还是响应)

二、优先级判断规则

当多个中断同时触发时,STM32 按以下顺序判断执行顺序:

  1. 先比较抢占优先级:数值小的先执行,且可嵌套;

  2. 若抢占优先级相同,比较响应优先级:数值小的先执行;

  3. 若响应优先级也相同,比较中断向量表中的硬件编号:编号越小,优先级越高(硬件固定,无法修改)。


三、代码实现(以 STM32F103 为例)
1. 配置中断分组(全局唯一)
复制代码
#include "stm32f10x.h"
// 配置中断分组为 Group2(2 位抢占 + 2 位响应)
void NVIC_ConfigGroup(void)
{
    // 初始化 NVIC 结构体
    NVIC_InitTypeDef NVIC_InitStructure;

    // 配置中断分组:Group2
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 示例:配置外部中断 EXTI0 的优先级
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;          // 选择 EXTI0 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级:1(0~3)
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 响应优先级:0(0~3)
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能该中断通道
    NVIC_Init(&NVIC_InitStructure);

    // 示例:配置定时器 TIM2 的优先级
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;           // 选择 TIM2 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级:1(与 EXTI0 相同)
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        // 响应优先级:1(比 EXTI0 低)
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
2. 优先级效果说明

以上配置中:

  • EXTI0 和 TIM2 的抢占优先级都是 1,因此无法互相嵌套

  • 若 EXTI0 和 TIM2 同时触发,EXTI0 的响应优先级 0 高于 TIM2 的 1,因此先执行 EXTI0 中断服务函数;

  • 若将 TIM2 的抢占优先级改为 0,则 TIM2 可以打断 EXTI0 的执行(嵌套)。

四、实际开发注意事项
  1. 分组选择原则

    • 若需要频繁使用中断嵌套,选择抢占优先级位数多的分组(如 Group3/4);

    • 若很少嵌套,仅需排队执行,选择响应优先级位数多的分组(如 Group1/0);

    • 常规场景推荐 Group2(2+2),兼顾嵌套和排队需求。

  2. 优先级数值误区

    • 不要认为 "数值大优先级高",STM32 是数值越小优先级越高

    • 分组配置后,抢占 / 响应优先级的取值范围会固定(如 Group2 抢占只能取 0~3),超出范围会导致配置失效。

  3. 系统异常优先级

    • 复位、NMI(不可屏蔽中断)、HardFault 等系统异常的优先级高于所有外部中断,且无法通过 NVIC 修改;

    • SVC、PendSV、SysTick 等内核中断的优先级可通过 SCB->SHPR 寄存器配置。

总结

  1. STM32 中断优先级分为抢占优先级 (决定嵌套)和响应优先级(决定同抢占优先级的排队),由 4 位寄存器拆分而来;

  2. 中断分组(Group0~4)全局唯一,决定 4 位寄存器在抢占 / 响应优先级的分配比例;

  3. 优先级判断顺序:抢占优先级 > 响应优先级 > 硬件中断编号,数值越小优先级越高。

关键点回顾

  • 抢占优先级:决定中断嵌套,高优先级(数值小)可打断低优先级;

  • 响应优先级:仅同抢占优先级时生效,决定排队顺序;

  • 中断分组:全局配置,4 位寄存器的拆分规则决定了抢占 / 响应优先级的取值范围。

相关推荐
不脱发的程序猿2 小时前
嵌入式Linux:阻塞式I/O与非阻塞式I/O
linux·服务器·单片机·嵌入式硬件·嵌入式
炸膛坦客2 小时前
单片机/C语言八股:(三)C 语言编译器的优化功能,包括 keil(仅作了解)
c语言·单片机·嵌入式硬件
csg11072 小时前
PIC单片机高阶实战(一):PIC32MX振荡器与定时器
单片机·嵌入式硬件·物联网
逐步前行2 小时前
STM32_GPIO_标准库操作
stm32·单片机·嵌入式硬件
LCG元2 小时前
USB设备开发:STM32F105实现USB HID设备,虚拟串口通信实战
stm32·单片机·嵌入式硬件
李boyang2 小时前
基于 STM32F103 + ESP8266 实现 DHT11 温湿度数据上传华为云 IoT 平台
stm32·物联网·华为云·esp8266
香水5只用六神3 小时前
【TIM】基本定时器定时实验(2)
c语言·开发语言·stm32·单片机·嵌入式硬件·mcu·学习
阿拉斯攀登3 小时前
【瑞芯微 RK 系列 + 安卓驱动全栈教程】博客系列
嵌入式硬件·安卓·瑞芯微·rk3576·嵌入式安卓·安卓驱动
时空自由民.4 小时前
IMU零漂温漂校准(chatgpt版本)
单片机