嗨!..大家好,我是SUNNY。本人學51單片機到現在基本是掌握了8成了,打算再過一陣子學習AVR和ARM了。現在給大家出一套本人自己開發的按鍵程序,本程序占用資源極低,并且支持長按連續執行。舉個例子,如果你在調節分鐘,那么長按的話會連續按照150ms的速度連加或者連減。此版本暫時不支持長按短按識別!工作原理:一般的按鍵處理采用延時避開抖動,并且通過while語句識別彈起,這樣在延時就浪費了CPU時間不說,就那個while語句就使程序死了,其他都不執行,并且難以做到長按。本人根據windows鍵盤原理,采用定時識別法,以150ms掃描一次鍵盤,如果按鍵按下就讀鍵值,通過不同的鍵值處理不同的程序。本人經過多次試驗,150ms剛剛好,不但有效避開抖動,而且執行速度剛好在人的識別范圍內。本人下面這個例子是兩個按鍵控制兩個數碼管的數增加或者減少,99最大!不廢話,下面是程序:
我之前有寫過單片機做的類似PLC的控制板!用定時器以3.3ms的速度掃描I/O口,當連續比較三次相同則認為確實變化了并設置對應緩存,如果三次不同則認為是干擾,保持原狀態,簡潔高效,長按檢測只需要加入連續比較相同的次數就可以實現了!這種方法基本不會占用CPU太多時間,非常實際,+ M `' W$ A; ]+ }
void time0_prg() interrupt 1 using 1 //中斷入口1程序 輸入I/O掃描
{ //以3.3ms的速度掃描輸入I/O,并將數據放入內存緩存區以便后續輸入濾波處理
TH0 = 0x0F3; //12M 3.3ms
TL0 = 0x1C; //設置中斷掃描時間
WDT_CONTR=0x38; //喂狗 (3.3ms刷新看們狗)
key_buffer[nc1+1]=in_put; //掃描輸入
if(nc1>=2) nc1=0; //NC1 計時器 掃描觸發時鐘 U1 e6 P% r: W1 f; j; p
else nc1++;
void in_scan() //輸入濾波 輸入抗干擾處理
{ //原理:比較每個輸入I/O的連續三次高低電位狀態當某I/O連續3次數據不同的時候
uchar n1,n2; //則認為是干擾!當連續的某位3次數據相同則認為I/O確實變化了!并輸出相應位的變化
for(n1=0;n1<8;n1++) //比較8個I/O口
{ 7 D- q* R7 q9 b
n2=key_buffer[1]&key_constant[n1];
- T1 X0 d0 _& R8 q' f
if(n2==(key_buffer[2]&key_constant[n1]))
{
if(n2==(key_buffer[3]&key_constant[n1]))
{
if(n2) in_buffer=in_buffer&~key_constant[n1]; //檢測到三次輸入相同為0, 則判斷輸入對應位為0;
else in_buffer=in_buffer|key_constant[n1]; //檢測到三次輸入相同為1, 則判斷輸入對應位為1;
}
}
}
}