程序说明
B1-普通单击;B2-锁定;B3-连击;B4-长短按
key_retrun-返回值,用于执行不同功能
key_state——大状态。
lock_Bx——小状态:0,表示所有判断都结束,即本次按键功能已经结束;1,表示需要进一步判断该按键是否是特殊功能(长短按,锁定,连击)。即状态变化为0——1——0
flag_longkey,flag_doublekey也是类似的小状态。
大状态中包含小状态,注意状态转换最终构成闭环,确保状态转换的有序性。
对于多功能按键,第一次按下,状态不能改变,需要后续再次判断按键功能才改变状态。
短按和长按,N击和N击判断配合理解。
u32 uwTick_longkey;
u32 uwTick_blockkey;
u32 uwTick_doublekey;
uint8_t Key_Scanf(void)
{
uint8_t key_return = 0;
static u8 key_state;
static u8 flag_longkey; //长按标志,0,没有按;1短按;2,长按
static u8 flag_doublekey; //N击次数记录
static u8 lock_B4;//=0,未按下,=1,记作第1次按下
static u8 lock_B2;// =0,未按下,=1,记作第1次按下
static u8 lock_B3;// =0,未按下,=1,记作第1次按下
switch(key_state)
{
case 0:
if(B1 && B2 && B3 && B4)
{ //所有按键都未按下,保持状态0
key_state = KEY_STATE_0;
}
else
{ //有按键按下,下一次循环再次判断,消抖
key_state = KEY_STATE_1;
}
break;
case 1:
if(B1 && B2 && B3 && B4)
{
if(flag_longkey==1) //短按
{
key_return = 4;
flag_longkey=0; //恢复初始状态
lock_B4=0; //结束
key_state = KEY_STATE_2;
}
if(flag_doublekey!=0)//N击判断
{
if(uwTick-uwTick_doublekey>800) //超过规定时间,判断按键结束
{
if(flag_doublekey==1) //单击
key_return = 3;
else if(flag_doublekey==2) //双击
key_return = 7;
else if(flag_doublekey==3) //三击
key_return = 8;
flag_doublekey=0; //恢复初始状态
lock_B3=0; //结束
key_state = KEY_STATE_2;
}
}
else
key_state = KEY_STATE_0; //抖动
}
else //确定是按下而不是抖动
{
if(!B1)
{
key_return = 1;
key_state = KEY_STATE_2;
}
else if(!B2) //5s内不可更改
{
if(lock_B2==0) //第一次按下
{
uwTick_blockkey = uwTick;
lock_B2=1;
i++;
i%=2;
if(i==0)
key_return = 2;
else if(i==1)
key_return = 6;
key_state = KEY_STATE_2;
}
if(uwTick-uwTick_blockkey>5000) //超过规定时间,解锁
lock_B2=0; //结束
}
else if(!B3) //N击
{
if(lock_B3==0) //第一次按下
{
uwTick_doublekey = uwTick; //开始计时
lock_B3=1; //更改lock
flag_doublekey=1; //N击标志
//key_state仍然等于KEY_STATE_1,在规定时间内再次按下则记为有效次数
}
if(uwTick-uwTick_doublekey>500 && uwTick-uwTick_doublekey<800) //确定是N击
{
uwTick_doublekey=uwTick; //重新计时
flag_doublekey++; //计次
}
}
else if(!B4) //长按
{
if(lock_B4==0)//第一次
{
uwTick_longkey = uwTick; //开始计时
flag_longkey=1;
lock_B4=1; //更改lock
//key_state仍然等于KEY_STATE_1,下一次确定是长按还是短按,若长按再次进入 else if(!B4)判断
}
if(uwTick-uwTick_longkey>1000) //大于规定时间表示长按
{
flag_longkey=0;//恢复初始状态
lock_B4=0; //结束
key_return = 5;
key_state = KEY_STATE_2;
}
}
}
break;
case 2:
if(B1 && B2 && B3 && B4)
{
key_state = KEY_STATE_0;
}
break;
}
return key_return;
}