单片机源程序如下:
#define PD 0x22|(P1&0x51)|(P2<<1&0x80)|(P3<<2&0x0c) /组合5个按键为1个字节数据
#define S0 0 //状态0
#define S1 1 //状态1
#define S2 2 //状态2
#define S3 3 //状态3
sbit up = P2^6; //0111 1111 7f
sbit unit = P1^0; //1111 1110 fe
sbit down = P3^0; //1111 1011 fb
sbit md = P1^6; //1011 1111 bf
sbit k5 = P3^1; //1111 0111 f7
sbit k6 = P1^4; //1110 1111 ef
/*******************************************************************************
* 文件名:按键函数
* 描 述:
* 功 能:
* 参 数:无
*******************************************************************************/
void key_scan()
{
bit kflag;
static u8 state=S0,key_time;
u8 key;
key=PD&0xFF;
switch(state) //检测状态
{
case S0: //状态0
if(key!= 0xFF) state = S1; break;
case S1: //状态1
if(key==0xFF) state = S0; //判断输入是否为1,为1返回状态0
else //否则,转入状态2,执行按键程序
{
state=S2; //按键按下执行短按操作
switch(key)
{
case 0x7F: 加键 break;
case 0xfe: 单位切换 break;
case 0xFB: 减键 break;
case 0xBF: 执行任务 break;
case 0xF7: 执行任务 break;
case 0xEF: 执行任务 break;
default:break;
}
}
break;
case S2: //状态2
if(key==0xFF) state = S0; //判断输入是否为1,为1返回状态0
else if(++key_time==200) //按下时间等于200时为长按,转入状态3
{
key_time=0;state=S3;
}
break;
case S3: //状态3
if(key==0xFF) state=S0; //判断输入是否为1,为1返回状态0
else if(++key_time==5) //否则开始计时,计时结束按键连击
{
key_time=0;
switch(key)
{
case 0x7F: 执行任务 break;
case 0xfe: 单位切换+长按开关机 break; //短按切换单位,长按开关机。长按开机或关机后都会跟随一次短按,如关机前是P单位,再次开机后不会在P单位,而是P下一个单位K.(此键放在这个位置是不对的,这里是连按识别,应该放在长按识别里的。)
case 0xFB: 执行任务 break;
}
}
break;
}
红色标注部分如何解决?在网上查了下,是不是要加个自锁标志?
|