STM32_按键中断

***************************************************************************************************************************************

开发板   :奋斗STM32

CPU        :STM32F103

开发环境:keil uVsion4

****************************************************************************************************************************************

前言:本文主要是通过按键中断,实现当按下按键时,LED灯灭,释放按键时,LED灯亮。(不过我设置LED的起始状态为亮,也就是上电就点亮了LED灯。)

    我的开发板按键,LED所对应的GPIO管脚原理图如下:


我写的按键中断程序实现的功能是:按下按键K2,LED3由亮变灭,释放按键LED3又变亮。(按键K2对应PC2管脚,LED3对应PD3管脚)。


测试代码:

#include "misc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_rcc.h"

#define LED_ON 	GPIO_SetBits(GPIOD, GPIO_Pin_3);

//unsigned char flag=0;
//unsigned char num=0;
void LED_Config(void);
void EXTI_PC2_Config(void);
void RCC_Config(void);
//void KEY_Dither(void);
//void delay_nms(u16 time);
int main(void)
{ 
	
//	unsigned char a = 0;
	RCC_Config();
	LED_Config();
	EXTI_PC2_Config();
	LED_ON;
	
	
	while(1)
	{
		//KEY_Dither();
		//if(num==1&&a==0){GPIO_ResetBits(GPIOD,GPIO_Pin_6);a=1;}
		//else if(num==1&&a==1){GPIO_SetBits(GPIOD,GPIO_Pin_6);a=0;}
  }
}
/*void KEY_Dither(void)
{
	num=0;
	if(flag==1)
		{   
			  delay_nms(12000);
		   if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)
			 {
				 delay_nms(12000);
			   if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)
				 {
					 while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)
						 num=1;
					   goto n_exit;
			   }
		    }
				else ;
           n_exit:;
           flag=0;
			}
}			 


void delay_nms(u16 time)
{    
   u16 i=0;  
   while(time--)
   {
      i=12000;  //自己定义
      while(i--) ;    
   }
}
*/
void RCC_Config(void)  
{    
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD,ENABLE); 
     SystemInit();  
	 
}  

void LED_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/*led config*/	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

}
void EXTI_PC2_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
  /*config for NVIC*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);	

	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	/* key for exti */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
	
  /*EXIT line(PC2) mode config */
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	

}
void EXTI2_IRQHandler(void)  
{  
    if (EXTI_GetITStatus(EXTI_Line2) != RESET)  
    {  
       // flag= 1;//按键按下标志 
			    /*LED取反*/
         GPIO_WriteBit(GPIOD, GPIO_Pin_3,  
                (BitAction)((1-GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_3)))); 			
  
        EXTI_ClearITPendingBit(EXTI_Line2);  
    }  
}  
************************************************************************************************************************************

说明:我写的这个程序只是实现了按键按下灯由亮变灭的简单功能,但是测试发现,这个按键抖动太严重,轻轻的触摸按键,灯会闪闪的亮,有时

候碰一下按键,还没有按下按键时,LED灯就熄灭了。所以用delay_nms()延时函数进行去抖,代码中注释掉的代码是为了按键去抖,不过这个去抖效果不是很好,还是会有抖动现象,但相比之前会好一点!不过官方提供了一个延时函数,可以调用官方写好的延时函数,一般10ms的时间可以去抖。

************************************************************************************************************************************************

写这个程序主要是完成相应的配置工作,步骤如下:

(1)初始化系统时钟和

初始化外部时钟(时钟配置)

void RCC_Config(void)  
{    
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);  
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD,ENABLE); 
      SystemInit(); //系统时钟初始化 	 
}  

*****************************************************************************************************************************************************************************

说明:我们可以不用加SystemInit();不加这个函数也没影响,因为startup_stm32f10x_hd.s这个文件已经帮我们做了这些事情。

*****************************************************************************************************************************************************************************

(3)配置LED

void LED_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/*led config*/	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

}

(4)配置中断优先级

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);	

	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
*********************************************************************************************************************************************************************************

说明:这个中断优先级的设置可以随便设置,原因是我创建的工程中只用到了按键中断,没有其他中断,当然如果有多个中断,就得按照中断向量表

以及中断优先级设定规则来设,具体规则可以参考网上的资料,有很多,可以看看,这里我就不说明了。这里我设置的是第一组中断,抢占优先级是

0,响应优先级也是0。

************************************************************************************************************************************************************************************

(5)配置外部中断线

/*EXIT line(PC2) mode config */
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
*************************************************************************************************************************************************************************************

说明:这个中断模式有两种,一是Event,二是Interrupt,因为这里是中断,所以我们设为

Interrupt

,因为是按键Key2,则这里中断线为EXTI_Line2,如果按键是5-9则这里就要统一写成EXTI9_5_IRQn。

**************************************************************************************************************************************************************************************

(6)中断处理函数

void EXTI2_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line2) != RESET) //判断按键是否按下
	{
		/*LED反转*/
GPIO_WriteBit(GPIOD, GPIO_Pin_6,  
                (BitAction)((1-GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_6))));  
		EXTI_ClearITPendingBit(EXTI_Line2); //清除中断标志位
	}
} 
****************************************************************************************************************************************************************************************
说明:这里的中断处理函数我们通常最好是放在 stm32f10x_it.c这个文件,这是官方提供的一个用来放所有外部中断处理函数的文件,当主程序在执行程序时,如果发生中断,cpu会立即跳到这里来执行中断处理函数,这里因为只有按键中断,还体现不出这样做的好处,如果是一个大工程,用到多个中断时,把中断函数统一放在这个文件中的话,可以大大优化代码。

***************************************************************************************************************************************************************************************




  • 7
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32CUBEMX是STMicroelectronics公司开发的一款用于生成STM32微控制器初始化代码的软件工具。它可以帮助开发人员快速配置STM32微控制器的外设和引脚,并自动生成相应的初始化代码。在使用STM32CUBEMX进行按键中断配置时,可以按照以下步骤进行操作: 1. 打开STM32CUBEMX软件并创建一个新工程。 2. 在Pinout & Configuration选项卡中,找到对应的按键引脚和LED灯的引脚,并进行配置。可以参考提供的电路图进行正确的配置。 3. 在Configuration选项卡中,配置按键的模式为输入下降沿触发。这可以通过设置GPIO外设的相应控制寄存器来实现。 4. 在生成代码之前,可以进一步进行配置文件的编辑,以满足项目的需求。这可以通过在Configuration选项卡中进行相应的设置来完成。 5. 生成代码并将其导入到您的开发环境中进行编译和调试。 需要注意的是,延时函数的声明可以在头文件中进行。在主函数中,您可以使用extern关键字来声明其他文件中的函数,以便能够调用它们。这样可以将函数声明集中到主函数的头文件中,以方便管理和维护。有关extern关键字的更多信息,可以通过搜索引擎进行进一步了解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [STM32CubeMX按键中断](https://blog.csdn.net/qq_15672897/article/details/111322736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [毕设项目:基于zigbee和stm32的智能家居系统,上位机使用Qt编写.zip](https://download.csdn.net/download/qq_35831906/88258947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值