//这是我对以前发表过的按键检测方式的优化,之前的是:http://blog.youkuaiyun.com/chuangwu2009/article/details/9466715
//现在的程序按键有效检测方式:1:单按键响应 2:多按键响应 3:长按单个按键响应 4:长按多个按键响应 5:以上响应的方式都可以选择释放后响应和按下马上响应
void Key_scan(void) // uint8
{
static uint8 key_value=0;//当前按键值寄存器
static uint8 key_delay=0;//按键去抖动寄存器
static uint8 key_value0=0;//前一次按键值寄存器
static uint8 key_value1=0; //按键释放后的按键值寄存器
static uint8 key_mult=0;//多按键寄存器
static uint8 key_longtime=0;//长按时间累积寄存器1
static uint8 key_longtime1=0;//长按时间累积寄存器2
key_value=0;
key_mult=0;
if(!P_K1)//按键扫描 P_K1
{
key_value|=SETB0;
key_mult++;
}
if(!P_K2)//按键扫描 P_K2
{
key_value|=SETB2;
key_mult++;
}
if(!P_K3)//按键扫描P_K3
{
key_value|=SETB3;
key_mult++;
}
if(!P_K4)//按键扫描 P_K4
{
key_value|=SETB4;
key_mult++;
}
if(!P_K5)//按键扫描 S5 减键
{
key_value|=SETB5;
key_mult++;
}
if(key_value==key_value0)//如不相等,保存当前按键值,清抖动寄存器,以此次识别
{
if(key_delay>5)//抖动处理
{
if(key_value>0)//无按键按下确认,等于0时表示无按键,清释放标识位
{
if(!f_onkey)
{
f_onkey=1;
if(1==key_mult)
{//单按键按下处理程序
switch(key_value)
{
case SETB0://按下P_K1
{
key_value1|=SETB0;
break;
}
default:
break;
}
}
else
{//多按键按下处理程序
case SETB0|SETB1://同事按下P_K1 P_K2
{
key_value1|=SETB0|SETB1;
break;
}
case SETB0|SETB1|SETB2://同事按下P_K1 P_K2 P_K3
{
key_value1|=SETB0|SETB1|SETB2;
break;
}
}
}
else
{//按键长按
if(!F_longkey)
{
if(++key_longtime>=40)//5毫秒1次 40*15*5=3秒
{
key_longtime=0;
if(++key_longtime1>=15)
{
key_longtime1=0;//3秒时间到
F_longkey=1;
//长按按键处理程序
if(1==key_mult)
{
switch(key_value)
{
case SETB0://长按下P_K1
{
break;
}
default:
break;
}
}
else
{//多按键长按按键处理程序
case SETB0|SETB1://同事按下P_K1 P_K2
{
key_value1|=SETB0|SETB1;
break;
}
case SETB0|SETB1|SETB2://同事按下P_K1 P_K2 P_K3
{
key_value1|=SETB0|SETB1|SETB2;
break;
}
}
}
}
}
}
}
else//按键释放
{
f_onkey=0;
F_first=0;
key_longtime=0;
key_longtime1=0;
if(F_longkey)
{//长按按键释放
F_longkey=0;
}
else
{//短按按键释放
if(SETB0==key_value1)
{//P_K1释放
}
else if(SETB0|SETB0==key_value1)
{//P_K1 P_K2释放
}
}
key_value1=0;
}
}
else //有按键
{
key_delay++;
}
}
else
{
key_value0=key_value;
key_delay=0;
}
}