NVIC中断优先级管理
什么是NVIC
NVIC即嵌套向量中断控制器(Nested Vectored Interrupt Controller).STM32中有一个强大而方便的NVIC,它是属于CM3内核的器件。NVIC是嵌套向量中断控制器,控制着芯片中断相关的功能,他跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对CM3内核里面的NVIC进行剪裁,把不需要的部分去掉,所以说STM32的NVIC是CM3的NVIC的一个子集。CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但是STM32并没有使用CM3内核的全部东西,而是只用了它的一部分呢。STM32F103xe芯片有70个中断,包括10个内核中断和60个可屏蔽中断,具有哦16级可编程的中断优先级,我们常用的就是这60个可屏蔽中断。
中断优先级
STM32中有两个优先级的概念:抢占式优先级和响应优先级,响应优先级也称子优先级,每个中断源都需要被指定这两种优先级。具有高抢占式优先级的中断可以在具有低抢占优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式的优先级中断中,当两个中断源的抢占式优先级相同时。这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等前一个中断处理完才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级的高低来决定先处理哪一个;如果他们的抢占优先级和响应优先级都相同,则根据他们在中断向量表中排位顺序来决定处理哪一个。
优先级分组
优先级的分组由内核外设SCB的应用程序中断及复位控制寄存器AIRCR的PRIGROUP【10:8】位决定,有五个可选分组
我们就可以清楚的看到组0—4对应的配置关系,例如组设置为2,那么此时所有的60个中断,每个中断优先寄存器的高四位中的最高两位式抢占优先级,低2位是响应优先级。每个中断,你可以设置抢占优先级0—4,响应优先级也可设置为0—4。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
举例
假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1.中断6(外部中断0)的抢占优先级为3,响应优先级为0.中断7(外部中断1)的抢占优先级为2,响应优先级为0.
那么这3个中断的优先级顺序为:中断7>中断3>中断6.
NVIC中断HAL库函数介绍
中断操作HAL库函数分布文件
头文件:stm32f1xx_hal_cortex.h
源文件:stm32f1xx_hal_cortex.c
重要函数
设置中断优先级分组
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
设置中断优先级
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup = 0x00;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
使能中断
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Enable interrupt */
NVIC_EnableIRQ(IRQn);
}
禁止中断
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Disable interrupt */
NVIC_DisableIRQ(IRQn);
}
系统复位
void HAL_NVIC_SystemReset(void)
{
/* System Reset */
NVIC_SystemReset();
}
特别说明
星光嵌入式STM32开发板的相关外设的中断服务函数,是分别放在相应的外设驱动的。