【CC2530強化實訓04】定時器間隔定時實現按鍵N連擊

【題目要求】

    2018年全國職業院校技能大賽“物聯網技術應用”國賽(高職組)中關於感知層開發的難度陡然增大,三個題目均在Zigbee協議棧下完成。其中第一個題目考查了按鍵單擊、雙擊和三連擊。爲了讓大家更好的掌握按鍵的複雜處理思路,在這裏通過一個具體的實訓案例,講述通過間隔定時實現按鍵N連擊的基本思路。

    在新大陸國賽設備的黑色Zigbee模塊上,或者小蜜蜂製作的XMF09B和XMF09C中,按鍵SW1單擊,切換D5燈的開關狀態;按鍵SW1雙擊,切換D6燈的開關狀態;按鍵SW1三連擊,切換D3燈的開關狀態;按鍵SW1四連擊,切換D4燈的開關狀態

      按鍵SW1--------P1_2

      D5燈--------------P1_3(高電平點亮)

      D6燈--------------P1_4(高電平點亮)

      D3燈--------------P1_0(高電平點亮)

      D4燈--------------P1_1(高電平點亮)

【實現思路】

    每個按鍵按下都定義一個生命週期,假如是0.5秒,生命週期結束的時候才確定按鍵的最終狀態。如果在按鍵的生命週期內有新的按鍵按下,將會重新計算生命週期,這時候就是雙擊。在雙擊的生命週期中,又有新的按鍵按下,則生命週期會重新計算,這時候就是三連擊。在整個生命週期中如果沒有新的按鍵按下,那麼最終的按鍵狀態就是三連擊。如此類推。

【實現代碼】

#include "ioCC2530.h"

#define D3  P1_0
#define D4  P1_1
#define D5  P1_3
#define D6  P1_4
#define SW1 P1_2
#define SW2 P0_1

unsigned char count_t = 0;
unsigned char K_Num = 0;

/*=======================簡單的延時函數========================*/
void Delay(unsigned int t)
{
  while(t--);
}

/*======================端口初始化函數========================*/
void Init_Port()
{
  P1SEL &= ~0x1b;     //P1_0、P1_1、P1_3和P1_4作爲通用I/O端口
  P1DIR |= 0x1b;      //P1_0、P1_1、P1_3和P1_4端口輸出
  
  P1SEL &= ~0x04;     //P1_2作爲通用I/O端口
  P1DIR &= ~0x04;     //P1_2端口輸入
  P1INP &= ~0x04;     //P1_2設置爲上拉/下拉模式
  P2INP &= ~0x40;     //P1_2設置爲上拉
}

/*=======================定時器1初始化========================*/
void Init_Timer1()
{
  T1CC0L = 0xd4;      
  T1CC0H = 0x30;        //16MHz時鐘,128分頻,定時0.1秒
  T1CCTL0 |= 0x04;      //開啓通道0的輸出比較模式
  T1IE = 1;
  EA = 1;
  T1CTL = 0x0e;         //分頻係數是128,模模式
}

/*====================定時器1服務函數========================*/
#pragma vector = T1_VECTOR
__interrupt void Timer1_int()
{
  T1STAT &= ~0x20;    //清除定時器1的溢出中斷標誌位
  if(K_Num != 0 && SW1 != 0)      
  {
    count_t++;        //定時器1溢出一次加1,溢出週期爲0.1S
  }
}

/*====================按鍵掃描處理函數========================*/
void Scan_Keys()
{
  if(SW1 == 0)
  {
    Delay(100);         //去抖動處理
    if(SW1 == 0)
    {
      while(SW1 == 0);  //等待按鍵鬆開
      count_t = 0;      //每次有按鍵按下,計時重新開始
      K_Num++;          //改變按鍵狀態
      if(K_Num > 4)     //四連擊以上均判爲四連擊
      {
        K_Num = 4;
      }
    }
  }
  if(count_t > 5)       //按鍵間隔時間到
  {    
    switch(K_Num)
    {
      case 1:           //按鍵單擊
        D5 = ~D5;
      break;
      case 2:           //按鍵雙擊
        D6 = ~D6;
      break;
      case 3:           //按鍵三連擊
        D3 = ~D3;
      break;
      case 4:           //按鍵四連擊
        D4 = ~D4;
      break;
    }
    K_Num = 0;     //每處理完一次按鍵,狀態清零
    count_t = 0;   //計時清零
  }
}

/*=========================主函數=============================*/
void main()
{
  Init_Port();
  Init_Timer1();
  D3 = 0;
  D4 = 0;
  D5 = 0;
  D6 = 0;
  while(1)
  {
    Scan_Keys();
  }
}

廣東職業技術學院   歐浩源 <小蜜蜂老師>  [email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章