电子说
单片机与矩阵键盘连接如下图:
此图用P1口P1.0---P1.3接4行P1.4--P1.7接4列
矩阵键盘工作原理:由于按键没有接地,4行4列正好占用8个I/O如果4行我们送P3.0到P3.3送入0111然后去读取4列的值,如果P3.0的按键按下那么P3.4---P3.7的值等于0111,假如是第2个键按下的话那么读回来的值是1011,如果第3个键按下去读回来的值是1101,如果第4个键按下去读回来的值是1110,如果没有键按下去读回来就是1111。所以我们就根据读回来的值来判断按下去的是那个键。当然这是对P3.0这一行,因为矩阵键盘是扫描的,所以下次把P3.0给1P3.1给0对第2行,陆续的第3行第4行,0111101111011110而每次都去从新扫描一遍列值列有4个值,以确定是那个键按下。无论何时任何一个时间有一个按键被按下就跳出循环。当然不可能有2个键刚好一起按下你的手没有这么好的力度,就算有2个键一起按键,程序也有先后检测的顺序,只能检测一个后面的检测不到。
P3=0XFE;//第一行给0
temp;定义个变量
temp=P3;读回来由于读需要先写1因为P3=FE已经把高4位给1了所以能读了
temp&oxf0如果没有按键按下结果还是0xf0。如果有键按下结果就不是0xf0了。
num然后我们再定义一个变量让它赋值给这个按下去的按键值。
一次类推把第一行赋值0扫描一遍然后把第2行赋值0扫描一遍。。。。。。。。。。。。。。共扫描16遍。
只要有键按下就会得到一个值num就从1排到16.共16个按键4*4的矩阵键盘。
我再总结下思路:
首先低4位是行共4行分别把每行给0低电平就4次0111、1011、1101、1110对吧
然后去检测高4位4列啊先不考虑极端情况,4列就4个按键只要按下一个P3口的高4位就会有一个值。根据这个值就能判断是那个键了。
如:P3=11111110低四位是行先把第一行给0
有按键下的话temp=P3读回来11011110然后temp&0xf0与运算下就判断下还等于oxf0吗?如还等于就没有按下,如果不等于就肯定有按键按下。定义个变量让它等于这个不是0XF0的值,做个标记。依次类推。
小编使用proteus模拟了一个8x8的矩阵键盘。以下是原理图:
启动后的原来图,还没有按键按下:
再来一张,有按键按下的情况:
代码如下:
#include《reg52.h》
#defineucharunsignedchar
#defineuintunsignedint
//共阴极数码管0~9
ucharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchartmp;//暂存P2的值
ucharkeynum;//按键值
ucharshi,ge;//数码管个位和十位显示
sbitP36=P3^6;//数码管时能端
sbitP37=P3^7;
//数码管显示声明
voiddisplay();
//毫秒级延时
voiddelay(uintz)
{
uintx,y;
for(x=z;x》0;x--)
for(y=110;y》0;y--);
}
voidkeyscan()
{
P0=0xfe;//扫描第1行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=1;break;//第1行第1个按键按下
case0xfd:keynum=2;break;//第1行第2个按键按下
case0xfb:keynum=3;break;//第1行第3个按键按下
case0xf7:keynum=4;break;//第1行第4个按键按下
case0xef:keynum=5;break;//第1行第5个按键按下
case0xdf:keynum=6;break;//第1行第6个按键按下
case0xbf:keynum=7;break;//第1行第7个按键按下
case0x7f:keynum=8;break;//第1行第8个按键按下
}
while(tmp!=0xff)//等待按键松手
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xfd;//扫描第2行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=9;break;//第2行第1个按键按下
case0xfd:keynum=10;break;//第2行第2个按键按下
case0xfb:keynum=11;break;//第2行第3个按键按下
case0xf7:keynum=12;break;//第2行第4个按键按下
case0xef:keynum=13;break;//第2行第5个按键按下
case0xdf:keynum=14;break;//第2行第6个按键按下
case0xbf:keynum=15;break;//第2行第7个按键按下
case0x7f:keynum=16;break;//第2行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xfb;//扫描第3行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=17;break;//第3行第1个按键按下
case0xfd:keynum=18;break;//第3行第2个按键按下
case0xfb:keynum=19;break;//第3行第3个按键按下
case0xf7:keynum=20;break;//第3行第4个按键按下
case0xef:keynum=21;break;//第3行第5个按键按下
case0xdf:keynum=22;break;//第3行第6个按键按下
case0xbf:keynum=23;break;//第3行第7个按键按下
case0x7f:keynum=24;break;//第3行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xf7;//扫描第4行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=25;break;//第4行第1个按键按下
case0xfd:keynum=26;break;//第4行第2个按键按下
case0xfb:keynum=27;break;//第4行第3个按键按下
case0xf7:keynum=28;break;//第4行第4个按键按下
case0xef:keynum=29;break;//第4行第5个按键按下
case0xdf:keynum=30;break;//第4行第6个按键按下
case0xbf:keynum=31;break;//第4行第7个按键按下
case0x7f:keynum=32;break;//第4行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xef;//扫描第5行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=33;break;//第5行第1个按键按下
case0xfd:keynum=34;break;//第5行第2个按键按下
case0xfb:keynum=35;break;//第5行第3个按键按下
case0xf7:keynum=36;break;//第5行第4个按键按下
case0xef:keynum=37;break;//第5行第5个按键按下
case0xdf:keynum=38;break;//第5行第6个按键按下
case0xbf:keynum=39;break;//第5行第7个按键按下
case0x7f:keynum=40;break;//第5行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xdf;//扫描第6行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=41;break;//第6行第1个按键按下
case0xfd:keynum=42;break;//第6行第2个按键按下
case0xfb:keynum=43;break;//第6行第3个按键按下
case0xf7:keynum=44;break;//第6行第4个按键按下
case0xef:keynum=45;break;//第6行第5个按键按下
case0xdf:keynum=46;break;//第6行第6个按键按下
case0xbf:keynum=47;break;//第6行第7个按键按下
case0x7f:keynum=48;break;//第6行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xbf;//扫描第7行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=49;break;//第7行第1个按键按下
case0xfd:keynum=50;break;//第7行第2个按键按下
case0xfb:keynum=51;break;//第7行第3个按键按下
case0xf7:keynum=52;break;//第7行第4个按键按下
case0xef:keynum=53;break;//第7行第5个按键按下
case0xdf:keynum=54;break;//第7行第6个按键按下
case0xbf:keynum=55;break;//第7行第7个按键按下
case0x7f:keynum=56;break;//第7行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0x7f;//扫描第8行
if(P2!=0xff)//有按键按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延时后确定有按键按下
{
switch(tmp)
{
case0xfe:keynum=57;break;//第8行第1个按键按下
case0xfd:keynum=58;break;//第8行第2个按键按下
case0xfb:keynum=59;break;//第8行第3个按键按下
case0xf7:keynum=60;break;//第8行第4个按键按下
case0xef:keynum=61;break;//第8行第5个按键按下
case0xdf:keynum=62;break;//第8行第6个按键按下
case0xbf:keynum=63;break;//第8行第7个按键按下
case0x7f:keynum=64;break;//第8行第8个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
}
voiddisplay()
{
//显示个位
P37=0;
P1=table[ge];
delay(5);
P37=1;
//显示十位
P36=0;
P1=table[shi];
delay(5);
P36=1;
}
voidmain()
{
while(1)
{
shi=keynum/10;
ge=keynum;
keyscan();
display();//这里的显示是保存上一次的显示值
}
}
全部0条评论
快来发表一下你的评论吧 !