您现在的位置是:首页 >技术杂谈 >stm32的如何开启外部中断(仅仅是个人理解)网站首页技术杂谈
stm32的如何开启外部中断(仅仅是个人理解)
简介stm32的如何开启外部中断(仅仅是个人理解)
开启时钟
一个简单的中断配置图,大致表达了开启中断所需要的步骤:
对于外部中断,我们需要开启的内容较多,相当于自己去完整的配置一个中断
AFIO
时钟
//AFIO(替代功能输入输出)可以改变一些引脚的作用
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO
时钟
//假设我们选择GPIOB的14引脚作为外部中断源,对应开启的是GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
初始化
开启时钟之后开始初始化GPIO口与初始化中断
AFIO
发挥作用
/*AFIO选择中断引脚*/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚
初始化GPIO
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //推荐设置为上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB14引脚初始化为上拉输入
初始化EXTI
/*EXTI初始化*/
EXTI_InitTypeDef EXTI_InitStructure; //定义结构体变量
//选择配置外部中断的14号线(注意开启GPIOB的14号线后GPIOA的14号线是不能同时作用的)
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
//指定外部中断线使能
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//指定外部中断线为中断模式EXTI_Mode_Interrupt(中断触发),EXTI_Mode_Event(事件触发)
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//指定外部中断线为下降沿触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
初始化NVIC
有关优先级分组、抢占优先级、响应优先级可以参考作者DuHz
的文章
链接: stm32优先级略
/*NVIC中断分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2
//即抢占优先级范围:0~3,响应优先级范围:0~3
//此分组配置在整个工程中仅需调用一次
//若有多个中断,可以把此代码放在main函数内,while循环之前
//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置
/*NVIC配置*/
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择配置NVIC的EXTI15_10线
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1
NVIC_Init(&NVIC_InitStructure); //将结构体变量交给NVIC_Init,配置NVIC外设
中断处理函数
//因为是一个有多个中断都可以触发的函数,所以需要判断一下
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line14) == SET) //判断是否是外部中断14号线触发的中断
{
//处理逻辑在此处
EXTI_ClearITPendingBit(EXTI_Line14); //清除外部中断14号线的中断标志位
//中断标志位必须清除
//否则中断将连续不断地触发,导致主程序卡死
}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。