【CC2530強化實訓03】定時器間隔定時實現按鍵長按與短按
阿新 • • 發佈:2018-12-13
【題目要求】
雖然用普通的延時函式能夠實現按鍵長按與短按的判別,但是在實際的工程應用和專案開發中並不好用也不靈活。更多得是藉助定時器的間隔定時來計算按鍵從按下到鬆開的時間間隔,然後通過判斷該時間值來區分按鍵長按與短按的狀態。
在新大陸國賽裝置的黑色Zigbee模組上,或者小蜜蜂製作的XMF09B和XMF09C中,按鍵SW1短按,切換D5燈的開關狀態;按鍵SW1長按,切換D6燈的開關狀態。
按鍵SW1--------P1_2
D5燈--------------P1_3(高電平點亮)
D6燈--------------P1_4(高電平點亮)
【實現思路】
<1> 定義一個變數K_Press,標誌按鍵狀態。按鍵在按下狀態時,值為1;按鍵在鬆開狀態時,值為0。
<2> 定義一個變數count_t,計算按鍵處在按下狀態的時間,也就是K_Press為1時的時間。
<3> 在按鍵鬆開後,通過判斷count_t的值來區分按鍵長按與短按狀態。
<4> 每處理完一個按鍵狀態,隨即將count_t清0。
【實現程式碼】
#include "ioCC2530.h" #define D3 P1_0 #define D4 P1_1 #define D5 P1_3 #define D6 P1_4 #define SW1 P1_2 unsigned char K_Press = 0; unsigned char count_t = 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設定為上拉 D3 = 0; D4 = 0; D5 = 0; D6 = 0; } /*=======================定時器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_Press != 0) //按鍵按下 { count_t++; //計算按下按下的時間值 } } /*====================按鍵掃描處理函式========================*/ void Scan_Keys() { if(SW1 == 0) { Delay(100); //去抖動處理 if(SW1 == 0) { K_Press = 1; //標誌按鍵正在按下 while(SW1 == 0); //等待按鍵鬆開 K_Press = 0; //標誌按鍵已經鬆開 if(count_t > 5) //按鍵長按 { D6 = ~D6; } else //按鍵短按 { D5 = ~D5; } count_t = 0; //按鍵計數值清零 } } } /*=========================主函式=============================*/ void main() { Init_Port(); Init_Timer1(); while(1) { Scan_Keys(); } }