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.算法只针对一路按键信号的检测,多路按键检测同一路。