#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define key_no 0
#define key_click 1
#define key_double 2
#define key_long 3
#define key_input P30
static unsigned char key_driver(void)
{
static unsigned char key_state_buffer1 = key_state_0;
static unsigned char key_timer_cnt1 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = key_input;
//read the I/O states
switch(key_state_buffer1)
{
case key_state_0:
if(key == 0)
key_state_buffer1 = key_state_1;
//按键被按下,状态转换到按键消抖和确认状态//
break;
case key_state_1:
if(key == 0)
{
key_timer_cnt1 = 0;
key_state_buffer1 = key_state_2;
//按键仍然处于按下状态
//消抖完成,key_timer开始准备计时
//状态切换到按下时间计时状态
}
else
key_state_buffer1 = key_state_0;
//按键已经抬起,回到按键初始状态
break;
//完成软件消抖
case key_state_2:
if(key == 1)
{
key_return = key_click;
//按键抬起,产生一次click操作
key_state_buffer1 = key_state_0;
//转换到按键初始状态
}
else if(++key_timer_cnt1 >= 100)
//按键继续按下,计时超过1000ms
{
key_return = key_long;
//送回长按事件
key_state_buffer1 = key_state_3;
//转换到等待按键释放状态
}
break;
case key_state_3:
//等待按键释放
if(key == 1)
//按键释放
key_state_buffer1 = key_state_0;
//切回按键初始状态
break;
}
return key_return;
}
unsigned char key_read(void)
{
static unsigned char key_state_buffer2 = key_state_0;
static unsigned char key_timer_cnt2 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = key_driver();
switch(key_state_buffer2)
{
case key_state_0:
if(key == key_click)
{
key_timer_cnt2 = 0;
//第一次单击,不返回,到下个状态判断是否会出现双击
key_state_buffer2 = key_state_1;
}
else
key_return = key;
//对于无键、长按,返回原事件
break;
case key_state_1:
if(key == key_click)
//又一次单击,时间间隔小于500ms
{
key_return = key_double;
//返回双击事件,回到初始状态
key_state_buffer2 = key_state_0;
}
else if(++key_timer_cnt2 >= 50)
{
//这里500ms内肯定读到的都是无键事件,因为长按大于1000ms
//在1s前底层返回的都是无键
key_return = key_click;
//500ms内没有再次出现单击事件,返回单击事件
key_state_buffer2 = key_state_0;
//返回初始状态
}
break;
}
return key_return;
}
---------------------
作者:沉默的小宇宙
来源:CSDN
原文:https://blog.csdn.net/qq997758497/article/details/80606710
版权声明:本文为博主原创文章,转载请附上博文链接!
http://blog.sina.com.cn/s/blog_e1d2ec4f0102ziw1.html"