矩陣按鍵: 實現功能按一個鍵,相應的燈亮。 左邊的是普通二極管,右邊的是發光二極管。左邊的二極管如果想導通,則右邊要比左邊電平低。如果導通就是按鍵可以控制燈亮,那么按鍵左下的都為低電平,系統復位時默認I/O是高電平,所以給垂直方向的I/O拉低,這樣如果按鍵按下,電路導通,那么垂直方向I/O的低電平會把水平方向的拉低。這樣就可以通過檢測水平方向哪個I/O為低電平來檢測哪個鍵被按下。 開始時對程序的錯誤想法:被按下的鍵兩邊肯定都是低電平,把它們存在一個數組里,然后檢測。這樣是不對的,用一個臨時變量去存P0的值,不會有相同的,開始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; //尋找按下的是哪個按鍵,先讓垂直的為低電平, 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_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(); } } 獨立按鍵: 實現功能,按一個獨立按鍵時,一個燈亮,按另一個獨立按鍵,另一個燈亮。圖中的按鍵右下接地, 左邊通過跳線與P1.0和P1.1想接。如果按鍵按下,則P1.0和P1.1會被拉低。復位時默認I/O口都 是高電平。這樣可以通過檢測P1.0和P1.1的電平,來檢查按鍵是否被按下。單片機I/O口是準雙向 口,沒有方法控制單片機的輸入輸出方向。相當于我們在每個口上都上拉了一個5V 10歐的電阻,這 樣單片機上電復位是高電平的。除了P0口都上拉了,P0內部沒有上拉電阻,所以外部上拉。 #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(); //按鍵在閉合和斷開時,觸點處會出現抖動,消除抖動 if(key1 == 0) //延時一段時間后如果還是低電平,說明不是抖動造成的, led1 = "led1; //確實是按鍵被按下了,實現燈亮滅 } if(key2 == 0){ delay(); if(key2 == 0) led2 = "led2; } } } 李萬鵬 |