2.1.2 器件和原理
本例主要介紹AVR單片機外圍電路中按鍵去抖電路的設(shè)計,分別介紹相應(yīng)的軟件和硬件解決方案。然后利用C語言編寫通過按鍵控制發(fā)光二極管亮滅狀態(tài)的程序。
1、按鍵的去抖動電路
(1)按鍵的響應(yīng)過程
我們?nèi)粘Kf的按鍵,實際上是一個機械開關(guān),本實例所用的按鍵外觀如圖2.1.1所示。理想的按鍵的閉合和斷開時,接觸點的電壓應(yīng)該立即變高或者變低,但
是由于機械觸點的彈性以及按鍵按動時電壓突變等原因,在觸點閉合或斷開的瞬間會出現(xiàn)電壓抖動現(xiàn)象,如圖2.1.2所示。在發(fā)生抖動的時間一般在
5-10ms。
一次按鍵處理過程如下:當(dāng)按鍵按下之后,相應(yīng)的按鍵接觸點的電壓以高低電平的方式輸入到單片機的I/O口。按鍵的閉合與斷開是有一定時間的,一般為
0.1-1S。而AVR單片機的機器周期一般為1us甚至更短,在0.1-1S的時間段內(nèi),程序會檢測很多次按鍵的輸入電平,這樣單片機可能會認為按鍵被
按下了多次,從而出現(xiàn)誤判。
圖2.1.1 按鍵開關(guān) 圖2.1.2 按鍵閉合斷開時的電壓波動示意圖
(2)按鍵去抖動的方法和原理
為了去除按鍵的抖動,保證單片機對按鍵的一次輸入只響應(yīng)一次,可以采用硬件和軟件兩種方法:硬件電路去抖動是在外圍電路中加入去抖動電路(如R-S觸發(fā)
器);軟件去抖動是在程序中加入延時程序以跳過抖動時間,等待信號穩(wěn)定后再次判斷按鍵的輸入電平,如果信號電平保持不變,則可以確認一次按鍵按下。
●硬件去抖動電路的原理
用R-S觸發(fā)器形成去抖電路是單片機外圍電路設(shè)計中常用的方法,這種方法可以減少單片機軟件對按鍵動作的延時和計算。
先來了解一下R-S觸發(fā)器的基本工作原理和工作特點。R-S觸發(fā)器的基本構(gòu)成如圖2.1.3所示,這個電路有兩個與非門交叉耦合而成,/S、/R是信號輸入端,低電平有效。Q和/Q既表示觸發(fā)器狀態(tài),又是觸發(fā)器的輸出端。
圖2.1.3 R-S觸發(fā)器的基本原理
在啟動過程中,/S端一旦下降到開門電平,Q端電平就會上升,反饋到門B的輸入端,此時門B在/R的低電平作用下處于導(dǎo)通狀態(tài),/Q輸出高電平反饋到A的
輸入端,如果這時/S端電壓有一個高的跳動,則A門截止,Q段輸出低電平,這個低電平反饋到A的輸入端,使A門導(dǎo)通,Q端電平為高,這樣就保證了Q端電平
的穩(wěn)定,從而消除按鍵的抖動。
典型的硬件去抖動電路如圖2.1.4,74LS02按鍵輸出端口通過/Q端接入單片機的I/O口,74LS02構(gòu)成一個R-S觸發(fā)器電路實現(xiàn)按鍵的消抖。
●軟件消抖的原理和實現(xiàn)
軟件消抖的基本原理是在軟件中對按鍵進行兩次檢測確認,記載第一次檢測到按鍵按下后,間隔10ms左右再次檢測按鍵是否按下,只有在兩次都檢測到按鍵按下時才最終確認有鍵按下,這樣就避開了按鍵的抖動時間,從而消除了抖動的影響。
圖2.1.4 74LS02實現(xiàn)的硬件消抖電路
在按鍵接口軟件的設(shè)計中,除了要考慮按鍵消抖外,一般還要判別按鍵的釋放,只有檢測到按鍵釋放后,才能確定為一次完整的按鍵動作。
通用的案件檢測程序如下:
[code="c"]
Keyscan()
{
if(!key) //判斷按鍵是否按下,key=0表示按鍵按下
{
delayms(20); //延時20ms。避開按鍵抖動時間
if(!key) //再次判斷按鍵是否按下,
{
… //按鍵按下的處理程序
}
}
While(!key); //判斷按鍵是否放開,key=1表示按鍵釋放,退出按鍵處理函數(shù)
}
[/code]
2.1.3 電路
本例中的電路如圖2.1.5和2.1.6所示。
1、電路原理
圖2.1.5是按鍵檢測電路,兩個按鍵分別連接到單片機的PD6、PD7管腳,AVR單片機在程序里把PD6、PD7設(shè)置為帶上拉的端口,這樣按鍵沒有按
下時,PD6、PD7處于高電平狀態(tài),當(dāng)按鍵按下時PD6、PD7被連接到地,電平狀態(tài)變?yōu)榈碗娖?,程序中檢測到PD6、PD7的電平為低電平時,就可以
認為按鍵被按下了。
圖2.1.6為LED顯示電路,當(dāng)按鍵K3被按下時,D1、D3、D5、D7點亮,D2、D4、D6、D8熄滅。當(dāng)按鍵K4被按下時,D1、D3、D5、D7熄滅,D2、D4、D6、D8點亮。
2、元器件選擇
在這里列出和本例相關(guān)的、關(guān)鍵部分的器件名稱及其在電路中的作用。
● ATmega16:單片機,檢測按鍵按下情況并控制發(fā)光二極管的亮滅。
● D1-D8:發(fā)光二極管,指示按鍵狀態(tài)。
● RP1:阻值為330Ω的排阻,限流電阻。
● K3、K4:按鍵,當(dāng)按鍵按下時,與按鍵連接的單片機端口的電平發(fā)生變化。
3、管腳連接
在這里列出和本例相關(guān)的、關(guān)鍵部分的單片機端口與外圍電路的連接。
● PB0-PB7:連接8個發(fā)光二極管LED1-LED8,控制發(fā)光二極管的亮滅。
● PD6、PD7:連接按鍵K3、K4,檢測兩個按鍵的狀態(tài)。
2.1.4 程序設(shè)計
1、程序功能
● 按鍵軟件消抖
本例中采用軟件消抖的方法,在程序中加入軟件延時,去除按鍵的抖動。
● 按鍵檢測
通過將單片機的PD6、PD7口設(shè)置為輸入狀態(tài),同時使能這兩個口的內(nèi)部上拉電阻(因為這兩個口在按鍵沒有按下時處于懸空狀態(tài),易受外界干擾,所以必須將其內(nèi)部上來電阻使能,使其平時處于高電平狀態(tài)),檢測按鍵是否按下。
通過將單片機的PB0-PB7口設(shè)置為輸出狀態(tài),根據(jù)K3、K4兩個按鍵的按下情況,控制不同的發(fā)光二極管點亮或熄滅。
● AVR單片機端口輸入狀態(tài)的讀取
AVR單片機端口配備有3個寄存器,分別是方向控制寄存器DDRx,數(shù)據(jù)寄存器PORTx,和輸入引腳寄存器PINx(x=A\B\C\D)。當(dāng)I/O工作在輸入方式,要讀取外部引腳上的電平時,應(yīng)讀取PINxn的值,而不是PORTxn的值。
2、主要變量和函數(shù)說明
無
3、使用WINAVR開發(fā)環(huán)境,makefile文件同前面的例子,直接復(fù)制到本實例程序的文件夾中即可。
4、程序代碼
[code="c"]
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
PORTB = 0X00; //輸出低,LED全部熄滅
DDRB = 0Xff; //PB端口置為輸出
PORTD = 0Xc0; //一定要使能上拉電阻,否則會有干擾
DDRD = 0X3F; //K3、K4按鍵(PD6、PD7)設(shè)置為輸入端口
while(1)
{
if(!(PIND & (1 << PD6))) //判斷按鍵是否按下
{
_delay_ms(20); //判斷按鍵按下,延時一會再判斷是否按下, 以消除干擾
if(!(PIND & (1 << PD6))) // 按鍵真正按下后,進行相應(yīng)處理
{
PORTB = 0X55; // 按鍵按下,燈亮
while(!(PIND & (1 << PD6)));//等待按鍵釋放
//PORTB = 0X55; // 把這句話從上面移到這里,按鍵釋放后,燈才點亮
}
}
if(!(PIND & (1 << PD7))) //判斷按鍵是否按下
{
_delay_ms(20); //判斷按鍵按下,延時一會再判斷是否按下, 以消除干擾
if(!(PIND & (1 << PD7))) // 按鍵真正按下后,進行相應(yīng)處理
{
PORTB = 0Xaa; //
while(!(PIND & (1 << PD7))); //
//PORTB = 0Xaa; //
}
}
}
}