前言
前幾章介紹的都是IO 口輸出的使用,這一教程我們通過獨(dú)立按鍵實(shí)驗(yàn)來介紹IO 口作為輸入的使用。開發(fā)板上板載8 個(gè)獨(dú)立按鍵。本教程所要實(shí)現(xiàn)的功能是:通過開發(fā)板上的獨(dú)立按鍵K1 控制D1 指示燈亮滅。大家可以參考前面的實(shí)驗(yàn)內(nèi)容。
一、按鍵介紹
按鍵是一種電子開關(guān),使用時(shí)輕輕按開關(guān)按鈕就可使開關(guān)接通,當(dāng)松開手時(shí),開關(guān)斷開。開發(fā)板上使用的按鍵及內(nèi)部簡易圖如下圖所示:
按鍵管腳兩端距離長的表示默認(rèn)是導(dǎo)通狀態(tài),距離短的默認(rèn)是斷開狀態(tài), 如果按鍵按下,初始導(dǎo)通狀態(tài)變?yōu)閿嚅_,初始斷開狀態(tài)變?yōu)閷?dǎo)通。
通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),電壓信號如下圖所示:
由于機(jī)械點(diǎn)的彈性作用,按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定的接通,在斷開時(shí)也不會(huì)一下子斷開,因而在閉合和斷開的瞬間均伴隨著一連串的抖動(dòng)。抖動(dòng)時(shí)間的長短由按鍵的機(jī)械特性決定的,一般為5ms 到10ms。按鍵穩(wěn)定閉合時(shí)間的長短則由操作人員的按鍵動(dòng)作決定的,一般為零點(diǎn)幾秒至數(shù)秒。按鍵抖動(dòng)會(huì)引起按鍵被誤讀多次。為了確保CPU 對按鍵的一次閉合僅作一次處理,必須進(jìn)行消抖。
按鍵消抖有兩種方式,一種是硬件消抖,另一種是軟件消抖。為了使電路更加簡單,通常采用軟件消抖。我們開發(fā)板也是采用軟件消抖,一般來說一個(gè)簡單的按鍵消抖就是先讀取按鍵的狀態(tài),如果得到按鍵按下之后,延時(shí)10ms,再次讀取按鍵的狀態(tài),如果按鍵還是按下狀態(tài),那么說明按鍵已經(jīng)按下。其中延時(shí)10ms 就是軟件消抖處理,至于硬件消抖,大家可以百度了解下,網(wǎng)上都有非常詳細(xì)的介紹。這里給大家列出單片機(jī)常用的軟件去抖動(dòng)方法:
1,先設(shè)置IO 口為高電平(由于開發(fā)板IO 都有上拉電阻,所以默認(rèn)IO 為高電平)。
2,讀取IO 口電平確認(rèn)是否有按鍵按下。
3,如有IO 電平為低電平后,延時(shí)幾個(gè)毫秒。
4,再讀取該IO 電平,如果仍然為低電平,說明按鍵按下。
5,執(zhí)行按鍵控制程序。
獨(dú)立按鍵電路構(gòu)成是由各個(gè)按鍵的一個(gè)管腳連接在一起接地,按鍵其他引腳
分別接到單片機(jī)IO 口。我們知道單片機(jī)的IO 口既可作為輸出也可作為輸入使用,當(dāng)檢測按鍵時(shí)用的是它的輸入功能,獨(dú)立按鍵的一端接地, 另一端與單片機(jī)的I/O 口相連,開始時(shí)先給該IO 口賦一高電平,然后讓單片機(jī)不斷地檢測該I/O 口是否變?yōu)榈碗娖?,?dāng)按鍵閉合時(shí),即相當(dāng)于該I/O 口通過按鍵與地相連,變成低電平,程序一旦檢測到I/O 口變?yōu)榈碗娖絼t說明按鍵被按下,然后執(zhí)行相應(yīng)的指令。
二、硬件設(shè)計(jì)
本實(shí)驗(yàn)使用到硬件資源如下:
(1)LED 模塊中D1 指示燈
(2)K1 按鍵
LED 模塊電路在前面章節(jié)都介紹過,這里就不多說,開發(fā)板上的獨(dú)立按鍵模塊電路如下圖所示:
從上圖中可以看出,該電路是獨(dú)立的,8 個(gè)獨(dú)立按鍵的控制管腳并未直接連接到51 單片機(jī)的IO 上,而是連接到JP1 端子上。如果要想51 單片機(jī)能夠檢測按鍵是否按下,就必須將單片機(jī)管腳通過導(dǎo)線連接到JP1 端子上。因此需使用一根8Pin 排線將單片機(jī)的管腳與JP1 端子順序連接。由于獨(dú)立按鍵模塊電路是獨(dú)立的,所以使用任意單片機(jī)管腳都可以,為了與我們例程程序配套,這里使用P3.1 口來檢測K1 按鍵,使用P2.0 管腳控制D1指示燈。
三、軟件設(shè)計(jì)
本教程所要實(shí)現(xiàn)的功能是:通過開發(fā)板上的獨(dú)立按鍵K1 控制D1 指示燈亮滅。
???????
#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit KEY1=P3^1;
sbit KEY2=P3^2;
sbit KEY3=P3^3;
sbit KEY4=P3^4;
sbit LED1=P2^0;
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY1_UNPRESS 0
void delay_10us(u16 time_us)//延時(shí)函數(shù)
{
while(time_us--);
}
u8 key_scan(u8 mode)
{
static u8 key=1;
if(mode==1)
{
key=1;//連續(xù)掃描按鍵
}
if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按鍵按下
{
delay_10us(1000);//消抖
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)//無按鍵按下
{
key=1;
return KEY1_UNPRESS;
}
}
void main()
{
u8 key=0;
while(1)
{
key=key_scan(0);
if(key==KEY1_PRESS)//檢測按鍵K1是否按下
{
LED1=!LED1;//LED1狀態(tài)翻轉(zhuǎn)
}
}
}
key_scan 函數(shù)帶一個(gè)形參mode,該參數(shù)用來設(shè)定是否連續(xù)掃描按鍵,如果mode 為0,只能操作一次按鍵,只有當(dāng)按鍵松開后才能觸發(fā)下次的掃描,這樣做的好處是可以防止按下一次出現(xiàn)多次觸發(fā)的情況。如果mode 為1,函數(shù)是支持連續(xù)掃描的,即使按鍵未松開,在函數(shù)內(nèi)部有if(mode==1)這條判斷語句,因此key 始終是等于1 的,所以可以連續(xù)掃描按鍵,當(dāng)按下某個(gè)按鍵,會(huì)一直返回這個(gè)按鍵的鍵值,這樣做的好處是可以很方便實(shí)現(xiàn)連按操作。函數(shù)內(nèi)的delay_10us(1000)即為軟件消抖處理,通常延時(shí)10ms 即可。
key_scan 函數(shù)還帶有一個(gè)返回值,如果未有按鍵按下,返回值即KEY_UNPRESS,否則返回值即為對應(yīng)按鍵的鍵值,如KEY1_PRESS、KEY2_PRESS、KEY3_PRESS、KEY4_PRESS,這都是程序開頭定義好的宏,方便大家理解和使用。函數(shù)內(nèi)定義了一個(gè)static 變量key,相當(dāng)于全局變量,所以該函數(shù)不是一個(gè)可重入函數(shù)。還有一點(diǎn)要注意的就是該函數(shù)按鍵的掃描是有優(yōu)先級的,因?yàn)楹瘮?shù)內(nèi)用了if...else if...else 格式,所以最先掃描處理的按鍵是KEY1,其次是KEY2,然后是KEY3,最后是KEY4。如果需要將其優(yōu)先級設(shè)置一樣,那么可以全部用if 語句。文章來源:http://www.zghlxwxcb.cn/news/detail-455108.html
main 函數(shù)中主要就是調(diào)用key_scan 函數(shù)用于檢測按鍵,此時(shí)傳入的mode值為0,表示單次掃描按鍵,然后將掃描按鍵的值保存在變量key 中,最后通過if 判斷語句控制LED1 狀態(tài)。文章來源地址http://www.zghlxwxcb.cn/news/detail-455108.html
到了這里,關(guān)于51單片機(jī) --獨(dú)立按鍵的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!