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

2010-3-30 22:06 2236 7 7 分类: MCU/ 嵌入式

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


标题:按键的工作方式02


最近又翻阅了一些书,更深入的了解了各种按键的工作方式,下面把我编程过程中的一些体会说一下。


一、短击与连击的实现


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:            //确认2状态下,如果仍为低电平,则真的按下了,


         if(FiveOKState==0)


           {KeySM=WaitForRelease; //转入等待释放阶段


 


               Key[KeyNum]=KeyOK;


         OSQPost(KeyOSQ,&Key[KeyNum]); //向消息队列发送按键值


               KeyNum++;


              }


         else


           {KeySM=WaitForPress;


              }


         break;


         


    case WaitForRelease:  //按键会保持一段时间,并进行按下时间计数


         if(FiveOKState==0)


           {KeySM=WaitForRelease; 


               PressTimeCount++;  //按下时间计数


               if(!LongPress)  //连击标志未设置时


                 {


                   if(PressTimeCount==100) 计时超过1s,设置连击标志


                       {LongPress=1;


                         PressTimeCount=0;


                        }


                 }


               Else  //连击标志已设置


               {


                   if(PressTimeCount==10)  每隔0.1s发送一次按键消息


                       {Key[KeyNum]=KeyOK;


                OSQPost(KeyOSQ,&Key[KeyNum]);


                      KeyNum++;


                           


                            PressTimeCount=0;


                        }


                }            


              }


         else


           {


               KeySM=KeyReleasing;


              }


         break;


    case KeyReleasing:  //在等待释放阶段,检测到高电平转入此阶段


         if(FiveOKState==0)  //如果检测到低电平,说明刚刚的高电平为干扰,回到等待释放阶段。


           {KeySM=WaitForRelease;


 


               PressTimeCount++;


              }


         Else   //如果仍然是高电平,则的确是释放了,回到等到按键状态。


           {KeySM=WaitForPress;


               LongPress=0;


               PressTimeCount=0;


              }


         break;


                     


       default:


         break;


  }


 }   


}

文章评论0条评论)

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