本例示范了如何使用嵌套向量中断控制器(Nested Vectored Interrupt Controller)来设置各个中断的优先级(Preemption Priority和SubPriority)。
设置2条外部中断线路(线路3和线路4)在每一个输入信号下降沿产生中断,开启SysTick中断。
这3个中断的优先级设置如下:
EXTI Line3: PreemptionPriority = PreemptionPriorityValue
SubPriority = 0
EXTI Line4: PreemptionPriority = 0
SubPriority = 1
SysTick Handler: PreemptionPriority = !PreemptionPriorityValue
SubPriority = 0
初始时,PreemptionPriorityValue的值为0,这意味着外部中断线路3(EXTI Line3)有着比SysTick中断更高的优先级。
在外部中断线路4的中断中,程序交换EXTI Line和SysTick中断的优先级。
- /*******************************************************************************
- * Function Name : EXTI4_IRQHandler
- * Description : This function handles External interrupt Line 4 request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void EXTI4_IRQHandler(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
-
- if(EXTI_GetITStatus(EXTI_Line4) != RESET)
- {
- PreemptionPriorityValue = !PreemptionPriorityValue;
- PreemptionOccured = FALSE;
- /* Modify the EXTI3 Interrupt Preemption Priority */
- NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
- NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, !PreemptionPriorityValue, 0);
-
- /* Clear EXTI Line4 pending bit */
- EXTI_ClearITPendingBit(EXTI_Line4);
- }
- }
在外部中断线路3的中断中,程序设置SysTick中断的pending比特,这样,如果SysTick中断的优先级较高,他就会被打断,反之则不会。
- /*******************************************************************************
- * Function Name : EXTI3_IRQHandler
- * Description : This function handles External interrupt Line 3 request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void EXTI3_IRQHandler(void)
- {
- /* Generate SysTick exception */
- NVIC_SetSystemHandlerPendingBit(SystemHandler_SysTick);
- /* Clear EXTI Line3 pending bit */
- EXTI_ClearITPendingBit(EXTI_Line3);
- }
在SysTick中断中,程序检查是否中断是由打断外部中断线路3的中断进入的,如果是,把PreemptionOccured的值置为True。
- /*******************************************************************************
- * Function Name : SysTickHandler
- * Description : This function handles SysTick Handler.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void SysTickHandler(void)
- {
- /* If the EXTI3 IRQ Handler was preempted by SysTick Handler */
- if(NVIC_GetIRQChannelActiveBitStatus(EXTI3_IRQChannel) != RESET)
- {
- PreemptionOccured = TRUE;
- }
- }
当PreemptionOccured的值不为False时,连接在PC.04 – PC.07上的4个LED开始闪耀。
- while (1)
- {
- if(PreemptionOccured != FALSE)
- {
- GPIO_WriteBit(GPIOC, GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_4)));
- Delay(0x5FFFF);
- GPIO_WriteBit(GPIOC, GPIO_Pin_5, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_5)));
- Delay(0x5FFFF);
- GPIO_WriteBit(GPIOC, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6)));
- Delay(0x5FFFF);
- GPIO_WriteBit(GPIOC, GPIO_Pin_7, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7)));
- Delay(0x5FFFF);
- }
- }
综上所述,运行程序结果如下:
刚下载进去程序,按key2是不会有LED闪耀的,因为SysTick中断的优先级比外部中断线路3优先级低,如果先按key3,交换EXTI Line和SysTick中断的优先级,则再按key2时候PreemptionOccured的值被置为True,LED闪耀。再次按key3的话,又交换一次,SysTick中断的优先级变低,key2的中断不会被被SysTick中断打断,4个LED停止闪耀。
1. 当第一次外部中断线路4的中断发生后,SysTick中断的优先级变得比外部中断线路3的优先级高,因此,一旦发生外部中断线路3的中断,它将被SysTick中断打断,PreemptionOccured的值被置为True,4个LED开始闪耀。
2. 再次发生外部中断线路4的中断,PreemptionOccured的值被置回False,SysTick中断的优先级变得比外部中断线路3的优先级低,因此,一旦发生外部中断线路3的中断,它不会被SysTick中断打断,4个LED停止闪耀。
以上2种情况会循环发生。
阅读(9759) | 评论(0) | 转发(1) |