STM32 EXTI外部中断及NVIC的抢占优先级和响应优先级解释

1、中断类型

从之前的串口实验可以看出,STM32总共分为内部中断和外部中断,内部和外部的配置差别不是很大,外部中断只是多了一步,需要通过
GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)函数(在stm32f10x_gpio.h里面)
将外部中断源挂载到中断线上即可。

2、外部中断配置过程

1、开时钟(必须开启复用时钟)
2、初始化用到的GPIO口
3、将使用到的GPIO口挂载到中断线上 GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)函数
4、配置EXTI_Init() //中断线,中断的类型、触发方式
5、配置NVIC_Init() //中断优先级
6、编写中断服务函数

3、外部中断的主要配置说明

1)NVIC
外部出现满足中断条件,开始执行中断服务函数,如同时出现多个中断,则根据NVIC设定的优先级开始执行中断函数。
NVIC分组分析:NVIC的库函数和结构体定义都在misc文件中。
NVIC的分组分为两组,但优先级总数不变,均为16组,并且编号越小,优先级越高

============================================================================================================================
    NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  | Description
  ============================================================================================================================
   NVIC_PriorityGroup_0  |                0                  |            0-15             |   0 bits for pre-emption priority
                         |                                   |                             |   4 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------
   NVIC_PriorityGroup_1  |                0-1                |            0-7              |   1 bits for pre-emption priority
                         |                                   |                             |   3 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------    
   NVIC_PriorityGroup_2  |                0-3                |            0-3              |   2 bits for pre-emption priority
                         |                                   |                             |   2 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------    
   NVIC_PriorityGroup_3  |                0-7                |            0-1              |   3 bits for pre-emption priority
                         |                                   |                             |   1 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------    
   NVIC_PriorityGroup_4  |                0-15               |            0                |   4 bits for pre-emption priority
                         |                                   |                             |   0 bits for subpriority                       
  ============================================================================================================================

这里解释一下中断优先级分组是什么意思,有什么作用
第二列:NVIC_IRQChannelPreemptionPriority 抢占优先级
第三列:NVIC_IRQChannelSubPriority 响应优先级
(1)抢占优先级:指此中断的抢占能力,抢占优先级越高,则此中断就可以打断优先级低的函数,这样就会出现中断的嵌套。①两个抢占优先级一样的中断同时到达,那么就会比较响应优先级,越高越先反应;②两个抢占优先级一样的中断不同时到达,无关响应优先级,前一中断不会被打断,直到执行完前一中断,才会执行后一个中断。
(2)响应优先级:同时到达的中断的响应先后。两个抢占优先级一样的中断同时到达,那么就会比较响应优先级,越高越先反应。

2)中断服务函数
中断服务函数已经在“startup_stm32f10x_hd.s”中的264-323行声明,需要哪种中断直接去找即可。在配置EXTI时使用的中断线是哪一条,那么中断服务函数就选择哪一个。
个人建议所有的中断服务函数写在“stm32f10x_it.c”中,然后在原本设置的.c文件里面打一个备注,这样中断服务函数一目了然,在各个子程序里面也可以看到备注。

4、代码示例

/*
*main.c中需要添加
*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级	
	LED_Init();
	KEY_Init();   	
	EXTI_Config();	
/*
*EXTI 和 NVIC 配置函数
*/
void EXTI_Config(void)
{
    
    
	EXTI_InitTypeDef	EXTI_InitStructure;
	NVIC_InitTypeDef	NVIC_InitStructure;
	
	KEY_Init();//先配置需要用到的按键
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//一定要开启复用时钟
	
//KEY1 PE3 	上升沿	优先级2 1
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
	EXTI_InitStructure.EXTI_Line = EXTI_Line3;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_Init(&EXTI_InitStructure);	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}
/*
*中断服务函数
*/
//KEY1 中断服务函数
void EXTI3_IRQHandler(void)
{
    
    
	delay_ms(10);//消抖
	if(KEY1 == 1)
	{
    
    
		LED1 = !LED1;
	}
	EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位  
}

猜你喜欢

转载自blog.csdn.net/qq_44011116/article/details/112787836