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输出高电平,逐个读取判断列信号。
如此循环往复,扫描的按键的状态。
我们知道有按键按下动作,那么又怎么知道是哪一个按键按下呢?这时,我们最好定义一个键值全局变量,给矩阵行列上的每一个的按键编一个唯一的号码。当扫描的某一行某一列的按键动作后,把对应的编号复制给键值变量,这样我们判断这个键值,就知道是那个按键有触发动作了。
#include "reg52.h" sfr P4 = 0xc0; //若使用15芯片的头文件,可正常命名 sbit R1 = P3^0; sbit R2 = P3^1; sbit R3 = P3^2; sbit R4 = P3^3; sbit C4 = P3^4; sbit C3 = P3^5; sbit C2 = P4^2; sbit C1 = P4^4; unsigned char code SMG_duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90,0x88, 0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; void ScanKeysMulti(); void DisPlayKeyNum(); void SelectHC573(); void SelectHC573(unsigned char channel) { switch(channel) { 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 DisPlayKeyNum(unsigned char value) { SelectHC573(6); P0 = 0x01; SelectHC573(7); P0 = value; } unsigned char key_num ; void ScanKeysMulti() //键盘扫描函数 { R1 = 0; //第一次扫描 R2 = R3 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1==0) { while(C1==0); key_num = 0; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num = 1; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num = 2; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num = 3; DisPlayKeyNum(SMG_duanma[key_num]); } R2 = 0; //第二次扫描 R1 = R3 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1==0) { while(C1==0); key_num = 4; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num = 5; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num = 6; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num = 7; DisPlayKeyNum(SMG_duanma[key_num]); } R3 = 0; //第三次扫描 R2 = R1 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1==0) { while(C1==0); key_num = 8; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num = 9; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num = 10; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num = 11; DisPlayKeyNum(SMG_duanma[key_num]); } R4 = 0; //第四次扫描 R2 = R3 = R1 = 1; C1 = C2 = C3 = C4 = 1; if(C1==0) { while(C1==0); key_num = 12; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C2==0) { while(C2==0); key_num = 13; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C3==0) { while(C3==0); key_num = 14; DisPlayKeyNum(SMG_duanma[key_num]); } else if(C4==0) { while(C4==0); key_num = 15; DisPlayKeyNum(SMG_duanma[key_num]); } } void main() { while(1) { ScanKeysMulti(); } }