STM32 NVIC中断优先级系统深度解析:抢占、子优先级与D223设计
2026/9/4 3:38:46 网站建设 项目流程

www.z-linear.com

D223有十几个中断源——TIM12/13/14定时器中断、QSPI DMA中断、USB中断……它们之间谁优先?TIM13中断能不能打断DMA中断?本文解析STM32的NVIC中断优先级系统及D223的优先级设计。


一、NVIC中断系统概述

1.1 中断优先级寄存器

IP寄存器组由240个8bit的寄存器组成,每个可屏蔽中断占用8bit。而每个可屏蔽中断占用的8bit并没有全部使用,而是只用了高4位。这4位,又分为抢占优先级和子优先级。

IP[n]寄存器(8位) ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ P │ P │ P │ P │ - │ - │ - │ - │ └───┴───┴───┴───┴───┴───┴───┴───┘ └───┴───┴───┘ └──────────────┘ 高4位有效 低4位未使用 抢占+子优先级

1.2 抢占优先级 vs 子优先级

抢占优先级:抢占优先级高的中断可以打断正在执行但抢占优先级低的中断,即中断嵌套。

子优先级:抢占优先级相同时,子优先级高的中断不能打断正在执行但子优先级低的中断,即子优先级不支持中断嵌套。

特性抢占优先级子优先级
支持嵌套
打断低优先级
同级排序✅(同时挂起时先执行)
位宽可变可变

1.3 五种优先级分组

STM32将中断分为5个组(Group 0~4),由SCB->AIRCR寄存器的bit[10:8]决定。

分组抢占优先级位数子优先级位数抢占级别数子级别数
Group 00位4位1级(无抢占)16级
Group 11位3位2级8级
Group 22位2位4级4级
Group 33位1位8级2级
Group 44位0位16级1级(无子优先级)

对于RTOS(FreeRTOS/RT-Thread/UCOS-III),官方强烈建议使用中断优先级分组4(NVIC_PriorityGroup_4),即高4位全部用于抢占优先级,不使用子优先级。


二、D223的中断优先级设计

2.1 优先级分组设置

D223使用RT-Thread,采用NVIC_PriorityGroup_4:

// HAL库设置优先级分组4HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);// 所有16个优先级都是抢占优先级,无子优先级

这意味着每个中断都有唯一的抢占优先级(0~15),数值越小优先级越高,高优先级可以打断低优先级。

2.2 D223中断优先级分配

中断源抢占优先级说明能否被嵌套
SysTick15(最低)RT-Thread时钟节拍可被任何中断打断
TIM12 (1ms)6DIO/PWM加减速可被0~5打断
TIM13 (采样)5QSPI ADC读取可被0~4打断
TIM14 (DAC)5DAC波形输出与TIM13同级
QSPI DMA4DMA传输完成可被0~3打断
USB OTG HS3USB数据收发可被0~2打断
SPI17FPGA寄存器可被0~6打断
EXTI2外部触发可被0~1打断

2.3 优先级设计原则

原则说明
高速数据最高QSPI DMA(4) > TIM13(5) 确保ADC数据不丢
USB通信高USB(3) > 定时器(5,6) 确保命令响应快
DAC与ADC同级TIM14(5) = TIM13(5) 无需相互嵌套
SysTick最低(15) 确保不会打断任何业务中断

2.4 中断嵌套示例

场景: TIM13中断正在执行时,QSPI DMA中断到来 TIM13(优先级5)执行中... ↓ DMA(优先级4)到来 → 4 < 5 → 嵌套! ↓ DMA中断执行(TIM13暂停) ↓ DMA执行完毕 → 恢复TIM13 ↓ TIM13继续执行

QSPI DMA优先级(4)高于TIM13(5),确保DMA完成后能立即通知TIM13中断处理函数。


三、HAL库中断配置API

3.1 设置优先级分组

// 设置优先级分组4(16级抢占,0级子优先级)HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

3.2 设置单个中断优先级

HAL_NVIC_SetPriority函数用于设置中断的抢占优先级和响应优先级。

// 设置TIM13中断:抢占优先级5,子优先级0HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn,5,0);// 设置DMA1 Stream5中断:抢占优先级4HAL_NVIC_SetPriority(DMA1_Stream5_IRQn,4,0);// 设置USB HS中断:抢占优先级3HAL_NVIC_SetPriority(OTG_HS_IRQn,3,0);// 使能中断HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);HAL_NVIC_EnableIRQ(OTG_HS_IRQn);

3.3 CubeMX中的配置

在CubeMX的NVIC Settings页面中,每个中断都有:

  • Preemption Priority(抢占优先级)
  • Sub Priority(子优先级)—— 分组4时此值固定为0
  • Enable/Disable(使能/禁止)

四、NVIC寄存器详解

4.1 中断使能寄存器(ISER)

ISER用于使能中断。写1使能对应中断,写0无效。

// 使能TIM13中断(IRQn = 45)NVIC->ISER[45/32]|=(1<<(45%32));// 等价于HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);

4.2 中断挂起寄存器(ISPR)

ISPR通过置1可以将正在进行的中断挂起,而执行同级或更高级别的中断。

// 挂起TIM13中断NVIC->ISPR[45/32]|=(1<<(45%32));

4.3 中断解挂寄存器(ICPR)

ICPR的作用与ISPR相反,通过设置1可以将挂起的中断解挂。

4.4 中断激活标志寄存器(IABR)

IABR如果为1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。

// 检查TIM13是否正在执行if(NVIC->IABR[45/32]&(1<<(45%32))){// TIM13中断正在执行}

五、中断服务程序

5.1 D223中断向量表

// stm32h7xx_it.cvoidSysTick_Handler(void){// 优先级15HAL_IncTick();rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();}voidTIM8_BR_TIM12_IRQHandler(void){// 优先级6HAL_TIM_IRQHandler(&htim12);}voidTIM8_UP_TIM13_IRQHandler(void){// 优先级5HAL_TIM_IRQHandler(&htim13);}voidTIM8_TRG_COM_TIM14_IRQHandler(void){// 优先级5HAL_TIM_IRQHandler(&htim14);}voidDMA1_Stream5_IRQHandler(void){// 优先级4HAL_DMA_IRQHandler(&hdma_quadspi);}voidOTG_HS_IRQHandler(void){// 优先级3HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);}voidOTG_HS_EP1_OUT_IRQHandler(void){// 优先级3HAL_PCD_EP1_OUT_IRQHandler(&hpcd_USB_OTG_HS);}voidOTG_HS_EP1_IN_IRQHandler(void){// 优先级3HAL_PCD_EP1_IN_IRQHandler(&hpcd_USB_OTG_HS);}

5.2 HAL中断处理链

硬件中断 → IRQHandler() ↓ HAL_TIM_IRQHandler() / HAL_DMA_IRQHandler() ↓ 检测中断标志位 ↓ 调用回调函数 ↓ 用户回调:HAL_TIM_PeriodElapsedCallback() HAL_QSPI_RxCpltCallback()

六、RTOS中的中断管理

6.1 RT-Thread中断管理

RT-Thread要求中断分为两类:

  • 优先级0~(configMAX_SYSCALL_INTERRUPT_PRIORITY-1):可以被RTOS管理,可以调用RTOS API
  • 优先级configMAX_SYSCALL_INTERRUPT_PRIORITY~15:不受RTOS管理,不能调用RTOS API

6.2 中断进入/退出钩子

voidTIM8_UP_TIM13_IRQHandler(void){rt_interrupt_enter();// 通知RTOS进入中断HAL_TIM_IRQHandler(&htim13);rt_interrupt_leave();// 通知RTOS离开中断// 如果有更高优先级线程就绪,此处触发调度}

6.3 中断中不能调用的API

在RTOS管理的中断中不能调用以下API(会导致死锁或损坏调度器):

  • rt_thread_delay()
  • rt_sem_take()(带等待时间)
  • rt_mutex_take()
  • rt_mb_recv()(带等待时间)

D223在中断中使用标志位而非RTOS同步对象,避免了这个问题。


七、中断延迟分析

7.1 中断响应时间

阶段耗时(@480MHz)说明
硬件响应~12周期(25ns)NVIC识别+压栈
向量跳转~3周期(6ns)取中断向量
ISR入口~10周期(20ns)函数prologue
HAL分发~50周期(104ns)HAL_TIM_IRQHandler
总延迟~160ns从事件到回调

7.2 D223的关键中断延迟

中断最大延迟允许延迟余量
TIM13(500K)~200ns2μs(500KSPS周期)10倍
QSPI DMA~200ns3.3μs(66B传输时间)16倍
USB~200ns~10μs(USB帧间隔)50倍

八、中断优先级常见问题

8.1 优先级反转

低优先级中断持有资源 → 高优先级中断等待资源 → 实际效果:低优先级"反转"高于高优先级

D223通过标志位+轮询避免了优先级反转(中断只设标志,不持有资源)。

8.2 中断风暴

高频中断持续抢占主线程 → 主线程"饿死" → 采集不停上报 → 主线程无CPU时间

D223的TIM13(500K)中断每2μs触发一次,但DMA完成后才设标志,主线程每1ms轮询一次,不会饿死。

8.3 优先级配置错误

// 错误示例:DMA优先级低于TIM13HAL_NVIC_SetPriority(DMA1_Stream5_IRQn,6,0);// 低于TIM13的5HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn,5,0);// DMA完成中断被TIM13延迟 → 数据丢失

九、D223中断设计总结

设计原则实现
优先级分组Group 4(16级抢占,无子优先级)
数据采集最高QSPI DMA(4) > TIM13(5)
USB通信次高USB(3) > 定时器
SysTick最低15级(不干扰业务)
中断嵌套DMA可嵌套TIM13,USB可嵌套DMA
中断中通信仅设标志位,不调RTOS API
临界区保护rt_hw_interrupt_disable/enable

十、总结

D223的NVIC中断系统实现了:

中断源优先级功能嵌套关系
USB OTG HS3USB数据收发可被EXTI(2)嵌套
QSPI DMA4DMA传输完成可被USB(3)嵌套
TIM135ADC采样触发可被DMA(4)嵌套
TIM145DAC波形输出与TIM13同级
TIM126DIO/PWM(1ms)可被TIM13(5)嵌套
SPI17FPGA寄存器可被TIM12(6)嵌套
SysTick15RT-Thread节拍可被所有中断嵌套

从优先级分组4的配置到16级抢占优先级的分配,从中断嵌套到RTOS中断管理,D223的中断优先级设计确保了高速数据采集(QSPI DMA优先级最高)、实时通信(USB次高)和系统稳定(SysTick最低)的平衡。


下篇预告:《STM32 HAL库回调机制深度解析》

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询