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

2010-3-30 22:06 2773 6 6 分类: MCU/ 嵌入式

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2009107星期三 15:56:19<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


标题:按键的工作方式03


二、短击与长击的实现


1、特点:该按键的功能可区分短击和长击。长击是指超过一定的时间按键有效。


2、实现背景:在UCOS操作系统下,单独的一个键,利用状态机。在按键按下阶段进行计数,最终在按键释放后根据时间的长短判断是发出短击消息还是长击消息


3、程序的简单分析:


void Task_FiveOK(void *pdata)


{


  u8 FiveOKState;   //FiveOK是我给这个键起的名字


KeyStateMachine KeySM="WaitForPress";  //键盘状态机是一个枚举变量,


// 初始状态为等待按下


  pdata=pdata;


 


for(;;)


 {


  OSTimeDly(1);          //时钟频率为100Hz,每隔10ms扫描一次键盘。


  FiveOKState=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15); //最简单的单线按键,直接读取电平


  switch(KeySM)  //根据状态机的当前状态


  {


    case WaitForPress:        //等待按键


         if(FiveOKState==0)    //低电平为有键按下


           {KeySM=KeyVerify1;    //设置状态为按键确认110ms后进行按键确认。


              }


         break;


    case KeyVerify1:            //第一次确认,如果仍然是低电平,则进入确认2状态


         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:


         if(FiveOKState==0)


           {KeySM=WaitForRelease;


               PressTimeCount++;


              }


         Else          //两次检测到高电平,则按键真的释放了


           {KeySM=WaitForPress;  //下面的状态为按键等待状态。


               if(PressTimeCount>70)  //如果超过0.7s,则判断为长击。


                 { Key[KeyNum]=KeyLong;


             OSQPost(KeyOSQ,&Key[KeyNum]);


                   KeyNum++;


                   if ( KeyNum>=30)


                      { KeyNum="0"; }


                 }


               Else              //低于0.7s判断为短击


                 { Key[KeyNum]=KeyShort;


             OSQPost(KeyOSQ,&Key[KeyNum]);


                   KeyNum++;


                   if ( KeyNum>=30)


                      { KeyNum="0"; }


                 }


               PressTimeCount=0; //按下时间计数清零。


              }


         break;


                     


       default:


         break;


  }


 }   


}

文章评论0条评论)

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