2022-3-9 stm32mini 库函数 外部中断实验-EXTI 学习笔记

目录

外部中断实现的功能:

编写外部中断初始化函数

1)初始化 IO 口为输入。

2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。

3)初始化线上中断,设置触发条件等。

4)配置中断分组(NVIC),并使能中断。

外部中断初始化函数完整代码

编写服务函数

exti.c中完整代码为:

main.c中完整代码​​​​​​​


这章的代码主要分布在固件库的 stm32f10x_exti.h 和 stm32f10x_exti.c 文件中,但中断线及中断初始化配置文件在stm32f10x_gpio.h 和 stm32f10x_gpio.c中 。

外部中断实现的功能:

利用key按键,中断控制led灯。

KEY1对LED1取反

KEY0对LED0取反

WK UP对LED1和LED0同时取反

建立工程文件

工程文件如下:

 

编写外部中断初始化函数

1)初始化 IO 口为输入。


void EXTIX_Init(void)
{
  KEY_Init();//初始化io口

}

2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。

例如我们要用的WK UP对应串口为PA0,则函数中对应变量填(GPIO_PortSourceGPIOA,GPIO_PinSource0)

 当我们要利用其他key时,这行代码只需更改红色部分即可。


  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//中断线0

3)初始化线上中断,设置触发条件等。

 EXTI_InitTypeDef EXTI_InitStructure;//定义结构体变量
 EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断线0,与GPIO中相同
 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//模式
 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
 EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器

4)配置中断分组(NVIC),并使能中断。

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化

外部中断初始化函数完整代码

void EXTIX_Init(void)
{
  KEY_Init();//初始化io口

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);//中断线0

  EXTI_InitTypeDef EXTI_InitStructure;//定义结构体变量
  EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断线0,与GPIO中相同
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
  EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器

  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化

}

编写服务函数

void EXTI0_IRQHandler(void)
{
  delay_ms(10);    //延时函数
	if(WK_UP==1)
	{	  
		LED0=!LED0;
		LED1=!LED1;	
	}
	EXTI_ClearITPendingBit(EXTI_Line0);  //手动清除挂起位
}

这里需要说明一下,中断服务函数的名字是 在 MDK 中事先有定义的。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。

此时,我们的exti.c文件中的代码为:

#include "exti.h"

void EXTIX_Init(void)
{
  KEY_Init();//初始化io口

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//中断线0

  EXTI_InitTypeDef EXTI_InitStructure;//定义结构体变量
  EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断线0,与GPIO中相同
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
  EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器

  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化

}
void EXTI0_IRQHandler(void)
{
  delay_ms(10);    //延时函数
	if(WK_UP==1)
	{	  
		LED0=!LED0;
		LED1=!LED1;	
	}
	EXTI_ClearITPendingBit(EXTI_Line0);  //手动清除,确保下次能进入中断服务函数
}

按照以上方法,只需更改gpio口和中断线序号,就可以设置其他的服务函数;

exti.c中完整代码为:

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"


 
 
//外部中断初始化函数
void EXTIX_Init(void)
{
 
 	  EXTI_InitTypeDef EXTI_InitStructure;//定义结构体变量,一遍即可
 	  NVIC_InitTypeDef NVIC_InitStructure;

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断使能AFIO时钟
	  KEY_Init();//初始化io口

    //GPIOC.5 中断及中断初始化设置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line5;//中断线5,与GPIO中相同
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	//模式
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
  	EXTI_Init(&EXTI_InitStructure);	 	//根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器
	
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;			//使能按键外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级 2
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级 1
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 

    //GPIOA.15	  中断及中断初始化设置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line15;  //中断线15,与GPIO中相同
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	//模式
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
  	EXTI_Init(&EXTI_InitStructure);	  	//根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器
		
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;		//使能按键外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级 2
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级 0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); //GPIOA.0中断及中断初始化设置

  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

   	EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);		//根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器


 
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级 2
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级 2
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据参数设置寄存器
		
		
 
 
   	
 
}

 
void EXTI0_IRQHandler(void)
{
  delay_ms(10);    //消抖	 
	if(WK_UP==1)
	{	  
		LED0=!LED0;
		LED1=!LED1;	
	}
	EXTI_ClearITPendingBit(EXTI_Line0); //手动清除,确保下次能进入中断服务函数
}
 void EXTI9_5_IRQHandler(void)
{			
	delay_ms(10);   //消抖	 			 
	if(KEY0==0)	{
		LED0=!LED0;
	}
 	 EXTI_ClearITPendingBit(EXTI_Line5);    //手动清除,确保下次能进入中断服务函数  
}


void EXTI15_10_IRQHandler(void)
{
  delay_ms(10);    //消抖	 
  if(KEY1==0)	{
		LED1=!LED1;
	}
	 EXTI_ClearITPendingBit(EXTI_Line15);  //手动清除,确保下次能进入中断服务函数
}

接下来编写主函数

main.c中完整代码

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "exti.h" 

int main(void)
 {	
 
	delay_init();	    	 //延时函数初始化	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 中断优先级2
	uart_init(9600);	 //设置波特率为9600
	LED_Init();		  	 //led串口初始化
 	EXTIX_Init();		//中断初始化
    LED0=0;				//点亮LED
	while(1)
	{	    
		printf("OK\n");	
		delay_ms(1000);	  
	} 
}

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值