当前位置: 首页 > article >正文

【STM32】NVIC(嵌套向量中断控制器)

什么是 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 应用的实时性,优化中断的处理机制。

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!


http://www.kler.cn/a/590491.html

相关文章:

  • Android之RecyclerView列表拖动排序
  • Vue3项目白屏问题深度解析:从AI辅助诊断到性能优化实战
  • 《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(49)万鸦壶焚网络 - 网络延迟时间(Bellman-Ford)
  • Spring boot+mybatis的批量删除
  • 【AI】深度学习与人工智能应用案例详解
  • LIMS系统在纸制品制造的应用 内检实验室LIMS系统提升纸制品质控
  • Postman发送GET请求示例及注意事项
  • Vue.js 事件处理与修饰符详解
  • 2. qt写带有槽的登录界面(c++)
  • 玩转python:通俗易懂掌握高级数据结构-collections模块之UserDict
  • 人工智能之数学基础:从线性变换理解矩阵范数和矩阵行列式
  • 第一中标人!晶科能源入围大唐集团19.5GW光伏组件集采
  • 遥感新态势:Sentinel - 2多光谱指数与AI深度融合
  • 卡内基梅隆大学研究人员推出 PAPRIKA:一种微调方法,使语言模型能够发展出不局限于特定环境的通用决策能力
  • 基于javaweb的SpringBoot博客商城管理系统设计与实现(源码+文档+部署讲解)
  • 通过 Python 爬虫提高股票选股胜率
  • Linux快速安装mysql
  • 3D 射线方程学习
  • 青少年编程与数学 02-010 C++程序设计基础 43课题、MFC
  • 鸿蒙应用开发--数据埋点的名称由来,发展脉络,典型场景,现代演进的无埋点和智能化埋点//学习时长数据埋点的实现--待更新