对于键盘按键之前也是似懂非懂,手里有一块浩豚电子的51板子,现在跟着使用说明看一遍学习。矩阵键盘,称为行列键盘,在单片机上使用4条I/O口作为行线,4条I/O口作为列线,此文章中我使用P1口作为键盘的使用端口。P2口接共阴极8段数码管,为按键按下后显示对应的数字。
键盘扫描采用反转扫描法,p1.0~p1.3 先设为高电平,p1.4~p1.7设为低电平,当有按键按下时P1口作为I/O口,例如按下第一个按键,P10高电平,P17为低电平,按键按下后,线路导通,按键与I/O口之间没有其他元件,此时就相当于一根导线连接,P10口变成低电平状态,此时可以确定行按下,但是还要确定列按下,才能确定具体按键,最容易确定按键按下的当然是电平的跳变,不然都是低电平,怎样确认哪列?前面提到我们用反转法,讲p1.0~p1.3设为低电平,p1.4~p1.7设为高电平,在按键按下没松手时间段,确认电平跳变的I/O口,进而确认列坐标,行列组合最终确认按键被按下的坐标。
下面贴出此实验的C代码,共参考使用
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar led[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极 数码管 0-f显示
//函数声明
uchar keyscanner(void);//键盘扫描函数
void delay(uint i); //延迟函数
int main(){
uchar key;
P1 = 0x00; //P1口清除
while(1){
key = keyscanner(); //扫描
switch(key){
case 0x7e:
P2=led[0];
break;
case 0x7d:
P2=led[1];
break;
case 0x7b:
P2=led[2];
break;
case 0x77:
P2=led[3];
break;
case 0xbe:
P2=led[4];
break;
case 0xbd:
P2=led[5];
break;
case 0xbb:
P2=led[6];
break;
case 0xb7:
P2=led[7];
break;
case 0xde:
P2=led[8];
break;
case 0xdd:
P2=led[9];
break;
case 0xdb:
P2=led[10];
break;
case 0xd7:
P2=led[11];
break;
case 0xee:
P2=led[12];
break;
case 0xed:
P2=led[13];
break;
case 0xeb:
P2=led[14];
break;
case 0xe7:
P2=led[15];
break;
}
}
return 0;
}
void delay(uint i) {
for(;i>=0;i--);
}
uchar keyscanner(void){ //键盘扫描,使用行列反转
uchar cord_h,cord_l; //行列值中间变量
P1 = 0x0f; //行线输出0,列为1
cord_h = P1 & 0x0f; //读P1的列值,有按下高电平变为地电平
if(cord_h!=0x0f){
delay(100); //去抖处理
if(cord_h != 0x0f){
cord_h = P1 & 0x0f; //去抖后再读一次P1状态,确定按下行坐标
P1 = 0xf0; //反转行列电平设置
cord_l = P1 & 0xf0; //读入P1的行线值,确定按下列坐标
return cord_h+cord_l; //行列组合确定按键位置
}
}
return 0xff;
}
有错误的地方多谢留言指正。