STM32 长按、短按、双击、三击算法(改进版)

STM32 长按、短按、双击、三击算法

按键算法又来啦!

**
**
**

本算法可以有效解决以下问题:

1.按键双击或三击操作时,也会触发按键单击对应的程序

key.h文件如下

//定义一个按键结构体
	typedef struct
	{
	  uint8_t get_key_num; 
		uint8_t state;
		uint8_t long_count; 
		uint8_t key_resault;
		uint8_t count;    
		uint8_t double_count;
		uint8_t trible_count;
	} KEY_FLAG;
	
    KEY_FLAG key_s; //声明一个按键结构体变量
	
	#define KEY_NONE 0 
	#define KEY_1_DOWN 1
	#define	KEY_1_UP 2
	#define	KEY_1_LONG 3
	#define	KEY_1_DUBDOW 4
	#define	KEY_1_TIEBLE 5
	#define	KEY_1_DOUBLE 6
	
	#define KEY_LONG_TIME 40  //三击按键间隔最小时间40*50=2000ms
	#define KEY_DOUBLE_MAX 10 //双击按键间隔最小时间10*50=500ms
	#define KEY_DOUBLE_MIN 1  //双击按键消抖时间 1*50=50ms

key.c文件如下


if(key1==0)   //key1读取KEY按键,表示key1按下
	{                   
	switch(key_s.state)
		{
			case KEY_NONE:            
			 key_s.state=KEY_1_DOWN; //按键状态切换为单次按下
			 break;
			case KEY_1_DOWN:  //这里为按键长按检测   
			 key_s.long_count++;   
				if(key_s.long_count>=KEY_LONG_TIME)
			 {
				key_s.key_resault=KEY_1_LONG;
				key_s.state=KEY_1_LONG;
			 }
			 break;
			case KEY_1_UP: //如果本次按键按下距上次按下时间小于双击的最小时间间隔,则会执行以下程序             
			 key_s.state=KEY_1_DUBDOW; //按键状态切换为双击
				key_s.count=0;
			 break;
			case KEY_1_LONG: // 按键长按状态,不进行状态切换         
			 break;
			case KEY_1_DUBDOW:          
			 break;
			case KEY_1_TIEBLE:          
			 break;
			case KEY_1_DOUBLE: //双击按下后再次按下按键,为三击操作
				key_s.state=KEY_1_TIEBLE;
			 break;
			
			default:
			 break;
		}
	
	}
	else
	{
	 switch(key_s.state) //按键松开
	 {
		 case KEY_NONE:            
			key_s.count=0;
			key_s.double_count=0;
			key_s.long_count=0;
			key_s.trible_count=0;     
			break;
		 
		 case KEY_1_DOWN: //单击按键松开后,进行双击时间检测,为了和长按区分,变换按键状态
			key_s.state=KEY_1_UP;
		 break;
		 case KEY_1_UP://双击时间间隔检测
			 key_s.count++;         
			 key_s.double_count++;
			 if(key_s.count>=KEY_DOUBLE_MAX) //表示超过双击最小时间间隔
			 {
				key_s.key_resault=KEY_1_DOWN; //按键检测最终结果为单次按下
				key_s.state=KEY_NONE;//清除按键状态
			 }
			break;
			case KEY_1_LONG:  //长按按键后松开,需要对按键结果和状态即使清除
			 key_s.state=KEY_NONE;
			 key_s.key_resault=KEY_NONE;
			 break;
			case KEY_1_DUBDOW: //双击按键松手后,进行双击状态切换
			 key_s.state=KEY_1_DOUBLE;
			 break;
			case KEY_1_DOUBLE:
			 key_s.count++;        
				key_s.trible_count++;
				if(key_s.count>=KEY_DOUBLE_MAX)
			 {
				if((key_s.double_count>=KEY_DOUBLE_MIN)&&(key_s.double_count<=KEY_DOUBLE_MAX)) //双击按键间隔最小限制可以消抖
				 {
					key_s.key_resault=KEY_1_DOUBLE;
				 }
				key_s.state=KEY_NONE;
			 }      
				break;
			 case KEY_1_TIEBLE:
			 if((key_s.trible_count>=KEY_DOUBLE_MIN)&&(key_s.trible_count<=KEY_DOUBLE_MAX))
				{
				 key_s.key_resault=KEY_1_TIEBLE; //三击同双击
				}
			 key_s.state=KEY_NONE;  
				break;
		 default:
			break;
	 }
	}

本算法需要注意的问题

1.算法中只有在长按按键的状态下,才会在松手时,对按键状态和结果进行清除。别的情况,如双击和三击,可以在调用按键的程序中进行按键结果清除。
2.在按键结构体中,区分了按键的状态和结果,这是因为按键的状态切换后,需要等待如双击和三击的时间间隔才能确定下来,也就是按键结果。
3.按键状态中,把双击分为KEY_1_DUBDOW和KEY_1_DOUBLE。目的是为了进行第二次按键松手检测。
4.算法只针对一路按键信号的检测,多路按键检测同一路。

猜你喜欢

转载自blog.csdn.net/qq_48691686/article/details/115222288