【題目要求】
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();
}
}