您现在的位置是:首页 >技术杂谈 >stm32的如何开启外部中断(仅仅是个人理解)网站首页技术杂谈

stm32的如何开启外部中断(仅仅是个人理解)

chen_learning_star 2025-03-22 12:01:03
简介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号线的中断标志位
													//中断标志位必须清除
													//否则中断将连续不断地触发,导致主程序卡死
	}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。