矩阵键盘 (J5的跳帽决定是使用S7~S4这四个独立键盘还是使用矩阵键盘)
用P3口的高低4位分别接4x4键盘的行和列。
键盘扫描使用行列反转法。个人感觉比一行一行的行扫描法简单清楚。
具体操作例:
例程如下:
//读取矩阵键盘键值:转接板中使用P42和P44代替8051引脚
//顺序中的P36和P37引脚
unsigned char read_keyboard(void)
{
static unsigned char col;
P3 = 0xf0; P42 = 1; P44 = 1; //列扫描
if((P3 != 0xf0)||(P42 != 0)||(P44 != 0)) //有按键按下
key_press++;
else
key_press = 0; //抖动
if(key_press == 3)
{
key_press = 0;
key_re = 1;
if(P44 == 0) col = 1;
if(P42 == 0) col = 2;
if((P3 & 0x20) == 0) col = 3;
if((P3 & 0x10) == 0) col = 4;
P3 = 0x0F; P42 = 0; P44 = 0; //列扫描结束后再行扫描
key_press++;
else
key_press = 0; //抖动
if(key_press == 3)
{
key_press = 0;
key_re = 1;
if(P44 == 0) col = 1;
if(P42 == 0) col = 2;
if((P3 & 0x20) == 0) col = 3;
if((P3 & 0x10) == 0) col = 4;
P3 = 0x0F; P42 = 0; P44 = 0; //列扫描结束后再行扫描
if((P3&0x01) == 0) key_value = (col-1);
if((P3&0x02) == 0) key_value = (col+3);
if((P3&0x04) == 0) key_value = (col+7);
if((P3&0x08) == 0) key_value = (col+11);
}
//连续三次检测到按键被按下,并且该按键已经释放
P3 = 0x0f; P42 = 0; P44 = 0; //低4位对应行、高四位对应列。恢复行扫描状态
if(((key_re == 1) && (P3 == 0x0f))&&(P42 == 0)&&(P44 == 0)) //确定按键按下而且处于行扫描状态
{
key_re = 0;
return key_value; //返回键值
}
return 0xff; //无按键按下或被按下的按键未被释放 的标志
}
if((P3&0x02) == 0) key_value = (col+3);
if((P3&0x04) == 0) key_value = (col+7);
if((P3&0x08) == 0) key_value = (col+11);
}
//连续三次检测到按键被按下,并且该按键已经释放
P3 = 0x0f; P42 = 0; P44 = 0; //低4位对应行、高四位对应列。恢复行扫描状态
if(((key_re == 1) && (P3 == 0x0f))&&(P42 == 0)&&(P44 == 0)) //确定按键按下而且处于行扫描状态
{
key_re = 0;
return key_value; //返回键值
}
return 0xff; //无按键按下或被按下的按键未被释放 的标志
}
HC138译码器
最小系统图(含复位、时钟电路)
其中WR是P36 ——写线。
Y6C选通说明锁存选择数码管的端口;Y7C选通要锁存显示的数字。
因此显示函数需要P27~P25口→38译码器→Y6C→HC02(或非门)→HC573数据锁存器U8→com端高四位选择DS2低四位DS1数码管(位选),com端对应4个数码管。
→P27~P25口→38译码器→Y7C→HC02(或非门)→HC573数据锁存器U7→abcd~g、dp。(数码管段选,显示数据)
因此过程是P2口→P0口。控制数码管显示,且需要两次操作。
P.S.:数码管是共阳数码管。
锁存芯片的特点如图:
LE为低电平时就不能实时锁存,而是一直保持状态。