stm32之NVIC_PriorityGroup_3

NVIC_PriorityGroup_3 的优先级拆分规则,以及用它配置 16 个中断的具体组合方案,我来详细拆解并给出可直接使用的配置示例。

  1. NVIC_PriorityGroup_3 的核心定义
    NVIC_PriorityGroup_3 是偏向 "多抢占级别、少响应级别" 的分组,对 STM32 NVIC 的 4 位优先级寄存器拆分规则为:
    抢占优先级:3 位 → 共 8 个级别(0~7,0 为最高优先级)
    响应优先级:1 位 → 共 2 个级别(0、1,0 为更高优先级)
    总组合数:8 × 2 = 16 种 → 刚好能覆盖 16 个中断的优先级配置需求
    核心特点:支持 8 级中断嵌套(抢占能力强),同抢占级内仅能区分 2 级响应优先级,适合需要精细划分抢占层级、但同层级排序需求简单的场景(如工控、高实时性系统)。
  2. 能否实现 16 个中断?
    完全可以!该分组下的 16 种(抢占 + 响应)组合刚好能为 16 个中断分配唯一的优先级,且 8 级抢占能满足复杂的中断嵌套需求。
  3. 16 个中断的具体组合配置示例
    假设你有 16 个典型中断(EXTI0EXTI7、USART1USART3、TIM1~TIM4、SPI1、SPI2),以下是完整的配置代码,按 "抢占优先级从高到低、同抢占级内响应优先级 0 优先于 1" 分配:
    c
    运行
    #include "stm32f10x.h"

void NVIC_Config_16IRQ_Group3(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

复制代码
// 第一步:配置优先级分组为Group_3(3位抢占 + 1位响应)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

// ==================== 抢占优先级0(最高抢占级)====================
// 中断1:EXTI0(抢占0,响应0)→ 整体最高优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 响应优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断2:EXTI1(抢占0,响应1)→ 抢占0级中最低
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级1 ====================
// 中断3:EXTI2(抢占1,响应0)
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断4:EXTI3(抢占1,响应1)
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级2 ====================
// 中断5:EXTI4(抢占2,响应0)
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断6:EXTI5(抢占2,响应1)
NVIC_InitStructure.NVIC_IRQChannel = EXTI5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级3 ====================
// 中断7:EXTI6(抢占3,响应0)
NVIC_InitStructure.NVIC_IRQChannel = EXTI6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断8:EXTI7(抢占3,响应1)
NVIC_InitStructure.NVIC_IRQChannel = EXTI7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级4 ====================
// 中断9:USART1(抢占4,响应0)
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断10:USART2(抢占4,响应1)
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级5 ====================
// 中断11:USART3(抢占5,响应0)
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断12:TIM1(抢占5,响应1)
NVIC_InitStructure.NVIC_IRQChannel = TIM1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级6 ====================
// 中断13:TIM2(抢占6,响应0)
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断14:TIM3(抢占6,响应1)
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// ==================== 抢占优先级7(最低抢占级)====================
// 中断15:SPI1(抢占7,响应0)
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// 中断16:SPI2(抢占7,响应1)→ 整体最低优先级
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

  1. 关键优先级规则(Group_3 下)

抢占优先级是核心:

抢占 0 的中断(如 EXTI0)可打断抢占 1~7 的所有中断;

抢占 1 的中断可打断抢占 2~7 的中断,但无法打断抢占 0 的中断;

8 级抢占能实现复杂的中断嵌套,满足高实时性需求。

响应优先级仅做补充:

同抢占级内(如都是抢占 0),响应 0 的中断(EXTI0)比响应 1 的中断(EXTI1)先执行,但无法相互抢占;

响应优先级仅支持 0/1 两个值,超出范围会被 NVIC 截断(如设 2 会被当作 0 处理)。

  1. 注意事项

抢占优先级范围:Group_3 下仅能设 0~7,设 8 及以上会被截断为 0;

响应优先级范围:仅能设 0 或 1,设其他值无效;

分组配置唯一性:NVIC_PriorityGroupConfig 必须在所有中断配置前执行,且整个程序仅需调用一次。

总结

NVIC_PriorityGroup_3 是 3 位抢占优先级 + 1 位响应优先级,共 8 个抢占级别、2 个响应级别,总 16 种组合;

完全支持 16 个中断的配置,只需为每个中断分配唯一的(抢占 0~7 + 响应 0/1)组合;

核心特点:抢占层级多(8 级)、嵌套能力强,同抢占级仅能区分 2 级响应优先级,适合高实时性、需要精细嵌套的场景。

相关推荐
学嵌入式的小杨同学6 小时前
STM32 进阶封神之路(二十五):ESP8266 深度解析 —— 从 WiFi 通信原理到 AT 指令开发(底层逻辑 + 实战基础)
c++·vscode·stm32·单片机·嵌入式硬件·mcu·智能硬件
学嵌入式的小杨同学7 小时前
STM32 进阶封神之路(二十六):ESP8266 实战全攻略 ——TCP 通信 + 数据上传 + 远程控制 + 透传模式(库函数 + 代码落地)
stm32·单片机·嵌入式硬件·mcu·硬件架构·硬件工程·智能硬件
Nice__J7 小时前
Mcu架构以及原理——7.寄存器编程与抽象
stm32·单片机·架构
我不是程序猿儿7 小时前
【嵌入式】适合 STM32 初学者BootLoader 入门学习心得
linux·stm32·单片机·嵌入式硬件·学习
Suifqwu8 小时前
stm32进阶-启动文件
stm32·单片机·嵌入式硬件
火龙果里的芝麻9 小时前
STM32 FreeModbus 移植(最详细)
stm32·单片机·嵌入式硬件
Heartache boy10 小时前
野火STM32_HAL库版课程笔记-TIM通用定时器基础中断应用
笔记·stm32·单片机·嵌入式硬件
CODE_RabbitV10 小时前
【保姆级实操版 - STM32 系列笔记】新手入门STM32第一课:CubeMX+Keil MDK实现LED点灯
笔记·stm32·嵌入式硬件
我不吃西红柿k11 小时前
stm32新建项目编译即出现大量报错,如何解决
stm32·单片机·嵌入式硬件
火龙果里的芝麻11 小时前
CANOpen 移植+调试 LINUX(主站)+STM32(从站)
linux·stm32