51单片机-矩阵按键
矩阵键盘使用的是行和列的交叉点的形式来判断键盘按下的坐标。
)列坐标
在矩阵键盘中P3-4到P3-7为矩阵键盘的列坐标,当将列坐标引脚拉高以后(列坐标引脚给高电平,这时行坐标给低电平),当某一列有按键按下之后这一列整体就会被拉低。从而使用这种方法来判断按键那一列被按下。
P3 = 0xF0; if(p3 != 0XF0){ //不等于 0XF0说明P3-4到P3-7中有一列的按键被按下 dely(10);//延时消抖 if(p3 != 0XF0){ switch(p3){ case 0xe0: value = 0;break; //说明第一列被按下(1110 0000) case 0xd0: value = 1;break; //说明第2列被按下(1101 0000) case 0xb0: value = 2;break; //说明第3列被按下(1011 0000) case 0x70: value = 3;break; //说明第4列被按下(0111 0000) } } }
(2)行坐标
行坐标也是使用同样的方法(行给高电平,列给低电平),当一行为低电平时,说明这一行中有一个按钮被按下
P3 = 0xof;//0000 1111 if(p3 != 0xof){ //不等于 0XF0说明P3-4到P3-7中有一列的按键被按下 dely(10);//延时消抖 if(p3 != 0xof){ switch(p3){ case 0x0e: value = value;break; //说明第1行被按下(第一行被按下值不用改变,因为第一行就是从1-4进行排列,value的值在上面已经设置好了) case 0x0d: value = value + 4;break; //说明第2行被按下 case 0x0b: value = value + 8;break; //说明第3行被按下 case 0x07: value = value + 12;break; //说明第4行被按下 } } }
3)显示数据
当进行完成上面这两部,value就已经存放了矩阵键盘中的详细数据,矩阵键盘是一个4*4的所以可以用0-15来表示任何按键。
//0 - f 共阴极 char led[] = { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
矩阵按键完整代码
注意:这里直接将行与列的按键读值放到了一起,是因为按键按下去的时候单片机运行速度很快,所以当按键按下去直接执列读列然后存入value,在读行再存入value。(value是做的加法)
void NumberKey(){ P3 = 0xf0; //设置初始值,(行为低位,列为高位) if(P3 != 0xf0){ dely(20); if(P3 != 0xf0){ switch (P3) { case 0xe0: value = 0;break; case 0xd0: value = 1;break; case 0xb0: value = 2;break; case 0x70: value = 3;break; } //因为单片机速度很快,所以在按键按下的时候就可以直接执行下面的程序,也就是直接将行列读出来 P3 = 0x0f; //将行赋予初始值 switch (P3) { case 0x0e: value = value;break; case 0x0d: value = value + 4;break; case 0x0b: value = value + 8;break; case 0x07: value = value + 12;break; } while (P3 != 0x0f);//松手检测 } } }
(5)完整代码
#include "stdio.h" #include "reg52.h" #define uchar unsigned char #define uint unsigned int //数码管段选与位选 sbit duan = P2^6; sbit wei = P2^7; //建立全局变量,存放要显示的数码管字符数组中的位置 uint value = 0; //16进制所有字符 uchar led[] = {0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //延时函数 void dely( uint z ){ uint x,y; for(x = z;x > 0;x--){ for(y = 114; y > 0;y--); }; } //数码管显示函数 void play(uint n){?¢ //打开位选 P0 = 0xFF; wei = 1; P0 = 0xFE; wei = 0; //打开段选 duan = 1; P0 = led[n]; //显示按键具体数值 duan = 0; dely(5); } void NumberKey(){ P3 = 0xf0; //设置初始值,(行为低位,列为高位) if(P3 != 0xf0){ dely(20); if(P3 != 0xf0){ switch (P3) { case 0xe0: value = 0;break; case 0xd0: value = 1;break; case 0xb0: value = 2;break; case 0x70: value = 3;break; } //因为单片机速度很快,所以在按键按下的时候就可以直接执行下面的程序,也就是直接将行列读出来 P3 = 0x0f; //将行赋予初始值 switch (P3) { case 0x0e: value = value;break; case 0x0d: value = value + 4;break; case 0x0b: value = value + 8;break; case 0x07: value = value + 12;break; } while (P3 != 0x0f);//松手检测 } } } void main(){ while(1){ NumberKey(); play(value); } }