單片機按鍵識別篇---單擊---雙擊----長按


  最近做一任務需要使用一個按鍵實現三種功能,分別是按鍵單擊功能,按鍵雙擊功能和按鍵長按功能,可能之前沒有接觸過這類按鍵復用情況,頂多也只是簡單識別單擊和長按,沒有想過雙擊以上按鍵功能,也是絞盡腦汁,想了半天,又上網看了些例程,算是對於按鍵的識別有點小小的了解,感覺這個功能挺實用,在此做個隨筆。

一、思路

  1.識別長按操作思路:我們使用系統定時器定時,然后讓系統每過一段時間去掃描按鍵I/O口狀態,當掃描到按鍵按下I/O口狀態超過設定長按時間的閥值,就判定這次按鍵操作為“長按”操作;

  2.識別單擊操作思路:當系統掃描按鍵按下的I/O口時間小於我們設定的長按閥值,這時就可能出現兩種情況,情況1.可能是單擊;情況2.可能是雙擊;首先我們來說情況1,單擊操作,這時我們可以檢測按鍵按下后,按鍵彈起的時間到下次按鍵按下的時間間隔,當按鍵按下彈起到下次按鍵按下的時間超過某個值,則我們判定這次操作為“單擊”操作;

  3.識別雙擊操作思路:上面剛說的情況1,這次來說情況2,:雙擊操作,當我們檢測按鍵按彈起后在一定時間閥值內,又檢測到按鍵I/O口有電平變化,則我們判斷這次操作為“雙擊”操作

二、程序部分

unsigned char scan_key()  
{
/*
值key_return如下:
          1---------單擊
          2---------雙擊
          3---------長按
*/
static unsigned char key_state=0;                           //按鍵狀態
static unsigned char state=0;
static unsigned char time,time1,time2;    
static unsigned char key_up_flag=0;                           //按鍵彈起標志位
static unsigned char key_return;


  if(Key==0)                                                 //按鍵按下消抖
  { 
    delay(50);
     if(Key==0)
     { 
       key_state=0;
     } 
   }  
  else 
  {
    delay(50);                                                //按鍵松開消抖
    if(Key==1)
    {
     key_state=1;
     key_up_flag=0;
    }
  }
   if((state==0)&&(key_state==0)&&(key_up_flag==0))        //這里主要防止,按鍵在識別長按后,又會執行一遍單擊操作                               
    {
             state=1;
             time=key_time;                                       //記錄按鍵按下的時間為多少,做標記
    }
     if(state==1)
     {
          time1=key_time;
          time2=time1-time;                                 //計算按鍵按下時長
                
           if(time2>50)                                    //長按判斷
             {
              state=2;
            } 
         if(key_state==1)                                //按鍵彈起
           {
              state=3;
              time=key_time;                                  //標志什么時間按鍵彈起的
           }
     }
     if(state==2)                                         //長按
      {
            state=0;                                     //重置狀態
            key_up_flag=1;
            key_return=3;
      }
         if((state==3)&&(key_up_flag==0))
          {
               time1=key_time;
               time2=time1-time;                          //計算按鍵彈起后時間
                if(time2>6)                                //判斷按鍵彈起后的時間,超過300ms,則說明為單擊
                    {
                      state=0;
                    key_return=1;
                  }    
              else    if(key_state==0)                     //按鍵彈起后,300ms內又有按鍵按下
                 {
                      state=4;
                 }
           }
           if(state==4)
          {
                  if(key_state==1)                        //按鍵彈起
                  {
                     state=0;
                    key_return=2;
                   }
          }
          
     return key_return;          
}

void timer0() interrupt 1     //定時器T0中斷函數入口
{
     TH0=0X9E;             //初值重載
     TL0=0X57;           //定時50ms=50000us; 50000/2=25000
     key_time++;        //50MS++

  
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM