关于外部中断的初始化代码简介

中断与定时器一直是stm32中非常重要的两部分,今天先简单介绍一下有关中断中外部中断的使用。下面直接开始代码部分,而原理会在代码部分一起讲解。

中断的使用需要初始化,不妨写一个初始化函数名为void CountSensor_Init(void),用于存放外部中断的初始化。

以启用GPIOB,Pin14为外部中断引脚为例。

事实上,启用外部中断的顺序就是从启动GPIO、AFIO、EXTI、NVIC顺序导通,依次配置即可。

配置GPIO初始化如下:

void RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//配置时钟使能

GPIO_InitTypeDef GPIO_InitStructure;//定义名为GPIO_InitStructure的结构体变量

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//配置成上拉输入模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;//由原理图配置PB14口
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度一般设置成50MHZ即可
GPIO_Init(GPIOB, &GPIO_InitStructure);//对GPIO进行初始化

通过以上配置,GPIOB Pin14口便彻底完成了初始化,通过以上的流程图,我们还需要再进行配置以下AFIO寄存器,AFIO配置较为简单,打开时钟即可。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

接下来我们进行EXTI外部中断的初始化。而EXTI与NVIC属于系统的基本功能模块,与系统时钟(HSI、HSE等)一同启动并在运行时自动工作,因此无需配置时钟。

选用函数GPIO_EXTILineConfig();用于配置EXTI外部中断通道,由于我们选择的是GPIOB Pin14,所以配置函数为:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

下面操作与GPIO结构体类似,在此不作赘述

EXTI_InitTypeDef EXTI_InitStructrue;//定义名为EXTI_InitStructrue的结构体变量
EXTI_InitStructrue.EXTI_Line = EXTI_Line14;//通道14
EXTI_InitStructrue.EXTI_LineCmd = ENABLE;//使能
EXTI_InitStructrue.EXTI_Mode = EXTI_Mode_Interrupt;//中断而非事件
EXTI_InitStructrue.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发

EXTI_Init(&EXTI_InitStructrue);//EXTI初始化

下面开始配置NVIC

先进行配置NVIC优先组,因为本次代码较为简单,没有过多的中断冲突,因此分组可以比较随意,这里设置为级别2,采用函数NVIC_PriorityGroupConfig();配置为:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

从stm32官方库中我们可以得知组2的优先级分组为

即两位用于抢占优先级,两位用于子优先级。

接下来也是配置NVIC的结构体,配置如下

NVIC_InitTypeDef NVIC_InitStructrue;//定义名为NVIC_InitStructrue的结构体变量
        
NVIC_InitStructrue.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructrue.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级与从优先级级别相同时不会发生中断嵌套,这里我们不需要中断嵌套,设置级别相同即可
NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 1;
        
NVIC_Init(&NVIC_InitStructrue);//NVIC初始化

以上,整个外部中断的初始化配置就算完成了,完整代码如下:

void CountSensor_Init(void)
{
		
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	/*EXIT与NVIC不需要开启时钟*/
		
		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);

		GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
		EXTI_InitTypeDef EXTI_InitStructrue;
	 	EXTI_InitStructrue.EXTI_Line = EXTI_Line14;
	  EXTI_InitStructrue.EXTI_LineCmd = ENABLE;
	  EXTI_InitStructrue.EXTI_Mode = EXTI_Mode_Interrupt;
	  EXTI_InitStructrue.EXTI_Trigger = EXTI_Trigger_Falling;
	
		EXTI_Init(&EXTI_InitStructrue);
		
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
		
		NVIC_InitTypeDef NVIC_InitStructrue;
		
		NVIC_InitStructrue.NVIC_IRQChannel = EXTI15_10_IRQn;
		NVIC_InitStructrue.NVIC_IRQChannelCmd = ENABLE;
		NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 1; 
		NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 1;
		
		NVIC_Init(&NVIC_InitStructrue);
}

初始化完成后,就可以编写中断服务函数了。而中断函数不可以随意起名,这时我们就可以打开启动文件,我的文件名是startup_stm32f10x_md.s,打开后找到EXTI15_10_IRQHandler函数,而这里选择EXTI15是因为通道10~15都被放在了这个中断函数之中,而我们的通道14自然也是用这个函数。

找到中断函数后,我们首先需要判断是否程序进入了中断,通过调用EXTI_GetITStatus()中断标志位函数是否置1来判断是否进入了中断

if(EXTI_GetITStatus(EXTI_Line14) == SET)
{



}

随后,务必要记得进入一次中断服务程序后要清除标志位,否则程序会一直卡死在中断程序里面无法出去。实现这一操作调用的是EXTI_ClearITPendingBit()函数。完整中断服务函数程序如下:

void EXTI15_10_IRQHandler(void)
{
		if(EXTI_GetITStatus(EXTI_Line14) == SET)
		{
					
		
				EXTI_ClearITPendingBit(EXTI_Line14);
		}


}

同时,中断服务函数不需要在.h文件中进行声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值