stm32学习(3)——NVIC中断优先级分组

相信大多数铁汁在学习stm32的时候都了解过51单片机的基本内容,对于51单片机来说,中断就那么几个:

  1. 外部中断0
  2. 定时器/计数器0中断
  3. 外部中断1
  4. 定时器/计数器1中断
  5. 串口中断

它们在51单片机中的优先级也是按自上而下的顺序,中断少且优先级明确,这就是大家了解的51单片机中断系统,又顺便复习了一波老知识。

而在stm32f103系列芯片中有60个可屏蔽中断(可屏蔽中断简单来说就是可以由寄存器控制是否产生中断的中断,skr~),从《stm32中文参考手册》中可以看到有这么0-59号一共60个可屏蔽中断。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

NVIC中断优先级分组

对于数量如此之多的中断源怎么来进行中断管理也是一个问题,但是stm32给出了很好地解决办法,NVIC中断优先级分组(NVIC不懂没关系,我也不懂,懂分组就行了)
在这里插入图片描述
从图中可以看到(application interrupt and reset control register应用中断和复位控制寄存器AIRCR[10:8]这三位,也就是下图中绿色的三位,由这三位共同决定分组配置。
在这里插入图片描述
还要了解抢占优先级与响应优先级的基本概念:

  1. 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的
  2. 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断
  3. 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行
  4. 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行
  5. 优先级数字越小,优先级越高,越先被执行

了解了抢占与响应两个优先级的基本概念后再看上面的表就会发现,可以设置5中不同的优先级分组,每种都是4位也就是16种不同的优先级设置。

NVIC中断优先级设置

一般情况下,系统代码执行过程中,只设置一次中断优先级分组(并且是在main函数比较靠前的位置设置),设置好分组之后一般不会再改变分组。若是在多处进行了分组,程序会以最后一次的分组为准,并且之前设置的分组全部失效。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。
在stm32中,关于NVIC优先级设置的函数都在misc.h里可以看到:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);

在main函数中通常使用一个中断优先级分组设置函数

NVIC_PriorityGroupConfig();

//函数的入口参数可以选择这些,也就是对应上表的几种分组
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
                                       ((GROUP) == NVIC_PriorityGroup_1) || \
                                       ((GROUP) == NVIC_PriorityGroup_2) || \
                                       ((GROUP) == NVIC_PriorityGroup_3) || \
                                       ((GROUP) == NVIC_PriorityGroup_4))

在单个中断设置抢占和响应优先级时通常用:

 NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

//入口参数有三个
  assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));		//中断使能
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); 		//抢占优先级设置 
  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));		//响应优先级设置

关于NVIC中断优先级分组的介绍就到这了,砰~,水遁消失。

猜你喜欢

转载自blog.csdn.net/lqj11/article/details/106290521