06、原子战舰 NVIC 中断优先级管理

NVIC中断优先级分组

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在中断向量表中从优先级7-66(中断号从0-59)代表着STM32F103的60个中断。优先级号越小,优先级越高。

中断管理方法

首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。

分组配置是在寄存器SCB->AIRCR中配置:
在这里插入图片描述
抢占优先级的级别高于响应优先级,而数值越小所代表的的优先级越高。

介绍一下抢占优先级、响应优先级的区别:

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

  • 打断的情况只会与抢占优先级有关, 和响应优先级无关!
  • 一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果

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

中断优先级分组库函数

中断优先级分组函数,NVIC_SetPriorityGrouping()
在这里插入图片描述
在这里插入图片描述 NVIC_Init
在这里插入图片描述
在这里插入图片描述

NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f4xx.h 中定义的枚举类 型 IRQn
的成员变量中可以找到每个中断对应的名字。例如串口 1 对应 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
NVIC_IRQChannelSubPriority:定义这个中断的响应优先级别。
NVIC_IRQChannelCmd:该中断通道是否使能。

比如我们要使能串口 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 寄存器

编程步骤
1、设置分组
2、外设中断使能(函数名在外设的头文件中有)
3、初始化
4、写中断服务函数

//1.
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //可能在主函数
//2.
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);             //可能在初始化函数中
//3.
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 寄存器
//4.中断服务函数
void USART1_IRQHandler(void)
{
}
发布了274 篇原创文章 · 获赞 97 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/imxlw00/article/details/104463189