【STM32】NVIC嵌套中断向量控制器与外部中断
两种优先级
抢占优先级PreemptPriority:中断服务函数正在执行时,抢占优先级高的可以打断抢占优先级低的,实现中断的嵌套,相当于51的“高优先级”
响应优先级(子优先级)SubPriority:抢占优先级相同的情况下,当两个中断同时被触发时,为避免中断的阻塞,高响应优先级的中断源会被优先触发,但高响应优先级不能打断低相应优先级,相当于51的“自然优先级”
特性:数字越小优先级越高,其中Reset,Hard fault,NMI优先级为负数且不可变,高于普通的中断优先级
优先级组的配置
简述:每个可屏蔽中断都有对应的优先级寄存器IP,例如F429有91个可屏蔽中断,对应IP[0]~IP[90],对于M3/4/7的内核,IP有八位,可设置2^8 = 256级优先级,但ST只用了高四位[7:4],可以实现2^4 = 16级优先级,由于存在两类优先级,因此需要将这四位分给两个优先级用于配置优先级别,我们将不同的分分配方式成为优先级分组(NVIC_PriorityGroup),由寄存器SCB->AIRCR的10~8bit控制
API:HAL_NVIC_SetPriorityGrouping(NVIC_PriorityGroup_n)
以上函数出现在HAL_Init() 中,用于对优先级分组进行设定,n = 0~4
例如:HAL_NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2)//采用优先级分组2
优先级的设定
API:void HAL_NVIC_SetPriority(IRQn_Type IRQn,//中断号,此处由枚举IRQn_Type映射
uint32_t PreemptPriority,//抢占优先级
uint32_t SubPriority)//响应优先级(子优先级)
例如:HAL_NVIC_SetPriority(TIM3_IRQn,1,3);
void HAL_NVIC_EnableIRQ(IRQn_Tpye IRQn) //中断使能,同样由Disable,不赘述
例如:HAL_NVIC_EnableIRQ(TIM3_IRQn);
外部中断的实现(函数命明参考MX生成代码)
初始化:void MX_GPIO_Init(void)
进行GPIO的初始化配置,注意虽然是写外部中断,GPIO这一中断源的配置一样都不能少!区别与一般输出功能的GPIO,外部中断功能的Mode(为触发方式)有所不同,完成GPIO特性的配置后设置外部中断优先级并使能,至此初始化完成
触发时:void EXTI1_IRQHandler(void)
初始化完成之后,单片机开始运行main函数内容,同时等待中断的触发,一旦中断触发,程序将指向上述的中断服务函数,这一中断服务函数的作用主要时给总的外部中断Handler的GPIO_Pin赋值,以下为中断服务函数的内容,相当于将所有的外部中断都汇总到了这个HAL_GPIO_EXTI_IRQHandler(),不同的中断服务函数只负责传入不同的GPIO_Pin值
void EXTI3_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); }
回调:这个总的Handler的内容同样简单,首先清除对应GPIO_Pin的中断标志,接着执行公用的HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)中断回调函数,至此外部中断完成,而由于Callback函数是弱函数,即假设用户重新定义了该函数,编译器不会报Redefine,而是拿用户定义的内容把原先的覆盖掉,HAL大量采用这种写法,使得编写这些函数非常方便,只需要在main.c重新定义该函数的内容即可(实际上HAL库是只读的,对Callback的弱定义也是不可修改)由于Callback是公用的,因此需要在里面设置逻辑判断是什么中断源,done
参考:安富莱_STM32-V5开发板_用户手册,含BSP驱动包设计(V1.7).pdf
正点原子STM32F429开发指南-HAL库版本_V1.1.pdf
2021/7/20 18:35
LynnSX in HRB