摘要:單片機控制系統中大多使用控制鍵來實現控制功能。消除按鍵瞬間的抖動是設計者必須要考慮的問題。該文介紹了常用的一些對按鍵進行去抖動處理的硬件和軟件方法,來保證微機系統的正確工作。
關鍵詞:單片機;鍵處理;去抖動
中圖分類號:TP334文獻標識碼:A文章編號:1009-3044(2008)26-1831-03
The Ways of Elimination of Key Jitter
LIU Yan
(The Information Department of Ningxia Vocational Technological Institution, Yinchuan 750002, China)
Abstract: SCM control system ofen be used control keys to achieve control. Elimination of jitter of the key moment must be consider by the designers. In this paper, some of the commonly used of the hardware and software methods to deal with the jitter of keys are Introducted to ensure that computer systems work correctly.
Key words: singlechip; dealing with key; elimination of jitter
1 引言
鍵盤是由若干按鍵組成的開關矩陣,他是單片機最簡單的輸入設備。操作員通過鍵盤輸入數據或命令,實現簡單的人際對話。組成鍵盤的按鍵有觸點式和非觸點式兩種,單片機中應用的一般是由機械觸點構成的,當機械觸點斷開、閉合時,由于機械觸點的彈性作用,一個按鍵開關在閉合時不會馬上穩定地接通,在斷開時也不會一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動,造成如下波形圖(圖1)所顯示的毛刺。抖動時間的長短由按鍵的機械特性決定,一般為5ms~10ms。抖動可能造成一次按鍵的多次處理問題,所以應采取措施消除抖動的影響。消除辦法有多種,下面將對各種消除方式的實現及特點做一探討。
2 硬件方法
在鍵開關與單片機接口之間加一個消抖動電路,如雙穩電路、單穩電路。在硬件上可采用在,如圖2是鍵輸出端加R-S觸發器(雙穩態觸發器)或單穩態觸發器構成去抖動電路,當觸發器一旦翻轉,觸點抖動不會對其產生任何影響。
電路工作過程如下:按鍵未按下時,A=0,B=1,輸出Q=1,按鍵按下時,因按鍵的機械彈性作用的影響,使按鍵產生抖動,當開關沒有穩定到達B端時,因與非門2輸出為0反饋到與非門1的輸入端,封鎖了與非門1,雙穩態電路的狀態不會改變,輸出保持為1,輸出Q不會產生抖動的波形。當開關穩定到達b端時,因A=1,B=0,使Q=0,雙穩態電路狀態發生翻轉。當釋放按鍵時,在開關未穩定到達A端時,因Q=0,封鎖了與非門2,雙穩態電路的狀態不變,輸出Q保持不變,消除了后沿的抖動波形。當開關穩定到達B端時,因A=0,B=0,使Q=1,雙穩態電路狀態發生翻轉,輸出Q重新返回原狀態。由此可見,鍵盤輸出經雙穩態電路之后,輸出已變為規范的矩形方波。
由于硬件去抖動增加了電路的復雜性,每個按鍵都要一個去抖動電路,而且硬件方法會增加成本和體積。所以這種方法只適用于鍵數目較少的場合。
3 軟件延時10ms
就是通過延時來等候信號穩定,在信號穩定以后再去識別鍵碼。其過程是在檢查到有鍵按下以后調用延時子程序延時一段時間(5ms~20ms),再檢查一次看是否有按鍵按下。若這一次檢查不到,則說明前一次結果為干擾或者抖動。若這一次檢查到有按鍵按下,則說明信號已經穩定,然后判斷閉合按鍵的鍵碼。當閉合按鍵的鍵碼確定以后,再去檢查按鍵是否釋放,待按鍵釋放以后再進行處理,這樣就可以消除釋放抖動的干擾。
下面是一個4×4矩陣式鍵盤的去抖動程序:(設行線接至單片機的輸入口P1.0~P1.3,列線接至單片機的輸出口P1.4~P1.7 ,當鍵盤上沒有鍵閉合時,所有的行線與列線是斷開的,判有無按鍵按下時,首先使所有的列線為低電平。)
SMKEY: MOV P1,#0FH; 置P1口高4位為“0”、低4位為輸入狀態
MOV A, P1; 讀P1口
ANL A,#0FH;屏蔽高4位
CJNE A,#0FH,HKEY; 有鍵按下,轉HKEY
SJMP SMKEY ;無鍵按下返回
HKEY:LCALLDELAY10; 延時10ms,去抖
MOV A,P1
ANL A,#0FH
CJNE A, #0FH,WKEY ; 確認有鍵按下,轉判哪一鍵按下
SJMPSMKEY ; 是抖動返回
WKEY: … …;判斷按下的是哪一個鍵
… …
當按鍵較多時,常采用軟件延時的辦法,因為這種方法比較簡單,不需要增加成本,所以在大多數微機控制系統中常常使用,但是加固定延時的去抖動法效率最低,它以無謂地耗費機時來實現去抖動。
4 中斷配合的軟件方法
4.1 基本原理
由于按鍵的按下與抬起都會有10~20ms的抖動毛刺存在,因此,為了獲取穩定的按鍵信息,須要避開這段抖動期。
設置3個變量Kready、Ktemp和Kinput,并設置定時中斷周期為20ms。在定時中斷服務程序中讀取按鍵,并把讀取的數據存于變量Kinput中。變量Kready中是所需要的穩定的按鍵信息;Ktemp是中間變量,它的值是上一次的Kinput。
根據當前按鍵的狀態,考慮到Kready中是20ms抖動后的有效鍵信息,則Kready、Ktemp和Kinput之間,在不同時刻的狀態關系如表1所列。
時刻1為沒有鍵按下的初始狀態;時刻2的Kinput為1,但時刻3的Kinput又變為0,說明時刻2的Kinput為1并不是有鍵按下,可能只是干擾,所以 Kready 為0;時刻4同時刻2的情況類似,但是時刻4和時刻5時Kinput都為1,說明有按鍵按下,在時刻5時Kready為1;雖然時刻7時Kinput為0,但時刻5、6、8時Kinput都為1,說明按鍵一直按下,只不過有干擾,Kready保持為1;時刻9、10連續兩個時刻Kinput為0,表示按鍵抬起,時刻10時Kready為0。
通過分析可以看出,Kready中是消除了抖動并在一定程度上排除了干擾的有效按鍵信息。從按鍵按下到Kready為1,最長時間約為40ms,最短約為20ms。其時間長短取決于鍵按下時處于定時中斷周期的所在時刻。如果按鍵一直按下,則有效鍵信息以20ms的間隔重復輸出。
仔細分析表1,還可知道當前時刻Kready的值不但與Ktemp和Kinput有關,還與Kready前一時刻的值有關。我們把Kready的當前時刻記作Kreadyn,作為因變量;前一時刻記作Kreadyn-1,并和Ktemp、Kinput一起作為自變量,依照表1繪出卡諾圖如圖3所示。
由卡諾圖可得出最簡邏輯表達式如下:
Kreadyn=Ktemp Kinput+Kreadyn-1 (Ktemp⊙Kinput)
Ktemp=Kinput
通過軟件編程利用上面的邏輯運算表達式,配合定時中斷讀取按鍵,可以獲得消除抖動的按鍵消息。這種方法效率高,不需耗時的循環等待,而且算法簡單、使用方便。
4.2 應用程序實例
為了進一步理解上述方法如何在編程中得以實現,在此提供了1個用C51單片機編程語言編制的8個按鍵的鍵處理程序,以供參考。該程序在KEIL C51 V6.02/uVsion2 demo編譯環境下編譯通過。
#include
#include
unsigned char key_value;
unsigned char Kinput;
unsigned char Ktemp;
unsigned char Kready;
unsigned char bdata flag;
sbit endebounce=flag^0;
sbit getkey=iag^1;
sbit kprocess=flag^2;
sbit ACC_7=ACC^7;
void main(void);
void debounce(void);
void get_key_value(void);
void main(void)
{/*初始化*/
kinput=Ktemp=kready=Kstore=0;
endebounce=0;
getkey=0;
kprocess=0;
TMOD=0x01;
TL0=0xe0;
TH0=0xb1;
TR0=1;
ET0=1;
EA=1;
/*……*/
while(1)/*循環*/
{debounce();/*調用去除鍵抖動函數*/
get_key_value();/*調用獲取鍵值函數*/
key_processing();/*調用鍵處理函數*/
/*other functions*/}
}
void debounce(void)
{if (endebounce)
{/*以下是去除鍵抖動表達式*/
Kready=Ktemp Kinput |Kready (Ktemp^Kinput);
Ktemp=Kinput;
if (Kready ! =0)/*如果有鍵按下,置標志準備獲取鍵值*/
getkey=1;}
}
void get_key_value(void)
{if(getkey)
{unsigned char temp;
unsigned char j;
getkey=0;/*清標志*/
for(j=0;j<8;j++)
{temp=_cror_(kready,1);/*循環右移尋找按下的鍵*/
if(_testbit_(ACC_7))/*如果ACC_7=1,找到了按下的鍵*/
{key_value=j;/*獲得鍵值*/
j=8;/*找到按下的鍵就退出循環*/
kprocess=1;/*置標志,準備進行鍵處理*/}
else Kready=temp;/*準備下一次尋找*/}}
}
void timer0_interrupt_handler(void) interrupt using1
{TL0=0xe0;/*加載定時器參數,使晶振頻率12MHz時中斷周期為20ms*/
TH0=0xb1;
/*鍵掃描*/
P2_0;/*使能鍵掃描位*/
Kinput=~P0;/*從P0讀入按鍵信息,反相后保存*/
endebounce;/*置標志位準備去抖動*/
/*其它與定時器有關的語句*/
}
5 結束語
在實際應用中,1個比特表示1個鍵。C51中的字符變量可以處理8個鍵,如果系統需要更多的鍵,可選用整型變量、長整型變量或數組。如果系統的按鍵數量過多,則會占用較多單片機寶貴的內部寄存器,這是該方法的不足之處。單片機應用系統中,對按鍵的要求是千差萬別的,可根據不同的需要來選擇不同的消除鍵抖動的方法。
參考文獻:
[1] 李全利.單片機原理及應用技術[M].2版.北京:高等教育出版社,2005.
[2] 肖廣安.一種軟件去除鍵抖動的方法[J].單片機與嵌入式系統應用,2001,(7):241-243.
[3] 方龍,肖獻保,李威.關于消除按鍵機械抖動的研究[J].廣西輕工業,2008,(1):92,105.