原创 嵌入式系统的按键扫描程序设计04

2010-3-30 22:06 2982 8 8 分类: MCU/ 嵌入式

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2009107星期三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条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条