STM32中断优先级分组与抢占关系详解:10分钟速成指南

STM32 的中断优先级机制,是很多初学者和项目新人经常绕晕的一个概念。什么是抢占?什么是响应优先级?优先级分组又到底是干嘛的?为什么你设置了优先级却根本没生效?

别慌,这篇文章用 10分钟 帮你从概念 -> 配置 -> 实战,一步步搞清楚 STM32 中断优先级到底怎么玩。


1. STM32 中断优先级机制全貌

STM32 的中断控制由 NVIC(Nested Vectored Interrupt Controller) 控制,它支持中断嵌套,也就是“中断中断”。

NVIC 的中断优先级包括两个核心概念:

  • 抢占优先级(Preemption Priority):谁能打断谁。

  • 响应优先级 / 子优先级(Sub Priority):在抢占等级相同的情况下,谁先被响应。

  • 类比理解

    抢占优先级 = 职位高低
    响应优先级 = 谁先排队等的久

    如果两个中断的抢占等级不同,抢占等级高的可以中断低的中断。
    如果抢占等级一样,就比较响应优先级。


    2. 优先级分组是怎么回事?

    STM32 使用 CMSIS 标准,将中断优先级表示为一个 4bit 的值(0~15),但这个 4bit 如何划分抢占和响应,是由你配置的:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    STM32 的库函数允许你在 5 个“优先级分组”之间选择:

    分组模式 抢占优先级位数 响应优先级位数
    Group 0 0 4
    Group 1 1 3
    Group 2 2 2
    Group 3 3 1
    Group 4 4 0

    例如:你设为 Group 2,则 2 位抢占优先级 + 2 位响应优先级。

    注意:STM32 的默认分组不一定是你期望的!一定要显式调用 NVIC_PriorityGroupConfig() 来设置,否则你设的优先级可能完全没起作用。


    3. 优先级配置函数怎么用?

    NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);

    重点提示: 你设的优先级(0~15)实际上被映射成一个硬件中的优先级值,和 NVIC_PriorityGroupConfig() 直接相关,不设置分组会导致优先级行为完全失效。


    4. 实战示例:两个中断,谁先响应?

    我们设置两个中断:

  • EXTI0_IRQn:外部按键中断

  • USART1_IRQn:串口中断

  • 设定如下:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_IRQChannelPreemptionPriority = 0; NVIC_IRQChannelSubPriority = 1; // 对 USART NVIC_IRQChannelPreemptionPriority = 1; NVIC_IRQChannelSubPriority = 0; // 对 EXTI

    结果:即使 EXTI 先触发,也会被 USART 中断“插队”。

    因为 USART 抢占优先级更高(0 < 1),所以可以打断正在执行的 EXTI。

    结论:只要抢占优先级不同,不管谁先触发,中断一定被打断!


    5. 初学者最容易犯的三大误区

    误区1:只设置了优先级,没设置分组

    STM32 的中断优先级配置是双重的:优先级值 + 分组配置 缺一不可。

    误区2:以为抢占优先级和响应优先级加起来不能超过4

    不是“加起来”,而是由 NVIC_PriorityGroup 分开定义的位数!

    误区3:不知道某些中断(SysTick、PendSV)有固定优先级

    系统中断(比如 SysTick)的优先级用特殊寄存器设置,不能随便 NVIC_Init 配置


    6. 写给调试者的实用建议

  • 调试中断优先级时,强烈建议使用逻辑分析仪或串口打印标记时间点。

  • 建议固定使用 NVIC_PriorityGroup_2,抢占优先级足够用,响应优先级也能灵活分配。

  • 若需要确保某中断绝对优先,设为 Preemption = 0,并尽量避免复杂处理逻辑,防止中断阻塞。


  • 总结

    STM32 中断优先级看起来复杂,其实只要记住这三点就能掌握:

    1. 抢占优先级 = 谁能打断谁

    2. 响应优先级 = 抢占等级相同谁先响应

    3. 优先级分组决定了优先级的“位宽分配”

    作者:唐萍摆摊中

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32中断优先级分组与抢占关系详解:10分钟速成指南

    发表回复