【STM32】中断优先级管理 NVIC

发布于:2025-06-27 ⋅ 阅读:(16) ⋅ 点赞:(0)

这篇文章是对 Cortex-M3 内核中断系统 和 STM32F1 系列 NVIC(嵌套向量中断控制器) 的解析说明。我将从结构清晰、层次分明的角度,对 NVIC 中断优先级分组的概念和 STM32F103 的实际情况做一个系统性的总结与叙述。

参考资料:

STM32F1xx官方资料:《STM32中文参考手册V10》---- 第9章 中断和事件
附图:
在这里插入图片描述

为什么一定需要中断?

中断的本质是打破“顺序执行”的限制,使 CPU 能在关键事件发生时立即响应,从而实现多任务、高实时性和高效率运行。

如果没有中断会发生什么?

假设没有中断,CPU 想要获取外设状态(比如按键、串口、传感器数据),怎么办?

那我们只能使用轮询(Polling):

while (1) {
   
    if (UART_GetFlag() == 1) {
   
        // 接收到数据
    }
}
使用这种方式的缺点:
CPU效率低	一直忙等,浪费资源
实时性差		响应时间取决于轮询频率
多任务困难	轮询一个设备时,其他任务无法执行
数据易丢失	如果轮询间隔太长,可能错过事件

而中断则具备解决这些问题的优势:
高实时性		外设事件立即响应
高效率		CPU 空闲时间可执行主任务
多任务协作	支持 RTOS、任务调度
异步处理		外设与主程序解耦
可靠性提升	不易丢数据、不依赖轮询频率

引入中断的优势: 中断机制允许 CPU “只在需要时被打断”,避免无效等待。

中断触发后:

  1. CPU 自动跳转到中断服务函数(ISR)
  2. ISR 执行完毕后自动返回原来任务
  3. 响应迅速,处理高效

几乎所有操作皆离不开中断:

按键响应			用户按键瞬间触发		EXTI 外部中断
串口通信			接收到数据立即处理		USART 中断
定时任务			每秒触发一次事件		TIM 定时器中断
CAN 总线			收到帧立即解析		CAN 中断
操作系统调度		多任务切换			SysTick 定时器中断
没有中断 有中断
一切顺序执行 支持事件驱动
必须轮询外设 被动等待变主动响应
单任务运行 支持多任务调度
类比 你每分钟看一次手机有没有来电(轮询) 手机响了你立刻接听(中断)
效率 浪费精力,不及时 高效、及时响应

中断机制是从串行思维 → 并发思维的转变,是现代计算系统的基石。

中断是嵌入式系统中不可或缺的机制,它让 CPU 不再“苦等”,而是“即来即办”,极大提升了系统的实时性、效率与响应能力。


一、Cortex-M3 内核支持的中断资源(理论上限)
项目 数量
核心中断(系统异常) 16 个(含 HardFault、SysTick、PendSV 等)
外部中断(可屏蔽) 最多 240 个
可编程中断优先级级别 256(8位)

这表示 Cortex-M3 可以 支持 256 级中断优先级(理论),但 MCU 厂商会根据芯片实际资源进行裁剪。

二、STM32F103 实际中断资源(裁剪后)
项目 STM32F103xx STM32F107xx
内核中断 16 个 16 个
外部中断(可屏蔽) 60 个 68 个
可用中断优先级位数 4 位(即 16 级) 同上
总中断源数 16(系统) + 60(外部) = 76 84

STM32 只是用了 Cortex-M3 的一部分功能,比如只用了 4位中断优先级 而不是 8 位。

NVIC 优先级的两个概念

那么有几十个中断,怎么管理这么多的中断呢?于是,我们需要对NVIC中断优先级分组。

中断管理方法:首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。

分组配置是在寄存器 SCB->AIRCR 中配置:
在这里插入图片描述

综上↓:

CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个)
NVIC 中断优先级的两个维度:抢占优先级 & 响应优先级
  1. 抢占优先级(Preemption Priority)
    • 控制中断是否能“打断”其他中断
    • 数字越小,优先级越高
  2. 响应优先级 / 子优先级(Sub Priority)
    • 控制多个中断“同时触发”时谁先执行
    • 不影响中断嵌套

中断优先级比较规则总结:
1.高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
2.抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
3.抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
4.如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
中断优先级分组(Priority Group)

STM32 使用 AIRCR 寄存器 配置优先级分组,分组如下:

分组 抢占优先级位数 子优先级位数 描述
Group 0 0 bit 4 bit 全子优先级,无嵌套
Group 1 1 bit 3 bit 最多两级嵌套
Group 2 2 bit 2 bit 推荐使用,嵌套+排序
Group 3 3 bit 1 bit 高嵌套,低排序
Group 4 4 bit 0 bit 全抢占优先级,满嵌套

在这里插入图片描述
设置方式:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 2位抢占 + 2位子优先级

这是中断优先级分组函数: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
   
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

应用:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

举例分析强化理解

假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。 中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。

  • 设置分组2(2位抢占 + 2位响应)
  • 中断配置如下:
中断号 中断类型 抢占优先级 响应优先级
中断3 RTC中断 2 1
中断6 外部中断0(EXTI0

网站公告

今日签到

点亮在社区的每一天
去签到