|
发表于 2019-4-24 15:26:56
|
显示全部楼层
本帖最后由 zmh169 于 2019-4-24 15:33 编辑
我把楼主程序修改了一下,理论上应该没问题,没调试验证过,供参考。按键按下端口拉低,没考虑多键同时按下的情况。
//按键
sbit KEY_SET = P1^3;
sbit KEY_UP = P1^2;
sbit KEY_DOWN = P1^0;
//状态机3种状态: 按下,确认,松手
#define key_state_0 0 //按下
#define key_state_1 1 //确认
#define key_state_2 2 //计时 判断长短按
#define set_short_press 1 //短按
#define set_long_press 2 //长按
#define up_short_press 3
#define up_long_press 4
#define down_short_press 5
#define down_long_press 6
uchar keyscan(void)
{
static uchar key_state = 0, key_time = 0;
static bool set_down = false, up_down = false, down_down = false;
uchar key_set_press,key_up_press,key_down_press;
uchar key_return = 0;
key_set_press = KEY_SET; // 读按键I/O电平
key_up_press = KEY_UP;
key_down_press = KEY_DOWN;
switch (key_state)
{
case key_state_0: // 按键初始态
set_down = false;
up_down = false;
down_down = false;
key_time = 0; // 清零按键时间计数器
if ((!key_set_press) || (!key_up_press)|| (!key_down_press))//如果三个键有任何一个按下
{
key_state = key_state_1; // 状态转换到键确认态
if (!key_set_press)
{
set_down=true; //确认是set 键,标志位
}
else if (!key_up_press)
{
up_down=true;
}
else if(!key_down_press)
{
down_down=true;
}
}
break;
case key_state_1: // 按键确认态
if ( (!key_set_press && set_down) ||
(!key_up_press && up_down) ||
(!key_down_press && down_down) )
{
key_state = key_state_2;
}
else
{
key_state = key_state_0; // 按键已抬起,转换到按键初始态
}
break;
case key_state_2: //检测是否长按
if( (!key_set_press&&set_down) ||
(!key_up_press&&up_down) ||
(!key_down_press&&down_down) )
{
if (key_time < 255) //避免计时器溢出
{
key_time ++;
}
if(key_time >= 200) //按下时间>=2s,判断为长按
{
if (!key_set_press&&set_down)
{
key_return = set_long_press;
}
//-------------------------------------------
else if (!key_up_press&&up_down)
{
key_return = up_long_press;
}
//----------------------------------------------------
else if (!key_down_press&&down_down)
{
key_return = down_long_press;
}
}
}
else
{
if(key_time < 200) //按下过,现在已抬起, 判断为短按
{
if (key_set_press&&set_down)
{
key_return = set_short_press;
}
//-------------------------------------------
else if (key_up_press&&up_down)
{
key_return = up_short_press;
}
//----------------------------------------------------
else if (key_down_press&&down_down)
{
key_return = down_short_press;
}
}
else // 长按结束,判定为无按键按下
{
key_return = 0;
}
key_state = key_state_0; // 换到按键初始态
}
break;
}
return key_return;
} |
|