06-矩阵键盘的基本操作
矩阵键盘的基本操作
1、矩阵键盘的扫描思想
与独立按键不同的是,按键的两个引脚都分别连接的单片机的I/O端口,一个作为行信号,另外一个作为列信号。我们以4X4的矩阵键盘为例,试着探讨其工作方式和扫描思路。
在上面的矩阵键盘中,要识别出黄色按键的按下状态,应该怎么做呢?
对于矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。因此,我们可以得到矩阵键盘的基本扫描步骤:
<1> R1输出点电平,R2、R3、R4输出高电平,逐个读取判断列信号,如果都为高电平则R1行上没有按键按下。
<2> R2输出点电平,R1、R3、R4输出高电平,逐个读取判断列信号。
<3> R3输出点电平,R1、R2、R4输出高电平,发现C2列信号为低电平,那么可以判断得R3行的C2列的按键有按下动作。
<4> R4输出点电平,R1、R3、R4输出高电平,逐个读取判断列信号。
如此循环往复,扫描的按键的状态。
我们知道有按键按下动作,那么又怎么知道是哪一个按键按下呢?这时,我们最好定义一个键值全局变量,给矩阵行列上的每一个的按键编一个唯一的号码。当扫描的某一行某一列的按键动作后,把对应的编号复制给键值变量,这样我们判断这个键值,就知道是那个按键有触发动作了。
由上可知:
对于该单片机与51单片机相比的差别在于电路变化,其P37=>P44 ,P36=>P42,且都按下后为低电平
代码如下:
#include <REGX52.H>
// 由于51单片机没有对于P4口的定义
sfr P4 = 0XC0;
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit R5 = P3^4;
sbit R6 = P3^5;
sbit R7 = P4^2;
sbit R8 = P4^4;
// 此数码管为共阳数码管
unsigned char code num[] = {
0xc0, //0 // 1100 0000
0xf9, //1 // 1111 1001
0xa4, //2 // 1010 0100
0xb0, // 3 // 1011 0000
// dp g f e d c b a
0x99, // 4 1001 1001
0x92, // 5 1 0 0 1 0 0 10
0x82, // 6 1 000 0010
0xf8, // 7 1111 1000
0x80, // 8 1000 0000
0x90, // 9 1001 0000
0x88, // A 1000 1000
0x83, // b 1000 0011
0xc6, // C 1100 0110
0xa1, // d 1010 0001
0x86, //E 1000 0110
0x8e // F 1000 1110
};
// 单片机使能
void SelectHC573(unsigned char chinnel) {
switch(chinnel) { // LED使能
case 4: P2 =(P2 & 0x1f) | 0x80;
break; // 蜂鸣器和继电器使能
case 5: P2 =(P2 & 0x1f) | 0xa0;
break; // 数码管位选使能
case 6: P2 =(P2 & 0x1f) | 0xc0;
break; // 数码管段选使能
case 7: P2 =(P2 & 0x1f) | 0xe0;
break;
}
}
// 初始化
void SystemInit(void) {
SelectHC573(4);
P0 = 0xFF; // LED回到初始状态,全关
SelectHC573(5);
P0 = 0x00; // 关闭蜂鸣器和继电器
}
void DisplayKeyNum(unsigned char value) {
SelectHC573(6);
P0 = 0x01; // 选择数码管第一位使能
SelectHC573(7);
P0 = value; // 段选传值
}
unsigned char Keynum;
void ScanKeyMulti(void) {
// 此采用逐行扫描模式
// 首先将该行所在的列全部置为高电平,如果有该行所在的列被按下时,就为低电平
R1 = 0; // P30 = 0
R2=R3=R4=R5=R6=R7=R8=1;
if(R8==0){while(R8==0);Keynum=0;DisplayKeyNum(num[Keynum]);} // S7
if(R7==0){while(R7==0);Keynum=1;DisplayKeyNum(num[Keynum]);} // S11
if(R6==0){while(R6==0);Keynum=2;DisplayKeyNum(num[Keynum]);} // S15
if(R5==0){while(R5==0);Keynum=3;DisplayKeyNum(num[Keynum]);} // S19
R2 = 0; // P31 = 0
R1=R3=R4=R5=R6=R7=R8=1;
if(R8==0){while(R8==0);Keynum=4;DisplayKeyNum(num[Keynum]);} // S6
if(R7==0){while(R7==0);Keynum=5;DisplayKeyNum(num[Keynum]);} // S10
if(R6==0){while(R6==0);Keynum=6;DisplayKeyNum(num[Keynum]);} // S14
if(R5==0){while(R5==0);Keynum=7;DisplayKeyNum(num[Keynum]);} // S18
R3 = 0; // P32=0
R1=R2=R4=R5=R6=R7=R8=1;
if(R8==0){while(R8==0);Keynum=8;DisplayKeyNum(num[Keynum]);} // S5
if(R7==0){while(R7==0);Keynum=9;DisplayKeyNum(num[Keynum]);} // S9
if(R6==0){while(R6==0);Keynum=10;DisplayKeyNum(num[Keynum]);} // S13
if(R5==0){while(R5==0);Keynum=11;DisplayKeyNum(num[Keynum]);} //S17
R4 = 0; // P33 = 0
R1=R3=R2=R5=R6=R7=R8=1;
if(R8==0){while(R8==0);Keynum=12;DisplayKeyNum(num[Keynum]);} // S4
if(R7==0){while(R7==0);Keynum=13;DisplayKeyNum(num[Keynum]);} // S8
if(R6==0){while(R6==0);Keynum=14;DisplayKeyNum(num[Keynum]);} // S12
if(R5==0){while(R5==0);Keynum=15;DisplayKeyNum(num[Keynum]);} // S16
}
void main() {
SystemInit();
while(1) {
ScanKeyMulti();
}
}