stm32 外部中断程序(标准库)

stm32 外部中断程序(标准库)

还不知道外部中断是什么的同学可以看看以下资料
STM32 外部中断详解(原理+配置代码)
深入讲解STM32中断

EXTI的初始化方法

1.在HARDWARE创建EXTI的头文件和源文件,用来写我们的中断配置程序
在这里插入图片描述
包含常用的头文件
在这里插入图片描述
2.创建EXTI的初始化函数,在函数中定义NVIC 和 EXTI 结构体
在这里插入图片描述
3.按键对应的IO口初始化
使能SYSCFG时钟,使用APB2总线复用功能
在这里插入图片描述
4.中断线以及中断初始化初始化配置
在这里插入图片描述
在这里插入图片描述
这段代码是用于配置外部中断线(EXTI)的。库函数SYSCFG_EXTILineConfig来配置外部中断线。

EXTI_PortSourceGPIOC表示将外部中断线连接到GPIOC端口,
EXTI_PinSource13表示将外部中断线连接到GPIOC的第13引脚(PA13)
具体来说,这段代码将以下引脚连接到外部中断线:

  1. GPIOC的第11引脚(PA11)连接到中断线11。
  2. GPIOC的第12引脚(PA12)连接到中断线12。
  3. GPIOC的第13引脚(PA13)连接到中断线13。
  4. GPIOA的第0引脚(PA0)连接到中断线0。
    这些引脚被配置为外部中断源,当对应的引脚上的电平发生变化时,会触发相应的中断事件

5.配置EXTI_Line0的结构体
在这里插入图片描述
这段代码是用于配置STM32的外部中断(EXTI)的初始化结构体。

  • EXTI_InitStructure.EXTI_Line = EXTI_Line0;:将外部中断线设置为LINE0。
  • EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;:设置外部中断模式为中断事件模式。
  • EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;:设置触发方式为上升沿触发。
  • EXTI_InitStructure.EXTI_LineCmd = ENABLE;:使能外部中断线。
  • EXTI_Init(&EXTI_InitStructure);:使用初始化结构体进行外部中断的配置。

这段代码的作用是配置STM32的外部中断,当GPIOC的第13引脚上的电平从低变高时,会触发一个中断事件。

在这里插入图片描述
同理继续配置EXTI_Line2,3,4

6.定义NVIC的结构体
在这里插入图片描述
这段代码是用于配置两个外部中断的初始化结构体(注意:只有EXTI0~4有独立的中断向量,5 ~ 9和 10 ~ 15共享中断向量EXTI9_5_IRQn和EXTI15_10_IRQn,),并使能这两个中断通道。具体解释如下:

  1. 第一个外部中断(EXTI0)的配置:

    • NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;:设置中断通道为EXTI0。
    • NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;:设置抢占优先级为0。
    • NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;:设置响应优先级为3。
    • NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;:使能外部中断通道。
    • NVIC_Init(&NVIC_InitStructure);:调用NVIC_Init函数进行配置。
  2. 第二个外部中断(EXTI15_10)的配置:

    • NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;:设置中断通道为EXTI15_10。
    • NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;:设置抢占优先级为0。
    • NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;:设置响应优先级为2。
    • NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;:使能外部中断通道。
    • NVIC_Init(&NVIC_InitStructure);:调用NVIC_Init函数进行配置。

EXTI初始化的完整代码

void EXTIX_Init(void)
{
	//定义NVIC 和 EXTI 结构体
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	

	KEY_Init(); //按键对应的IO口初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
	
 
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource11);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource12);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
	
  /* 配置EXTI_Line0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
  EXTI_Init(&EXTI_InitStructure);//配置
	
	/* 配置EXTI_Line2,3,4 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line11 | EXTI_Line12 | EXTI_Line13;
  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 = EXTI0_IRQn;//外部中断0
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级为0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;//响应优先级为3
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);//配置
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//外部中断2
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);//配置

}

编写中断服务函数

void EXTI0_IRQHandler(void)	//中断服务程序
{
	delay_ms(20);	//消抖
	if(KEY_UP==1)	 
	{
		LED1=!LED1; 
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位 
}	

void EXTI0_IRQHandler(void): 这是中断服务程序的函数原型,表示该函数是用于处理外部中断0的中断事件,在函数中写上我们需要执行的程序即可。

EXTI_ClearITPendingBit(EXTI_Line0);: 这行代码调用了EXTI_ClearITPendingBit函数,用于清除外部中断0上的中断标志位。这样可以避免重复触发中断

在main的编写

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	
	delay_init(168);
	LED_Init();
	EXTIX_Init();
	while(1);
}

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)用于设置系统中断优先级分组为2,两位抢占优先级,两位响应优先级
之后在调用我们项目相关功能的初始化函数即可,可见在使用外部中断时我们在主函数编写的代码是非常少的,相关功能实现的代码基本放在中断服务函数中

还有就是如果我们需要快速屏蔽一个中断源可以这么写

EXTI->IMR |= EXTI_Line14; //使能外部中断14
EXTI->IMR &= ~(EXTI_Line14); //屏蔽外部中断14

中断屏蔽寄存器EXTI->IMR

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
STM32标准库中,可以使用GPIO外部中断模块的中断检测功能来实现按键的消抖。具体步骤如下: 1. 初始化GPIO外部中断模块,配置外部中断引脚,设置中断触发方式(上升沿、下降沿或者双边沿触发等)。 ```c GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 配置GPIO引脚为输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置外部中断线路 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_Falling; // 双边沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // 配置NVIC中断优先级 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ``` 2. 在中断服务函数中添加按键消抖处理代码。可以使用计时器或者延时等方式来实现消抖,以下示例使用计时器实现。 ```c void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 消抖处理 if (time_now - time_last > 10) // 判断两次中断时间差是否大于10ms { // 处理按键事件 // ... time_last = time_now; // 记录上一次中断时间 } EXTI_ClearITPendingBit(EXTI_Line0); } } ``` 在上述示例代码中,变量`time_now`和`time_last`分别表示当前时间和上一次中断时间,通过比较两者的时间差是否大于10ms来判断是否进行按键消抖处理。在实际应用中,需要根据具体的情况调整消抖时间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁子希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值