一、矩陣鍵盤的原理
矩陣鍵盤又稱為行列式鍵盤,它是用4條I/O線作為行線,4條I/O線作為列線組成的鍵盤。在行線和列線的每一個交叉點上,設置一個按鍵。這樣鍵盤中按鍵的個數是4×4個。
這種行列式鍵盤結構能夠有效地提高單片機系統中I/O口的利用率。由於單片機IO端口具有線與的功能,因此當任意一個按鍵按下時,行和列都有一根線被線與,通過運算就可以得出按鍵的坐標從而判斷按鍵鍵值。
二、驅動電路圖
三、軟件程序設計
1.行掃描式代碼
1 /*------------------------------------------------ 2 按鍵掃描函數,返回掃描鍵值 3 ------------------------------------------------*/
4 define Key P1 5 unsigned char KeyScan(void) //鍵盤掃描函數,使用行列逐級掃描法
6 { 7 unsigned char Val; 8 Key=0xf0;//高四位置高,低四位拉低
9 if(Keyt!=0xf0)//判斷是否有按鍵按下
10 { 11 DelayMs(10); //消抖
12 if(Key!=0xf0) //再次判斷是否有按鍵按下
13 { 14 Key=0xfe; //檢測第一行
15 if(Key!=0xfe) 16 { 17 Val=Key&0xf0; 18 Val+=0x0e; 19 while(Key!=0xfe); //等待松手
20 DelayMs(10); //消抖
21 while(Key!=0xfe); 22 return Val; 23 } 24 Key=0xfd; //檢測第二行
25 if(Key!=0xfd) 26 { 27 Val=Key&0xf0; 28 Val+=0x0d; 29 while(Key!=0xfd); 30 DelayMs(10); //去抖
31 while(Key!=0xfd); 32 return Val; 33 } 34 Key=0xfb; //檢測第三行
35 if(Key!=0xfb) 36 { 37 Val=Key&0xf0; 38 Val+=0x0b; 39 while(Key!=0xfb); 40 DelayMs(10); //去抖
41 while(Key!=0xfb); 42 return Val; 43 } 44 Key=0xf7; //檢測第四行
45 if(Key!=0xf7) 46 { 47 Val=Key&0xf0; 48 Val+=0x07; 49 while(Key!=0xf7); 50 DelayMs(10); //去抖
51 while(Key!=0xf7); 52 return Val; 53 } 54 } 55 } 56 return 0xff; 57 } 58 /*------------------------------------------------ 59 按鍵值處理函數,返回掃鍵值 60 ------------------------------------------------*/
61 unsigned char KeyPro(void) 62 { 63 switch(KeyScan()) 64 { 65 case 0xee:0; break; 66 case 0xde: 1; break; 67 case 0xbe: 2; break; 68 case 0x7e: 3; break; 69 case 0xed: 4; break; 70 case 0xdd: 5; break; 71 case 0xbd: 6; break; 72 case 0x7d: 7; break; 73 case 0xeb: 8; break; 74 case 0xdb: 9; break; 75 case 0xbb: 10; break; 76 case 0x7b: 11; break; 77 case 0xe7: 12; break; 78 case 0xd7: 13; break; 79 case 0xb7: 14; break; 80 case 0x77: 15; break; 81
82 default:break; 83
84 } 85
86 }
2.行列式掃描
- 以按鍵S2被按下為例
1 /*------------------------------------------------ 2 按鍵掃描函數,返回掃描鍵值 3 ------------------------------------------------*/
4 #define Key P1
5 unsigned char KeyScan(void) //鍵盤掃描函數,使用行列反轉掃描法
6 { 7 unsigned char cord_h,cord_l;//保存行列值變量
8 Key=0xf0; //行線輸出全為0
9 temp=Key&0xf0; //讀入列線值(1101 0000)
10 if( temp!=0xf0) //先檢測有無按鍵按下
11 { 12 DelayMs(10); //軟件消抖
13 if((Key&0xf0)!=0xf0)//再次判斷是否有按鍵被按下 14 { 15 cord_l=Key & 0xf0; //讀取列線值(1101 0000)
16 Key=cord_l | 0x0f; //將行線的值全部拉高(1101 1111)
cord_h=Key; //重新讀取端口P1的值,盡管按鍵被按下的速度很快,但對單片機來說時間是足夠的(1101 1110)【因為此時S2還沒有被松開,所以S2的行、列線值都為0】
17 cord_h=cord_h & 0x0f; //讀取行線值(0000 1110)
18
19 while((Key&0xf0)!=0xf0);//等待松開並輸出
20
21 return(cord_h+cord_l);//鍵盤最后組合碼值(1101 1110)
22 } 23 }return(0xff); //返回該值
24 } 25 /*------------------------------------------------ 26 按鍵值處理函數,返回掃鍵值 27 ------------------------------------------------*/
28 unsigned char KeyPro(void) 29 { 30 switch(KeyScan()) 31 { 32 case 0xee:return 0;break;//0 按下相應的鍵顯示相對應的碼值
33 case 0xde:return 1;break;//1
34 case 0xbe:return 2;break;//2
35 case 0x7e:return 3;break;//3
36 case 0xed:return 4;break;//4
37 case 0xdd:return 5;break;//5
38 case 0xbd:return 6;break;//6
39 case 0x7d:return 7;break;//7
40 case 0xde:return 8;break;//8
41 case 0xdd:return 9;break;//9
42 case 0xdb:return 10;break;//a
43 case 0xd7:return 11;break;//b
44 case 0xee:return 12;break;//c
45 case 0xed:return 13;break;//d
46 case 0xeb:return 14;break;//e
47 case 0xe7:return 15;break;//f
48 default:return 0xff;break; 49 } 50 } 51 ————————————————