#define N_Key 0 无键
#define S_Key 1 单键
#define D_Key 2 双键
#define L_Key 10 长键
#define T-Key 3 3次点击
#define F-Key 4 4次点击
#define V_Key 5 5次点击
#define Key_state_0 0
#define Key_state_1 1
#define Key_state_2 2
#define Key_state_3 3
#define Key_state_4 4
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
unsigned char key_press, key_return = N_key;
key_press=key_input; //读按键I/O电平
switch(key_state)
{
case key_state_0:
if(!key_press) //如果键被按下,状态转换到按键消抖和确认状态
key_state=key_state_1;
break;
case key_state_1:
if(!key_press)
{
key_time=0;
key_state=key_state_2; //按键仍然处于按下,消抖完成,状态切换到按下键时间的计时状态,但返回的无键状态
}
else
key_state=key_state_0;//按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的
break;
case key_state_2:
if(key_press)
{
key_return=S_Key; //此时按键释放,说明是产生一次端操作,回送S_key
key_state=key_state_0;
}
else if(++key_time>=100)//继续按下,计时加10ms(定时器为10s)
{
key_retuen=L_Key; //按下时间>1000ms,此按键位长按操作,返回长按事件
key_state=key_state_3; 转换到等待按键释放状态
}
}
}
unsigned char key_read(void)
{
static unsigned char key_m=key_state_0,key_time_1=0;
unsigned char key_return=N_Key,key_temp;
key_temp=key_driver();
switch(key_m)
{
case key_state_0:
if(key_temp==S_Key)
{
key_time_1=0; //第一次单机,不返回,到下个状态判断返回后面是否出现双击
key_m=key_state_1;
}
else
key_return=key_temp;
break;
case key_state_1:
if(key_temp==S_Key) // 又一次单击(间隔肯定<500ms)
{
key_return=D_Key; // 返回双击键事件,
key_m=key_state_2; //第二次单机,不返回,到下个判断是否出现三击
}
else
{
if(++key_time_1>=50)
{
key_return=S_Key; //500ms内没有再次出现单键事件,返回上一次的事件
key_m=Key_state_0;//返回初始状态
}
}
break;
case key_state_2:
if(key_temp==S_Key)
{
key_return=T_Key; //返回三击键事件
key_m=key_state_3; //第三次单机,不返回,到下个判断是否出现三击
}
else
{
if(++key_time>=50)
{
key_return=D_Key;
key_m=key_state_0;
}
}
break;
case key_state_3:
if(key_temp==S_Key)
{
key_return=F_Key; //返回四击键事件
key_m=key_state_4;//第四次单机,不返回,到下个判断是否出现三击
}
else
{
if(++key_time_1>=50)
{
key_return=T_Key;
key_m=key_state_0;
}
}
break;
case key_state_4:
if(key_temp==S_Key)
{
key_return=V_Key; //返回五击键事件,回初始状态
key_m=key_state_0;//第五次单机,不返回,到下个判断是否出现三击
}
else
{
if(++key_time_1>=50)
{
key_return=F_Key;
key_m=key_state_0;
}
}
break
}
return key_return;
}
void T1_INT_INTERRUPT interrupt 3
{
time_10ms_ok=1;
}
void initTimer1(void)
{
TIMER1_MODE1_ENABLE;
TH1 = (65536-TIMER1_10MS_VALUE)/256;
TL1 = (65536-TIMER1_10MS_VALUE)%256;
set_ET1;
set_EA;
set_TR1;
}
void mian(void)
{
while(1)
{
if(time_10ms_ok)
{
time_10ms_ok=0;
key=key_read();
switch(key)
{
case S_Key: //单击事件
break;
case D_Key: //双击事件
break;
case T-Key: //三击事件
break;
case F-Key: //四击事件
break;
case V_Key: //五击事件
break;
}
}
}
}
|