NVIC中断优先级管理示例解析
目录
NVIC中断优先级管理
STM32中断优先级简介
NVIC的缩写是“嵌套向量中断控制器(Nested Vectored Interrupt Controller)”。
如何管理中断?
STM32中断优先级管理采用“响应优先级和抢占优先级”结合的方法,并且进行了中断分组。
以第1组为例:1bit抢占优先级说明抢占优先级共有两级,3bits响应优先级说明响应优先级共有8级。我们可以看到无论如何分组,中断优先级总有16种。
什么是“抢占优先级”和“响应优先级”呢?
抢占优先级和响应优先级都是区分那个中断优先进行的标志,但是两者的含义去不尽相同。
抢占优先级从名字上就比响应优先级霸气一些,因此抢占优先级起决定作用,当抢占优先级相同时,响应优先级高的才会优先发生。
优先级是如何定义的?
值越小,优先级越大。
例如:假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。 中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。
优先级顺序:中断7>中断3>中断6
结论:抢占优先级高的必定先抢*断,如果抢占优先级相同,那就看响应优先级,此时谁的响应优先级高,谁就先发生。
除此之外,如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个,排序越考上,中断越优先。中断向量地址可以参考“STM32中文参考手册->中断->中断异常向量”部分的内容。部分示例:
特别说明
一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。
函数介绍
在操作函数的底层中,我们一般只用到ISER、ICER、IP这3个寄存器。ISER用于使能中断,ICER用来清除中断,IP用来设置中断优先级。
中断优先级分组选择函数
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
我们选择的是按照组2的方式进行分组,即抢占优先级总数为4级(0-3),响应优先级总级数为4级(0-3)。我们可以看到无论如何分组,中断优先级总有16种。
对于每个中断怎么设置优先级?
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 2<3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //3<=3
NVIC_Init(&NVIC_InitStructure);
如何理解中断挂起与解挂的含义?
中断的挂起与解挂针对的是中断标志位,也可以叫做允许中断发生的位。
获取中断状态的函数
函数原型
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
函数应用
uint32_t IterruptFlag = NVIC_GetPendingIRQ(USART1_IRQn);
// 这个函数获取了串口1中断的状态
清除/设置中断标志位的函数
函数原型
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
函数使用
NVIC_SetPendingIRQ(USART1_IRQn);
NVIC_ClearPendingIRQ(USART1_IRQn);
针对于中断标志位的操作有什么用?
1、一般来说单片机的中断发生有两个条件,一是中断标志位置位,二是中断允许,如果这两个条件都满足则进入中断,因为正常情况下中断一直是允许的,那么只能通过标志位来区分是否有中断挂起;
2、如果进入中断不清除标志位,那么这一中断服务程序结束后由于标志位还是置位的并且中断是允许的,那么还会再次进入该中断,就会发生一直在执行中断程序的情况。
举例说明
在A中断中设置B中断的中断标志位为1,那么当B中断条件满足时,B中断可以发生,但是如果清除A中B中断标志位,那么无论是否满足触发B中断的条件,A中断中永远不可能执行B中断,因为中断发生的条件是:“中断标志位有效+中断条件满足”。
上一篇: 如何防止IE缓存jsp文件