外部中断配置和操作(中断优先级分组)

来源:互联网 发布:于海文基督教网络歌曲 编辑:程序博客网 时间:2024/06/05 08:12

中断线

        STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。

STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。

 

中断线与IO对应关系   

        GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 15~0。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、 GPIOF.0、 GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。

 

*中断优先级分组问题(个人理解)

         STM32的中断优先级管理十分优越。首先,优先级分为两种:1、抢占优先级。2、响应优先级。这里需要说明的是抢占优先级可以打断响应优先级。设中断线0的抢占优先级为1(数值越小优先级越高),响应优先级为1 。同样设中断线1的抢占2,、响应0 。那么中断0可以打断中断1的服务函数。而响应优先级的意思是,2个中断请求同时到来的时候优先执行哪一个(响应优先级决定)。但是如果低优先级中断先执行,高优先级中断到来以后必须等待低优先级执行完毕再执行(这种情况是抢占优先级一致)。总结例子,就是抢占决定中断是否能打断别的中断,而响应决定同时触发中断时的优先级(不可打断)。新手需注意的是,抢占和响应优先级设置是一个中断中同时设置的,并不是一个中断可以设置给抢占,另一个设置给响应。

结合表格4.5.1,优先级分组可以设置成0~4组。0~4位的意思是0~4位二进制。如3位为111=7,1位为1=1.即3组中,可设置0~7的抢占优先级,0~1的响应优先级。这个设置是应用与整个工程的,需要在项目开头设置。

 

如在原子stm32自带开发代码中,在sys.c中有如下设置:

void NVIC_Configuration(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置 NVIC 中断分组 2:2 位抢占//优先级,2 位响应优先级 0-3}

 

中断服务函数

需要说明一下,STM32 的 IO 口外部中断函数只有 6 个,分别为:

EXPORT   EXTI0_IRQHandler         
EXPORT   EXTI1_IRQHandler      
EXPORT   EXTI2_IRQHandler        
EXPORT   EXTI3_IRQHandler       
EXPORT   EXTI4_IRQHandler         
EXPORT   EXTI9_5_IRQHandler       
EXPORT   EXTI15_10_IRQHandler     

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中断线 10-15 共用中断函数 EXTI15_10_IRQHandler。

在编写中断服务函数的时候会经常使用到两个函数,第一个函数是判断某个中断线上的中断是否发生(标志位是否置位) :
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
这个函数一般使用在中断服务函数的开头判断中断是否发生。

 

另一个函数是清除某个中断线上的中断标志位:
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
这个函数一般应用在中断服务函数结束之前,清除中断标志位。

 

下面给出配置步骤和例子:

使用 IO 口外部中断的一般步骤:
1)初始化 IO 口为输入。
2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
3)初始化线上中断,设置触发条件等。
4)配置中断分组(NVIC),并使能中断。
5)编写中断服务函数。

void EXTIX_Init(void){EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;KEY_Init();    //  按键端口初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//GPIOE.2  中断线以及中断初始化配置   下降沿触发GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);EXTI_InitStructure.EXTI_Line=EXTI_Line2;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);    //根据指定的参数初始化中断线参数NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能按键外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;  //抢占优先级 2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;      //子优先级 2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    //使能外部中断通道NVIC_Init(&NVIC_InitStructure);}//外部中断 2 服务程序void EXTI2_IRQHandler(void){delay_ms(10);//消抖if(KEY2==0 && EXTI_GetITStatus(EXTI_Line2)!=RESET)    //按键 KEY2{LED0=!LED0;}   EXTI_ClearITPendingBit(EXTI_Line2);   //清除 LINE2 上的中断标志位 }


结构体相关配置参数可查询库函数手册。记得开启RCC IO复用时钟哦~按键方面的配置实用正常的上下拉即可。


 


 

 

0 0