前言

STM32F103作为入门级嵌入式开发的经典款MCU,凭借性价比高、资料丰富、外设齐全的特点,成为绝大多数嵌入式新手的第一块开发板。不管是按键外部中断、串口收发、定时器定时,还是ADC采集、SPI通信,都会用到中断机制;而当多个中断同时触发时,中断优先级就是保证系统稳定、实时响应的核心。

很多新手学到中断优先级时,经常被“抢占优先级、子优先级、NVIC分组”绕晕,要么配置混乱导致系统死机,要么高优先级任务得不到响应。本文以最常用的STM32F103C8T6为例,从零科普中断优先级核心原理,讲透NVIC分组规则,搭配标准库+HAL库双版本实战代码,帮你彻底搞定STM32中断优先级。

💡 核心前提(STM32F103专属):F103基于Cortex-M3内核,NVIC中断控制器使用4位优先级配置,共16级可编程优先级;数值越小,优先级越高,这是配置的黄金准则!

一、先搞懂:两个关键优先级(抢占+子优先级)

STM32F103的中断优先级并非单一维度,而是分为抢占优先级子优先级,两者分工完全不同,共同决定中断的执行顺序,多中断场景下缺一不可。

1. 抢占优先级(Preemption Priority)

抢占优先级决定中断能否嵌套,也就是中断的“插队权限”,是保证关键任务实时性的关键:

  • 高抢占优先级中断:可以直接打断正在执行的低抢占优先级中断,处理完毕后再返回原中断继续执行;

  • 同抢占优先级中断:不能互相打断,必须排队等待,按照触发顺序依次执行。

👉 F103场景举例:串口1接收中断(抢占0)> 按键外部中断(抢占1),当串口收到数据时,可直接打断按键处理,避免串口数据丢包。

2. 子优先级(SubPriority/响应优先级)

子优先级仅作用于抢占优先级完全相同的中断,决定同级别中断的“排队执行顺序”:

  • 抢占优先级一致时,子优先级数值越小,越先执行

  • 子优先级不支持中断嵌套,仅做同级别仲裁,没有任何插队能力。

👉 F103场景举例:定时器2中断、定时器3中断抢占优先级均为1,定时器2子优先级0、定时器3子优先级1,定时器2会优先响应。

3. STM32F103优先级判断规则

  1. 第一步比抢占优先级:数值越小 → 优先级越高,可打断低优先级中断;

  2. 第二步比子优先级:抢占优先级相同时,数值越小 → 执行顺序越靠前;

  3. 第三步按默认顺序:两者数值完全相同时,按中断向量表出厂顺序执行。

二、STM32F103中断优先级分组(NVIC)

STM32F103的NVIC只有4位寄存器用来配置优先级,需要通过优先级分组,把这4位拆分成“抢占优先级位+子优先级位”;全局只能配置1次分组,禁止重复修改,否则会导致优先级彻底混乱!

1. 5种分组方案(F103全覆盖)

Cortex-M3内核支持5种分组方式,对应不同的抢占、子优先级数量,新手可根据项目复杂度直接选用,表格清晰对比:

分组编号 抢占优先级位数 子优先级位数 可配置抢占级数 可配置子优先级数 适合F103项目场景
Group 0 0位 4位 1级(固定0) 16级(0-15) 极简项目,无中断嵌套需求
Group 1 1位 3位 2级(0-1) 8级(0-7) 简单项目,少量中断嵌套
Group 2(新手首选) 2位 2位 4级(0-3) 4级(0-3) 通用项目,平衡嵌套与灵活性
Group 3 3位 1位 8级(0-7) 2级(0-1) 复杂项目,多中断嵌套需求
Group 4 4位 0位 16级(0-15) 1级(固定0) 强实时项目,无需子优先级
新手开发建议:STM32F103日常开发优先选Group 2,4级抢占+4级子优先级,足够应对绝大多数按键、串口、定时器、ADC项目,不易出错且灵活性拉满。

2. 优先级分组配置代码

(1)标准库配置(F103最常用)
// 必须在main函数开头、外设初始化前调用,仅执行一次
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

(2)HAL库配置
// 全局优先级分组配置,与标准库分组规则一致
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

三、STM32F103中断优先级实战配置

结合STM32F103最常用的外设中断,给出标准库+HAL库双版本实战代码,优先级分配贴合实际项目,直接复制到工程即可使用。

1. F103常用中断优先级推荐(Group 2分组)

中断源名称 抢占优先级 子优先级 配置理由(F103项目)
USART1_IRQn(串口1接收) 0 0 最高优先级,避免串口数据丢失
EXTI0_IRQn(按键中断) 1 0 实时响应按键,保证人机交互流畅
TIM2_IRQn(定时器2) 1 1 定时调度任务,优先级次于按键
ADC1_2_IRQn(ADC采集) 2 0 非实时采集,不影响核心任务

2. 标准库完整配置代码(F103通用)

#include "stm32f10x.h"

// NVIC中断优先级配置函数
void NVIC_Config(void)
{
    // 1. 全局分组配置:2位抢占+2位子优先级
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitTypeDef NVIC_InitStructure;
    
    // 2. 串口1中断:最高优先级
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    // 3. 按键外部中断(EXTI0)
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
    
    // 4. 定时器2中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
    
    // 5. ADC1采集中断
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
}

3. HAL库完整配置代码

#include "stm32f1xx_hal.h"

void MX_NVIC_Init(void)
{
  // 全局分组配置
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

  // 串口1中断
  HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(USART1_IRQn);

  // 外部按键中断
  HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

  // 定时器2中断
  HAL_NVIC_SetPriority(TIM2_IRQn, 1, 1);
  HAL_NVIC_EnableIRQ(TIM2_IRQn);

  // ADC中断
  HAL_NVIC_SetPriority(ADC1_2_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}

四、STM32F103中断优先级避坑指南(新手必看)

针对STM32F103开发,新手最容易踩的6个中断优先级坑,一定要牢记避开:

  1. 禁止重复配置分组:全局只调用1次优先级分组,多次调用会导致中断逻辑混乱、系统死机;

  2. 优先级数值别搞反:牢牢记住数值越小,优先级越高,不要把15当成最高优先级;

  3. 中断服务函数越短越好:高优先级中断严禁写延时、大量串口打印,尽快退出,避免阻塞其他中断;

  4. 关键中断优先级要高:串口接收、无线接收、紧急按键等实时性要求高的中断,抢占优先级设为0;

  5. 闲置中断及时失能:不用的中断要关闭,避免误触发导致系统异常;

  6. 注意中断向量号:不同外设对应不同中断通道,不要写错中断名(比如USART1和USART2中断不可混用)。

五、F103中断优先级常见问题解答

Q1:STM32F103可以不配置子优先级吗?

A:可以,选择Group 4分组,4位全部用于抢占优先级,适合无嵌套、强实时的极简项目。

Q2:配置完中断优先级,中断不响应怎么办?

A:按顺序排查3点:①是否配置了全局优先级分组;②中断通道是否正确使能;③抢占优先级是否被更高优先级中断阻塞。

Q3:F103的中断优先级和其他STM32系列通用吗?

A:核心规则完全通用,仅中断向量号、分组位数略有差异,F103学会后,F4、F7、L4等系列可快速上手。

Q4:低优先级中断能打断高优先级吗?

A:绝对不能!抢占优先级严格遵循“高打断低”,同级别只能排队,这是NVIC的核心机制。

总结

STM32F103的中断优先级逻辑并不复杂,核心就是:4位分组定抢占和子优先级,数值越小越优先,抢占决定嵌套,子优先级决定排队

新手入门优先选用Group 2分组,把串口、紧急按键等关键任务设为高抢占优先级,普通定时、采集任务设为低优先级,配合精简的中断服务函数,就能写出稳定、实时性强的F103程序。

中断是STM32开发的核心,吃透优先级配置,后续学习RTOS、复杂外设驱动都会事半功倍,建议大家拿到开发板直接上手实操,加深理解。


👉 原创干货,觉得有用欢迎点赞、收藏、关注

🎁欢迎关注,获取更多技术干货!

公众号:BackCatK Chen,文章末尾可以扫码关注

🎁资料包亮点

这份资料包涵盖了从硬件电路设计STM32单片机开发,再到Linux系统学习的全链路内容,适合不同阶段的学习者:

  • 硬件基础:包含硬件电路合集、硬件设计开发工具包,帮你打牢底层基础。
  • STM32专项:从环境搭建、开发工具、传感器模块到项目实战,还有书籍和芯片手册,一站式搞定STM32学习。
  • C语言进阶:C语言学习资料包,助你掌握嵌入式开发的核心语言。
  • 面试求职:嵌入式面试题合集,提前备战技术面试。
  • Linux拓展:Linux相关学习资料包,拓宽技术视野。
📂资料包目录
  • 00-STM32单片机环境搭建
  • 01-硬件电路合集
  • 02-硬件设计开发工具包
  • 03-C语言学习资料包
  • 04-STM32单片机开发工具包
  • 05-STM32传感器模块合集
  • 06-STM32项目合集
  • 07-STM32单片机书籍&芯片手册
  • 08-Linux相关学习资料包
    在这里插入图片描述
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐