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