
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
3.17 数码管显示4×4键盘矩阵按键
本例在识别键盘矩阵按键时,使用了不同的扫描程序代码,程序运行时数码管会显示相应按键的键值0~F。
本例电路如图3-14所示。
程序设计调试与实训:
读者要注意本例中P1端口低4位连接的是列线,高4位连接的是行线。
本例中键盘矩阵按键扫描思想与上一案例类似,但使用的代码有较大变化,而且没有再使用查表法得到按键序号,代码细节读者可以自行剖析。

图3-14 数码管显示4×4键盘矩阵按键电路
读者可在上一案例的键盘布局下重新修改本例扫描代码,实现按键识别功能。
另外,在本例及上一案例关于键盘矩阵单按键扫描的基础上,读者可修改代码,实现对多按键的判断(同时有2~3个按键按下)。在测试时,如果希望按键按下后不释放,然后再继续按第2个或第3个按键,这时不能用鼠标单击按键,而应单击按键旁边的上下箭头。
源程序代码:
//----------------------------------------------------------------- // 名称: 数码管显示4×4 键盘矩阵按键序号 //----------------------------------------------------------------- // 说明: 按下任意一按键时,数码管会显示它在键盘矩阵上的序号0~ F, // 扫描程序首先判断按键发生在哪一列,然后根据所发生的行附加 // 不同的值,从而得到键盘按键序号。 //----------------------------------------------------------------- #include <reg51.h> #define uchar unsigned char #define uint unsigned int //0~9,A~F的数码管段码,最后一个是黑屏 uchar code DSY_CODE[]= { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00 }; sbit BEEP = P3^7; //上次按键和当前按键序号,该矩阵中序号范围为0~15,16表示无按键 uchar Pre_KeyNo = 16, KeyNo = 16 ; //----------------------------------------------------------------- // 延时 //----------------------------------------------------------------- void DelayMS(uint ms) { uchar t; while(ms--) for(t = 0; t < 120; t++); } //----------------------------------------------------------------- // 键盘矩阵扫描 //----------------------------------------------------------------- void Keys_Scan() { uchar Tmp; //高4位置1,放入4行 P1 = 0x0F; DelayMS(1); //按键后00001111将变成0000XXXX,X中有1个为0,3个仍为1 //下面的异或操作会把3个1变成0,唯一的0变成1 Tmp = P1 ^ 0x0F; //判断按键发生于0~3列中的哪一列 switch (Tmp) { case 1: KeyNo = 0; break; case 2: KeyNo = 1; break; case 4: KeyNo = 2; break; case 8: KeyNo = 3; break; default: KeyNo = 16; //无键按下 } //低4位置0,放入4列 P1 = 0xF0; DelayMS(1); //按键后11110000将变成XXXX0000,X中有1个为0,3个仍为1 //下面的表达式会将高4位移到低4位,并将其中唯一的0变为1,其余为0 Tmp = P1 >> 4 ^ 0x0F; //对0~3行分别附加起始值0,4,8,12 switch (Tmp) { case 1: KeyNo += 0; break; case 2: KeyNo += 4; break; case 4: KeyNo += 8; break; case 8: KeyNo += 12; } } //----------------------------------------------------------------- // 蜂鸣器 //----------------------------------------------------------------- void Beep() { uchar i; for (i = 0; i < 100; i++) { DelayMS(1); BEEP = ~BEEP; } BEEP = 1; } //----------------------------------------------------------------- // 主程序 //----------------------------------------------------------------- void main() { P0 = 0x00; while(1) { P1 = 0xF0; if(P1 != 0xF0) Keys_Scan(); //扫描键盘获取按键序号KeyNo if (Pre_KeyNo != KeyNo) { P0 = ~DSY_CODE[KeyNo]; //显示(用~作共阴共阳转换) Beep(); Pre_KeyNo = KeyNo; } DelayMS(100); } }