STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。4bit的中断优先级可以分成2组,从高位看,前面定义的是抢占式优先级,后面是响应优先级。按照这种分组,4bit一共可以分成5组:
第0组:所有4bit用于指定响应优先级;
第1组:最高1位用于指定抢占式优先级,后面3位用于指定响应优先级;
第2组:最高2位用于指定抢占式优先级,后面2位用于指定响应优先级;
第3组:最高3位用于指定抢占式优先级,后面1位用于指定响应优先级;
第4组:所有4位用于指定抢占式优先级。
所谓抢占式优先级和响应优先级,他们之间的关系是:具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个。如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个,每一个中断源都必须定义2个优先级。
GPIO 外部中断:
STM32中,每一个GPIO都可以触发一个外部中断,但是GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。比如说PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能够再使用了,我们只能使用类似于PB1,PC2这种末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0-EXTI4这5个外部中断有着自己的单独的中断响应函数,EXTI5-9共用一个中断响应函数,EXTI10-15共用一个中断响应函数。
GPIO 外部中断配置步骤:
1. 设置相应的时钟;
void RCC_config()
{
//打开PE PD PC PB端口时钟,并且打开复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
}
2. 设置相应的中断;
void NVIC_config()
{
NVIC_InitTypeDefNVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择中断分组2
NVIC_InitStructure.NVIC_IRQChannel= EXTI2_IRQChannel; //选择中断通道2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0; //抢占式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0; //响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure);
}
3. IO口初始化;
void GPIO_config()
{
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; //选择引脚2
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //输出频率最大50MHz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //带上拉电阻输出
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_ResetBits(GPIOE,GPIO_Pin_2); //将PE.2引脚设置为低电平输出
}
4. 把相应的IO口设置为中断线路(要在设置外部中断之前)并初始化;
void EXTI_config()
{
EXTI_InitTypeDefEXTI_InitStructure;//清空中断标志
EXTI_ClearITPendingBit(EXTI_Line2);//选择中断管脚PC.2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line= EXTI_Line2; //选择中断线路2
EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt; //设置为中断请求,非事件请求
EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Rising_Falling; //设置触发方式上下边沿触发
EXTI_InitStructure.EXTI_LineCmd=ENABLE; //外部中断使能
EXTI_Init(&EXTI_InitStructure);//初始化中断
}
5. 在选择的中断通道的响应函数中中断函数
voidEXTI2_IRQHandler(void)
{
GPIO_SetBits(GPIOD,GPIO_Pin_6); //点亮LED灯
EXTI_ClearITPendingBit(EXTI_Line2); //清空中断标志位,防止持续进入中断
}