4*4矩阵键盘 - Tan先森
一、矩阵键盘的原理
矩阵键盘又称为行列式键盘,它是用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 ————————————————