實現按鍵的短按與長按的不同功能
問題分析
對于按鍵短按,通常是松開后實現其功能,而不會出現按下就進行后續的操作;而對于按鍵長按,則不太一樣,按鍵長按可能分為兩種情況,一是長按n秒后實現后續功能,比如按鍵按下1s后開燈,第二種情況是長按超過n秒以上實現功能,例如按鍵按下超過1s則不斷增加某一個參數的數值;
對于按鍵檢測,通常有兩種方式,一種是使用循環進行檢測,另一種是使用中斷進行檢測,對于短按按鍵,兩種方式都可以較好地實現,但是對于長按按鍵,則只能在中斷里進行檢測,下面上述幾種情況進行具體分析。
按鍵的檢測
引腳定義如下,對應按鍵為S7.
sbit col1=P4^4;
sbit row1=P3^0;
循環檢測
循環檢測就給一個行和一個列分別賦值相反的值即可,然后檢測是否被拉低,并進行消抖,代碼如下,通常來講,在比賽中都是按鍵松開后實現功能,因此這里不必糾結到底應該在什么時候實現功能,代碼如下。通過判斷函數是否返回1來判斷S7是否被按下。
bit S7()
{col1=0;row1=1;if(row1==0){Delay15ms();while(row1==0);return 1;}return 0;
}
中斷檢測
中斷檢測較為方便,通常我們將定時器設為1ms的定時,然后在中斷里檢測按鍵是否被按下,如果被按下,則開始計數,如果在15次計數后依舊處于按下的狀態,則說明此次按鍵是有效的,在這里,有兩種實現方式,第一種是按鍵按下超過15ms就進行下一步操作,不等待松開,這種方式通常來講會存在bug,因為會導致程序不斷重復執行后續的代碼,因此一般不用這種方式。另一種是等待按鍵松開后再進行下一步操作,代碼如下,這里定時器的配置省略;
void Timer0()interrupt 1
{static unsigned int cnt=0,flag=0;col1=0;row1=1;if(row1==0){cnt++;}else{if(cnt>15){/*****進行后續操作*****/}}
}
對于按鍵的長按,與短按檢測相差不大,只不過是比較的數值會增加而已,對于同一個按鍵的短按與長按,分開進行判斷即可,這里假設檢測長按時間為1s,代碼分別如下;
長按后松開執行
void Timer0()interrupt 1
{static unsigned int cnt=0,flag=0;col1=0;row1=1;if(row1==0){cnt++;}else{// 長按松開檢測 注意 長按檢測要放在短按檢測前if(cnt>1000){/*進行后續操作*/}// 短按檢測else if(cnt>15){/****進行后續操作****/}// 注意 此時按鍵處于斷開狀態 // 因此檢測完按鍵后要將cnt清零cnt=0;}
}
長按后即刻執行
void Timer0()interrupt 1
{static unsigned int cnt=0,flag=0;col1=0;row1=1;if(row1==0){cnt++;// 長按檢測if(cnt>1000){// 如果題目要求的是按鍵按下超過1s就執行動作 不需要按鍵松開// 例如按下超過1s則數字持續增加 此時就直接在此處進行增加的操作即可/*******進行后續的操作*******/}}else{// 短按檢測if(cnt>15){/****進行后續操作****/}// 注意 此時按鍵處于斷開狀態 // 因此檢測完按鍵后要將cnt清零cnt=0;}
}