NVIC中断优先级

一、STM32 NVIC 中断优先级管理

1,中断:

  • CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。
  • STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。
  • STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。
  • 在 STM32F103 系列 上面,又只有 60 个(在 107 系列才有 68 个)可屏蔽中断。如下:

    file

2,中断管理方法:

首先,对 STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。
分组配置是在寄存器SCB->AIRCR以配置:(根据AIRCR的位来操作分组情况)

file


抢占优先级&响应优先级区别 :

  • 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。(值越小优先级越高)
  • 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
  • 抢古优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
  • 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

举例:假定设置中断优先级组为2设置如下:

  • 中断3(RTC中断)的抢占优先级为2,响应优先级为1。
  • 中断6(外部中断0)的抢占优先级为3,响应优先级为0。
  • 中断7(外部中断1)的抢占优先级为2,响应优先级为0。
    那么这3个中断的优先级顺序为:中断7>中断3>中断6。

特别说明:
一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

3,中断优先级分组函数:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分 组确定就最好不要更改。这个函数我们可以找到其实现:(misc.c中)

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) 
{ 
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); 
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; 
}COPY

例如:设置某函数为分组2

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);COPY

二、中断优先级设置

如何设置单个中断?

MDK中NVIC中断相关寄存器结构体:

typedef struct
{
    //中断使能寄存器组
_lO uint32_t ISER[8];
uint32_t RESERVEDO[24];

//中断失能寄存器组
_IO uint32_t ICER[8];
uint32_t RSERVED1[24];

//中断挂起寄存器组
_lO uint32_t ISPR[8];
uint32_t RESERVED2[24];

//中断解挂寄存器组
_lOuint32_t ICPR[8];
uint32tRESERVED3[24];

//中断激活标志位寄存器组
_lO uint32_t IABR[8];
uint32_t RESERVED4[56];

//中断优先级控制的寄存器组
_IO uint8_t IP[240];
uint32_t RESERVED5[644];

_Ouint32_t STIR;
}NVIC_Type;
COPY

对于每个中断怎么设置优先级?

中断优先级控制的寄存器组:IP[240]

全称是: Interrupt Priority Registers
240个8位寄存器,每个中断使用一个寄存器来确定优先级。
STM32>10x系列一共60个可屏蔽中断,使用IP[59]-IP[0]。
每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。

设置函数:void NVIC_Init(NVIC_InitTypeDefNVIC_InitStruct);
其结构体:

typedef struct 
{ 
uint8_t NVIC_IRQChannel; //定义初始化的是哪个中断(可以在 stm32f10x.h 中找到 每个中断对应的名字)
uint8_t NVIC_IRQChannelPreemptionPriority; //定义这个中断的抢占优先级别。 
uint8_t NVIC_IRQChannelSubPriority; //定义这个中断的子(响应)优先级别。 
FunctionalState NVIC_IRQChannelCmd;//该中断是否使能。
} NVIC_InitTypeDef;
COPY

比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:

NVIC_InitTypeDef NVIC_InitStructure; 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中断 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子(响应)优先级位 2 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 
NVIC_Init(&NVIC_InitStructure); 
//根据上面指定的参数初始化 NVIC 寄存器
COPY

三、NVIC总结:

中断优先级设置步骤
1,系统运行后先设置中断优先级分组。调用函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组

2,针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDefNVIC_InitStruct);

3,如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

本文转载自:NVIC中断优先级 – 布尔博客

<think>我们正在配置ARMCortex-M系列微控制器的NVIC中断优先级。根据引用内容,配置步骤主要包括设置优先级分组和设置具体中断优先级。注意:优先级数值越小,优先级越高。步骤:1.设置优先级分组(通常在系统初始化时调用一次)。在ARMCortex-M中,优先级分组决定了抢占优先级和子优先级的位数。例如,使用`NVIC_PRIORITYGROUP_4`表示4位抢占优先级,0位子优先级(即没有子优先级,所有位都用于抢占优先级)。2.设置具体中断优先级。使用`NVIC_SetPriority`函数,参数包括中断号、编码后的优先级值。编码优先级时,需要根据当前设置的优先级分组,将抢占优先级和子优先级(如果有)组合成一个数值。可以使用`NVIC_EncodePriority`函数来编码。注意:在设置优先级时,数值越小优先级越高。示例代码(基于引用[3]):```c//1.设置优先级分组NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);//使用分组4,即4位抢占优先级,0位子优先级//2.设置具体中断优先级//假设我们要设置USART1中断的抢占优先级为1,TIM2中断的抢占优先级为5(因为分组4没有子优先级,所以子优先级设为0)NVIC_SetPriority(USART1_IRQn,NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,0));NVIC_SetPriority(TIM2_IRQn,NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5,0));```详细步骤说明:1.**设置优先级分组**:通过设置SCB->AIRCR寄存器的PRIGROUP字段(使用库函数`NVIC_SetPriorityGrouping`)。分组的选择决定了抢占优先级和子优先级的位数。常见的分组有:-NVIC_PRIORITYGROUP_0:0位抢占优先级,4位子优先级(对于8位优先级寄存器,具体位数取决于实现)-NVIC_PRIORITYGROUP_1:1位抢占优先级,3位子优先级-...以此类推,直到NVIC_PRIORITYGROUP_4:4位抢占优先级,0位子优先级(对于Cortex-M3/M4等,优先级寄存器通常为8位,但Cortex-M0可能只有2位,所以分组可能有限,具体参考芯片手册)。注意:在Cortex-M0中,通常只支持非常有限的分组(可能只有2个优先级位),所以分组设置可能只有一种或两种。具体需要查阅芯片手册。2.**设置中断优先级**:对于每个中断,需要指定其抢占优先级和子优先级(根据分组设置)。使用`NVIC_SetPriority`函数,该函数需要中断号(如USART1_IRQn)和优先级值。优先级值可以通过`NVIC_EncodePriority`函数生成,该函数根据当前的分组设置将抢占优先级和子优先级编码成一个数值。注意事项:-优先级数值越小,优先级越高。-复位、NMI和HardFault等异常具有固定优先级,它们的优先级比任何可编程中断优先级都高,因此不能配置。-在配置中断优先级之前,必须先设置优先级分组(一般整个系统只设置一次,在初始化时设置)。-最后,别忘了使能中断(使用`NVIC_EnableIRQ`函数)。完整配置步骤示例(以USART1中断为例):```c//设置优先级分组(整个系统只设置一次)NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);//配置USART1中断优先级uint32_tpriorityGroup=NVIC_GetPriorityGrouping();//获取当前优先级分组设置(可选,但为了明确可以获取一下)uint32_tusartPriority=NVIC_EncodePriority(priorityGroup,1,0);//抢占优先级1,子优先级0(由于分组4,子优先级被忽略)NVIC_SetPriority(USART1_IRQn,usartPriority);//使能USART1中断NVIC_EnableIRQ(USART1_IRQn);```总结:配置NVIC中断优先级的步骤为:设置优先级分组->为每个中断编码优先级(包括抢占优先级和子优先级)并设置->使能中断。请根据实际使用的微控制器和需求选择合适的分组和优先级数值。参考文献:[^1]:ARMCortex-M微控制器--中断优先级分组[^2]:ARMCortex-M系列微控制器-NVIC[^3]:设置优先级分组和具体中断优先级的代码示例[^4]:Cortex-M处理器的异常优先级规则[^5]:Cortex-M0系列处理器的应用领域相关问题:1.在ARMCortex-M中,中断优先级分组的作用是什么?2.如何选择合适的中断优先级分组?3.在配置中断优先级时,为什么需要调用`NVIC_EncodePriority`函数?4.如何使能和禁用特定的中断?5.在ARMCortex-M0中,中断优先级的配置与Cortex-M3/M4有什么不同?</think>### ARM Cortex-M NVIC中断优先级配置指南 在ARM Cortex-M系列微控制器中,NVIC(嵌套向量中断控制器)负责管理中断优先级。配置步骤如下: #### 一、核心概念 1. **优先级规则**:优先级数值越小,实际优先级越高(如优先级0 > 优先级1 > 优先级15)[^3]。 2. **分组机制**:优先级位被分为抢占优先级(preemption)和子优先级(subpriority)两部分: - 抢占优先级:决定中断能否打断当前中断 - 子优先级:相同抢占优先级时决定执行顺序 3. **固定优先级**:复位、NMI和HardFault具有固定最高优先级(负数值)[^4]。 #### 二、配置步骤(基于标准外设库) ```c // 1. 设置全局优先级分组(系统初始化时调用一次) NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); // 示例:4位抢占优先级,0位子优先级 // 2. 配置具体中断优先级 // 语法:NVIC_SetPriority(IRQn, priority) // 优先级编码:NVIC_EncodePriority(分组, 抢占级, 子级) NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 0)); // 抢占级1 NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); // 抢占级5(低于USART1)[^3] // 3. 使能中断通道 NVIC_EnableIRQ(USART1_IRQn); NVIC_EnableIRQ(TIM2_IRQn); ``` #### 三、关键寄存器 1. **SCB->AIRCR**:通过PRIGROUP字段(bit10:8)设置优先级分组方案[^1] 2. **NVIC_IPRx**:设置具体中断源的优先级值 3. **NVIC_ISERx**:中断使能寄存器 #### 四、分组方案选择 | 分组宏 | 抢占优先级位数 | 子优先级位数 | 优先级总数 | |------------------------|----------------|--------------|------------| | NVIC_PRIORITYGROUP_0 | 0 | 4 | 16 | | NVIC_PRIORITYGROUP_1 | 1 | 3 | 8 | | NVIC_PRIORITYGROUP_2 | 2 | 2 | 4 | | **NVIC_PRIORITYGROUP_3** | 3 | 1 | 2 | | **NVIC_PRIORITYGROUP_4** | 4 | 0 | 1 | > 推荐使用GROUP_4(纯抢占优先级)简化设计[^3] #### 五、注意事项 1. 整个系统**只能设置一次**优先级分组(通常在启动代码中) 2. Cortex-M0/M0+仅支持2-4级优先级(精简版NVIC)[^5] 3. 优先级数值范围取决于芯片实现(4位或8位) 4. 高优先级中断可抢占低优先级中断形成嵌套[^4] [^1]: ARM Cortex-M 微控制器中断优先级分组通过SCB->AIRCR寄存器配置 [^2]: NVIC是Cortex-M处理中断的核心组件,支持嵌套和优先级处理 [^3]: 优先级数值越小优先级越高,GROUP_4分组简化优先级管理 [^4]: 复位/NMI/HardFault具有固定最高优先级,支持异常嵌套 [^5]: Cortex-M0系列采用精简NVIC优先级配置更简单
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值