STM32按键程序讲解

本文介绍了嵌入式系统中按键的两种操作模式——连按和不连按,并通过示例代码展示了如何实现。在不连按模式下,长时间按住按键只被视为一次输入。此外,还探讨了按键的复用技巧,如长按短按的区分、按键次数复用以及两个按键组合使用的场景,展示了如何通过中断和定时器优化按键功能,实现更高效的操作控制。
摘要由CSDN通过智能技术生成

一、连按、不连按

连按:手一直按按钮保持不松的状态,小灯的状态发生改变

不连按模式:手一直按按钮保持不松的状态相当于只按了一次

三个按键都处于上拉输入状态:按下GPIO口为0

下面程序中用到了static关键字,下面一起来回顾一下:

  静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

//static出现在类中
class Person
{
public:
	static int i;  //类内声明
};
int Person::i;   //类外定义
int main()
{
	Person::i = 10; //其他地方可以改变其值
}

u8 keyScan(u8 mode)
{
	static u8 f=1;
	if(mode)
	{
		f=1;
	}
	if(f&&(key0==0||key1==0||key2==0))
	{
		delay_ms(10);//延时去抖
		f=0;
		if(key0==0)
		{
			return 0;
		}
		else if(key1==0)
		{
			return 1;
		}
		else if(key2==0)
		{
			return 2;
		}
	}
	else if(key0==1&&key1==1&&key2==1)
	{
		f=1;
	}
	return -1;  //返回-1表示无按键按下
	
}
void main()
{
	u8 key;
	delay_init();   //延时函数初始化
	Led_init();    //led小灯初始化
	Key_init();    //按键初始化
	LED0=0;        //刚开始使led0小灯处于亮的状态
	while(1)
	{
		key=keyScan(1);
		switch(key)
		{
			case 0:
			{
				LED0=!LED0;   //改变led小灯状态
				delay_ms(1000); //延时1s
				break;
			}
			case 1:
			{
				LED1=!LED1;
				delay(1000);
				break;
			}
			case 2
			{
				LED0=!LED0;
				LED1=!LED1;
				delay(1000);
				break;
			}
			default:
			{
				delay_ms(10);
			}
		}
	}
	
}

二、按键复用

  按键复用的应用在我们日常生活中非常常见,我们的智能手机的按键很少,只有开关键和音量键,但却能应用复用实现其他功能。

  1、长按、短按

 下面这个例子中我们来实现只用一个按键来控制两个led小灯的控制。

  3s以内:控制LED0

  3s以上:控制LED1

u8 key_Scan(u16 time)
{
  u16 count=0;
  if(key0==0)
  {
    delay_ms(10); 
    if(key0==0)
    {
      while(key0==0)
      {
        delay_ms(10);
        count++; 
      }
    }
    if(count==0)
      return 0;
    else if(count*10<time)
      return 1;
    else
      return 2;
  }
  return 0;
}
int main(void)
 {	
	u8 t=0;	  
	delay_init();	    	 	  
	LED_Init();		  	 	
	KEY_Init();          	
	LED0=0;					
	while(1)
	{		
		t=key_Scan(3000);
		switch(t)
		{
		  case 0:
		  {
			break;
		  }
		  case 1:   
		  {
			LED0=!LED0;
			break;
		  }
		  case 2:
		  {
			LED1=!LED1;
			break;
		  }
		}
	}		 
}

 2、在一定时间内次数复用

    1s内按一次:控制LED0

    1s内按两次:控制LED1

会使用中断后再写(这都过了三四个月了才想起写)

思路:按键为下降沿中断,触发后打开定时器,定时1s后判断按键次数。

main主函数:

 u8 count=0;  //记录1s内按下KEY0的次数
 int main(void)
 {	 
	delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
    TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms
    EXTIX_Init();    //KEY0外部中断中断初始化
	LED_Init();		  	 	//初始化与LED连接的硬件接口
	while(1)
	{
    
    }	 
 }

中断线5(KEY0)的中断服务程序:

 void EXTI9_5_IRQHandler(void)
{			
  delay_ms(10);   //消抖		
  
  if(KEY0==0)	{
    count++;
    if(count==1)
    {
      //打开定时器
      TIM_Cmd(TIM3, ENABLE);  //开始计时
    }   
    
  }
  EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}

定时器3中断服务程序:
 

void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
	{
    if(count==1)   //1s内按1次KEY0,led0亮
    {
      LED0=!LED0;
    }
    else           //1s内按1次KEY0,led1亮
    {
      LED1=!LED1;
    }
    count=0;
    TIM_Cmd(TIM3,DISABLE);  //停止计时
	  TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 
	}
}

 3、两个按键共同按下

单独按下key0,控制ed0    

key0和key1一起按下,控制led1

u8 key_Scan2()   //一定要不支持连按
{
  static u8 f=1;
  if(f&&(KEY0==0||(KEY0==0&&KEY1==0)))
  {
    delay_ms(10);
    if(KEY0==0)
    {
      f=0;
      if(KEY0==0&&KEY1)
      {
        return 1;
      }
      else if(KEY0==0&&KEY1==0)
      {
        return 2;
      }
      else
        return 0;
    }
  }
  else if(KEY0==1)
    f=1;
  return 0;
}
void main(void)
 {	
	u8 t=0;	  
	delay_init();	    	   
	LED_Init();		  	 	
	KEY_Init();          	
	LED0=0;					
	while(1)
    {
        t=key_Scan2();
		switch(t)
		{
			case 0:
			{
				break;
			}
			case 1:
			{
				LED0=!LED0;
				break;
			}
			case 2:
			{
				LED1=!LED1;
				break;
			}
		}
	}		 
}
    }

STM32按键中断例程主要是指针对STM32单片机,通过按键来触发中断服务程序,并对相关的中断进行响应和处理的一个示例代码程序。以下是关于STM32按键中断例程的详细讲解: 1. 程序文件及配置:需要引用头文件"stm32f10x.h"、"stm32f10x_gpio.h"和"stm32f10x_exti.h",同时配置相关的中断和IO口。 2. 按键中断的初始化:主要包括GPIO口初始化、EXTI中断初始化、NVIC中断向量表配置和GPIO口中断处理函数的设置。 3. 接收按键中断信号:通过构造EXTI中断服务程序,实现对按键按下事件的捕捉并进行相应的处理动作。在处理函数中,涉及到的主要操作包含:清除中断标志位、调用相关回调函数、应答外设等操作。 4. 回调函数的设置:中断服务程序需要实现一个回调函数,对中断事件进行处理。回调函数一般存在于主局面中,对按键的响应和业务逻辑进行处理。 5. 应用场景:STM32按键中断例程可应用于各种嵌入式应用场景,包括遥控器、汽车电子、智能家居等领域,实现对按键操作的监听和相应动作的处理。其优点是响应速度快、功耗低、可靠性高,广泛应用于工业控制、通信、医疗等各个领域。 综上所述,STM32按键中断例程是一种基于STM32单片机的中断服务程序,通过对按键事件进行监听并进行相关处理,实现了对嵌入式系统的控制和交互,广泛应用于各种应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

small_planet

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

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

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

打赏作者

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

抵扣说明:

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

余额充值