51單片機(jī)-按鍵
實(shí)現(xiàn)功能按一個(gè)鍵,相應(yīng)的燈亮。
左邊的是普通二極管,右邊的是發(fā)光二極管。左邊的二極管如果想導(dǎo)通,則右邊要比左邊電平低。如果導(dǎo)通就是按鍵可以控制燈亮,那么按鍵左下的都為低電平,系統(tǒng)復(fù)位時(shí)默認(rèn)I/O是高電平,所以給垂直方向的I/O拉低,這樣如果按鍵按下,電路導(dǎo)通,那么垂直方向I/O的低電平會(huì)把水平方向的拉低。這樣就可以通過檢測水平方向哪個(gè)I/O為低電平來檢測哪個(gè)鍵被按下。
開始時(shí)對程序的錯(cuò)誤想法:被按下的鍵兩邊肯定都是低電平,把它們存在一個(gè)數(shù)組里,然后檢測。這樣是不對的,用一個(gè)臨時(shí)變量去存P0的值,不會(huì)有相同的,開始P0的值為oxff,這樣即使按下按鍵,那么兩邊的引腳還是高電平,所以失敗了。
#include <reg52.h>
sbit p2_0 = P2^0;
sbit p2_1 = P2^1;
sbit p2_2 = P2^2;
sbit p2_3 = P2^3;
sbit p2_4 = P2^4;
sbit p2_5 = P2^5;
sbit p2_6 = P2^6;
sbit p2_7 = P2^7;
sbit L0 = P0^0;
sbit L1 = P0^1;
sbit L2 = P0^2;
sbit L3 = P0^3;
sbit H0 = P0^4;
sbit H1 = P0^5;
sbit H2 = P0^6;
sbit H3 = P0^7;
void delay(){
int i,j;
for(i = 0; i < 0xff; i++)
for(j = 0; j < 0xff; j++)
;
}
void display(){
P0 = 0xfe; //尋找按下的是哪個(gè)按鍵,先讓垂直的為低電平,
if(H0 == 0){p2_0 = 0; delay(); p2_0 = 1;} //然后通過檢測水平的來確定,延時(shí)為了消抖
if(H1 == 0){p2_1 = 0; delay(); p2_1 = 1;}
if(H2 == 0){p2_2 = 0; delay(); p2_2 = 1;}
if(H3 == 0){p2_3 = 0; delay(); p2_2 = 1;}
P0 = 0xfd;
if(H0 == 0){p2_4 = 0; delay(); p2_4 = 1;}
if(H1 == 0){p2_5 = 0; delay(); p2_5 = 1;}
if(H2 == 0){p2_6 = 0; delay(); p2_6 = 1;}
if(H3 == 0){p2_7 = 0; delay(); p2_7 = 1;}
P0 = 0xfb;
if(H0 == 0){p2_0 = 0; delay(); p2_0 = 1;}
if(H1 == 0){p2_1 = 0; delay(); p2_1 = 1;}
if(H2 == 0){p2_2 = 0; delay(); p2_2 = 1;}
if(H3 == 0){p2_3 = 0; delay(); p2_3 = 1;}
P0 = 0xf7;
if(H0 == 0){p2_4 = 0; delay(); p2_4 = 1;}
if(H1 == 0){p2_5 = 0; delay(); p2_5 = 1;}
if(H2 == 0){p2_6 = 0; delay(); p2_6 = 1;}
if(H3 == 0){p2_7 = 0; delay(); p2_7 = 1;}
}
void main(){
while(1){
display();
}
}
獨(dú)立按鍵:
實(shí)現(xiàn)功能,按一個(gè)獨(dú)立按鍵時(shí),一個(gè)燈亮,按另一個(gè)獨(dú)立按鍵,另一個(gè)燈亮。圖中的按鍵右下接地,
左邊通過跳線與P1.0和P1.1想接。如果按鍵按下,則P1.0和P1.1會(huì)被拉低。復(fù)位時(shí)默認(rèn)I/O口都
是高電平。這樣可以通過檢測P1.0和P1.1的電平,來檢查按鍵是否被按下。單片機(jī)I/O口是準(zhǔn)雙向
口,沒有方法控制單片機(jī)的輸入輸出方向。相當(dāng)于我們在每個(gè)口上都上拉了一個(gè)5V 10歐的電阻,這
樣單片機(jī)上電復(fù)位是高電平的。除了P0口都上拉了,P0內(nèi)部沒有上拉電阻,所以外部上拉。
#include <reg52.h>
sbit key1 = P1^0;
sbit key2 = P1^1;
sbit led1 = P2^0;
sbit led2 = P2^1;
void delay(){
int i,j;
for(i = 0; i < 0xff; i++)
for(j = 0; j < 0xff; j++)
;
}
void main(){
while(1){
if(key1 == 0){
delay(); //按鍵在閉合和斷開時(shí),觸點(diǎn)處會(huì)出現(xiàn)抖動(dòng),消除抖動(dòng)
if(key1 == 0) //延時(shí)一段時(shí)間后如果還是低電平,說明不是抖動(dòng)造成的,
led1 = "led1; //確實(shí)是按鍵被按下了,實(shí)現(xiàn)燈亮滅
}
if(key2 == 0){
delay();
if(key2 == 0)
led2 = "led2;
}
}
}
評論