矩阵键盘扫描原理
独立按键:接上拉电阻,按键未按下时稳定输出高电平。按下按键,引脚接地,读到低电平。
矩阵键盘:两别都接在了IO口上。若左边IO口为0,按键按下右边读出低电平,未被按下则读出高电平。
扫描思路:先选中一行,使IO口为低电平,依次扫描列,若读出的IO口为低电平,则按键被按下,依次重复上述操作。
练习内容
代码部分
注意:新板子没有P4口,使用前要定义
这里定义的第一行第一列为右上角的那个按键
16个按键,这里只用一位数码管显示按键值,对应0~F的段码值
#include "reg52.h"
#include "delay.h"
sfr P4=0xC0;//新板子没有P4口,要定义
sbit r1=P3^0;//行
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
sbit c1=P3^4;//列
sbit c2=P3^5;
sbit c3=P4^2;
sbit c4=P4^4;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};//0~F,“-”,“.”对应段码
//声明为“code”,节约ram区资源
unsigned char keynum=0;
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 display(unsigned char value)
{
selecthc573(6);//位选
P0=0x01;
selecthc573(7);//段选
P0=value;
}
void scanmulti()
{
r1=0;//选中第一行
r2=r3=r4=1;
c1=c2=c3=c4=1;
if(c1==0)
{
delayxms(20);//去抖动
while(c1==0);//等待按键松开
delayxms(20);//去抖动
keynum=0;
display(SMG_duanma[keynum]);
}
else if(c2==0)
{
delayxms(20);//去抖动
while(c2==0);//等待按键松开
delayxms(20);//去抖动
keynum=1;
display(SMG_duanma[keynum]);
}
else if(c3==0)
{
delayxms(20);//去抖动
while(c3==0);//等待按键松开
delayxms(20);//去抖动
keynum=2;
display(SMG_duanma[keynum]);
}
else if(c4==0)
{
delayxms(20);//去抖动
while(c4==0);//等待按键松开
delayxms(20);//去抖动
keynum=3;
display(SMG_duanma[keynum]);
}
r2=0;//选中第二行
r1=r3=r4=1;
c1=c2=c3=c4=1;
if(c1==0)
{
delayxms(20);//去抖动
while(c1==0);//等待按键松开
delayxms(20);//去抖动
keynum=4;
display(SMG_duanma[keynum]);
}
else if(c2==0)
{
delayxms(20);//去抖动
while(c2==0);//等待按键松开
delayxms(6);//去抖动
keynum=5;
display(SMG_duanma[keynum]);
}
else if(c3==0)
{
delayxms(20);//去抖动
while(c3==0);//等待按键松开
delayxms(20);//去抖动
keynum=6;
display(SMG_duanma[keynum]);
}
else if(c4==0)
{
delayxms(20);//去抖动
while(c4==0);//等待按键松开
delayxms(20);//去抖动
keynum=7;
display(SMG_duanma[keynum]);
}
r3=0;//选中第三行
r2=r1=r4=1;
c1=c2=c3=c4=1;
if(c1==0)
{
delayxms(20);//去抖动
while(c1==0);//等待按键松开
delayxms(20);//去抖动
keynum=8;
display(SMG_duanma[keynum]);
}
else if(c2==0)
{
delayxms(20);//去抖动
while(c2==0);//等待按键松开
delayxms(20);//去抖动
keynum=9;
display(SMG_duanma[keynum]);
}
else if(c3==0)
{
delayxms(20);//去抖动
while(c3==0);//等待按键松开
delayxms(20);//去抖动
keynum=10;
display(SMG_duanma[keynum]);
}
else if(c4==0)
{
delayxms(20);//去抖动
while(c4==0);//等待按键松开
delayxms(20);//去抖动
keynum=11;
display(SMG_duanma[keynum]);
}
r4=0;//选中第四行
r2=r3=r1=1;
c1=c2=c3=c4=1;
if(c1==0)
{
delayxms(20);//去抖动
while(c1==0);//等待按键松开
delayxms(20);//去抖动
keynum=12;
display(SMG_duanma[keynum]);
}
else if(c2==0)
{
delayxms(20);//去抖动
while(c2==0);//等待按键松开
delayxms(20);//去抖动
keynum=13;
display(SMG_duanma[keynum]);
}
else if(c3==0)
{
delayxms(20);//去抖动
while(c3==0);//等待按键松开
delayxms(20);//去抖动
keynum=14;
display(SMG_duanma[keynum]);
}
else if(c4==0)
{
delayxms(20);//去抖动
while(c4==0);//等待按键松开
delayxms(20);//去抖动
keynum=15;
display(SMG_duanma[keynum]);
}
}
void main()
{
while(1)
{
scanmulti();
}
}