单片机
返回首页

【STM32】NVIC嵌套向量中断控制器详解

2025-10-09 来源:cnblogs

什么是 NVIC?

NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器) 适用于 Cortex-M0、M3、M4、M7 等 ARM 处理器,广泛用于 STM32、ESP32、GD32、NXP 等 MCU 中,它用于管理和控制中断,是 ARM Cortex-M 系列微控制器 的核心外设之一。NVIC 负责中断优先级管理、嵌套中断处理和中断向量跳转,使 Cortex-M 处理器能够高效地响应中断请求。


NVIC 主要功能

1. 支持多个中断源(STM32F103 系列最多支持 60 个)

2. 支持中断优先级管理(可配置 8~256 级优先级)

3. 支持中断嵌套(高优先级中断可打断低优先级中断)

4. 支持向量表偏移(Vector Table Offset Register, VTOR)

5. 支持低功耗中断唤醒(Wake-up Interrupt Controller, WIC)

6. 支持中断屏蔽、清除、挂起和使能

NVIC 与 Cortex-M 处理器紧密集成,能够 `直接与 CPU 交互`,实现高效的中断处理机制:

NVIC 负责中断管理,Cortex-M3/M4 使用 NVIC 进行中断分配,支持快速中断响应(低延迟),支持 Tail-Chaining(尾链接优化),减少中断切换开销。


???? NVIC 架构示意图:


+-----------------------------------+

            |          Cortex-M 内核           |

            +-----------------------------------+

            |           NVIC 控制器           |

            |  - 中断向量表 (Vector Table)     |

            |  - 优先级寄存器 (IPR)            |

            |  - 使能寄存器 (ISER)             |

            |  - 清除寄存器 (ICER)             |

            |  - 挂起寄存器 (ISPR / ICPR)      |

            |  - 系统控制寄存器 (AIRCR)         |

            +-----------------------------------+

            |         外设(UART, GPIO, TIM)  |

            +-----------------------------------+

NVIC 寄存器

在 STM32F103 及其他 Cortex-M 系列 MCU 中,NVIC 主要通过以下寄存器进行控制:

寄存器作用
ISER(中断使能寄存器)设置某个中断为“使能”状态
ICER(中断清除寄存器)关闭某个中断
ISPR(中断挂起寄存器)设置某个中断为“挂起”状态(软件触发)
ICPR(中断清除挂起寄存器)取消某个中断的挂起状态
IABR(中断激活状态寄存器)读取当前激活的中断
IPR(中断优先级寄存器)设置中断优先级
STIR(软件触发中断寄存器)手动触发一个中断(仅限 Cortex-M3/M4)

NVIC 中断优先级管理

⭐ 1. 中断优先级划分


NVIC 采用 8 位优先级字段,在不同的 STM32 设备中,实际使用的优先级位数可能不同:


NVIC 采用 分组优先级(Group Priority)+ 子优先级(Sub Priority) 机制:

分组优先级(Preempt Priority):决定中断是否可以抢占其他中断。

子优先级(Sub Priority):当多个相同分组优先级的中断发生时,决定处理顺序。

???? 优先级编码格式(STM32F103,4-bit):


| 4-bit 优先级字段 |  |

|-----------------|  

|  Preemption(4)  |  Sub(0)  |

数值越小,优先级越高(0 最高,255 最低)。

抢占优先级高的中断可以中断低优先级的中断。

⭐ 2. NVIC 优先级配置示例


使用 CMSIS(Cortex Microcontroller Software Interface Standard) 提供的函数可以轻松配置 NVIC:


#include 'stm32f10x.h'


// 配置中断优先级

void NVIC_Configuration(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;


    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  // 选择 USART1 中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级 1(数值小,优先级高)

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  // 子优先级 1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能中断

    NVIC_Init(&NVIC_InitStructure);

}


// USART1_IRQn:定义要配置的中断源

// NVIC_IRQChannelPreemptionPriority:设置抢占优先级

// NVIC_IRQChannelSubPriority:设置子优先级

// NVIC_IRQChannelCmd:使能该中断

示例二:Cortex-M 配置优先级:


void NVIC_SetPriority_Config(void) {

    NVIC_SetPriorityGrouping(2);  // 2 位抢占,2 位子优先级

    NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(2, 1, 1));

}

⭐ 3. NVIC 优先级分组



通过 SCB->AIRCR 配置 优先级分组:

分组模式抢占优先级位数子优先级位数适用场景
0b000(Group 0)0 位4 位适用于无抢占,所有中断按优先级顺序执行
0b100(Group 1)1 位3 位适用于少量高优先级抢占中断
0b101(Group 2)2 位2 位适用于多级抢占
0b110(Group 3)3 位1 位适用于实时系统,多级抢占
0b111(Group 4)4 位0 位适用于完全抢占,所有中断可被更高优先级中断打断

示例:高优先级中断打断低优先级中断:



???? 在 NVIC 配置中


EXTI0_IRQn 抢占优先级 0

TIM2_IRQn 抢占优先级 2

➡ 当 TIM2 在运行时,EXTI0 可以抢占 TIM2。

void TIM2_IRQHandler(void) {

    // 低优先级中断(定时器中断)

    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

    }

}


void EXTI0_IRQHandler(void) {

    // 高优先级中断(外部中断)

    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {

        EXTI_ClearITPendingBit(EXTI_Line0);

    }

}

NVIC 低功耗管理

NVIC 具备低功耗模式下的中断唤醒功能:


睡眠模式(Sleep Mode):等待中断(WFI)或事件(WFE)唤醒。

停止模式(Stop Mode):只有特定外设(如 RTC、EXTI)可唤醒。

待机模式(Standby Mode):最低功耗模式,仅通过外部中断(EXTI)或 RTC 唤醒。

示例代码(使用 WFI 指令进入低功耗模式):


void Enter_SleepMode(void)

{

    __WFI();  // 等待中断唤醒

}

不过,在某些情况下,可以通过软件触发中断(不依赖外部事件):


NVIC_SetPendingIRQ(EXTI0_IRQn);  // 触发 EXTI0 中断挂起


// 应用场景:

// 手动测试中断处理函数

// 在任务调度器中强制触发某个中断

NVIC 相关 API(CMSIS)

函数作用
NVIC_EnableIRQ(IRQn_Type IRQn)使能指定中断
NVIC_DisableIRQ(IRQn_Type IRQn)禁用指定中断
NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)设置中断优先级
NVIC_GetPriority(IRQn_Type IRQn)获取当前中断优先级
NVIC_SetPendingIRQ(IRQn_Type IRQn)触发中断挂起
NVIC_ClearPendingIRQ(IRQn_Type IRQn)清除中断挂起
NVIC_GetPendingIRQ(IRQn_Type IRQn)获取中断挂起状态
NVIC_GetActive(IRQn_Type IRQn)读取当前激活的中断

NVIC 是 ARM Cortex-M 系列的核心中断管理单元,支持多级中断嵌套、优先级分配和中断屏蔽,合理配置 NVIC 优先级,可以提高系统的实时性和响应速度,掌握 NVIC 操作 API(使能/禁用/挂起/清除)在嵌入式开发是十分重要的一环。它支持 60+ 中断源,最高 256 级优先级; 支持抢占式优先级调度,优化中断响应;支持低功耗模式唤醒,适用于电池供电设备;提供 CMSIS API,简化 NVIC 配置,可以利用 NVIC 提高 STM32 应用的实时性,优化中断的处理机制。


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • 12V转110V/220V 500W逆变器

  • DS1669数字电位器

    相关电子头条文章