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);
}
}