<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2009年10月7日星期三16:15:57<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
标题:键盘的工作方式04
三、单击和双击的实现。
1、特点:可识别双击。
2、利用状态机实现,不过比较麻烦,好在一般的应用中都用不到它,一个任务扫描一个按键,比较奢侈啊!
3、实现方法:在第一次按键释放后,根据按下阶段的计时,如果已经超时,则直接输出单击消息,回到等待按键状态;如果未超过双击计时时间,则等待双击,如果在规定时间内按键按下,则输出双击消息。
4、程序如下。
typedef enum{WaitForPress,KeyVerify1,KeyVerify2,WaitForRelease,KeyReleasing,DBClickVerify,DBClickWaitForRelease}KeyStateMachine; //按键状态机枚举变量,比较复杂
void Task_FiveOK(void *pdata) //按键处理任务
{
u8 FiveOKState;
KeyStateMachine KeySM="WaitForPress";
pdata=pdata;
for(;;)
{
OSTimeDly(1);
FiveOKState=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15);
switch(KeySM)
{
case WaitForPress:
if(FiveOKState==0)
{KeySM=KeyVerify1;
}
break;
case KeyVerify1:
if(FiveOKState==0)
{KeySM=KeyVerify2;
}
else
{KeySM=WaitForPress;
}
break;
case KeyVerify2:
if(FiveOKState==0)
{KeySM=WaitForRelease;
}
else
{ KeySM="WaitForPress";
}
break;
case WaitForRelease:
if(FiveOKState==0)
{KeySM=WaitForRelease;
PressTimeCount++; //单击按下计时
}
else
{
KeySM=KeyReleasing;
}
break;
case KeyReleasing: //重点在按键释放后,为了结构清晰,释放没有进行消抖确认
{ PressTimeCount++; //在释放阶段延续按下时间计数
if(PressTimeCount>70) //如果时间超过0.7s,则直接输出单击消息
{ KeySM="WaitForPress";
PressTimeCount=0;
Key[KeyNum]=KeyLong;
OSQPost(KeyOSQ,&Key[KeyNum]);
KeyNum++;
if ( KeyNum>=30)
{ KeyNum="0"; }
}
Else //如果及时时间未到,而又检测到低电平,则可能发生了双击
{
if(FiveOKState==0)
{
KeySM=DBClickVerify;
}
}
}
break;
case DBClickVerify: //没有进行确认,进入到该阶段,直接输出双击信息
{
KeySM=DBClickWaitForRelease;
PressTimeCount=0;
Key[KeyNum]=KeyShort;
OSQPost(KeyOSQ,&Key[KeyNum]);
KeyNum++;
if ( KeyNum>=30)
{ KeyNum="0"; }
}
break;
case DBClickWaitForRelease: //双击释放后,进入到按键等待状态
{
if(FiveOKState==1)
{ KeySM="WaitForPress";
}
}
break;
default:
break;
}
}
}
文章评论(0条评论)
登录后参与讨论