||
键盘识别思路是这样的,初始化时先让P1口的低四位(P13-P10)输出低电平,高四位(P17-P14)输出高电平,即让P1输出0xf0[P1=0xf0]
扫描键盘时,读P1口,看P1口是否为0xf0,如果仍为0xf0,则表示没有按键按下;如果不为0xf0,就先等待延时10ms左右,再读P1口,再次确认是否为0xf0。这是防止抖动干扰造成的错误识别。如果当再次确认不是0xf0,那就说明真的有按键按下,此时就可以读键码来识别是哪个键按下。
识别过程:初始化时让P1口的低四位输出低电平,高四位输出高电平,确认真的有按键按下时,首先读P1口的高四位,P1口输出0x
#include <intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
uchar num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89}; // LED共阳极段码
void delayns(void) //延时
{
uint i;
for(i=300;i>0;i--);
}
uchar keyscan(void) // 键盘扫描函数
{
uchar scode,recode;
P1=0xf0; // 列线为高电平
if((P1&0xf0)!=0xf0) //判断有无按键按下,有则此句成立往下执行,否则就return 0;
{ delayns(); //有按键按下时延时去抖
if((P1&0xf0)!=0xf0) //有键按下
{
scode=0xfe; //辅助变量,设定行,逐行扫描初值P10=0低电平
while((scode&0x10)!=0)
{
P1=scode; //将某一行设为(低电压)0,从而判断是否为该行,输出行扫描
if((P1&0xf0)!=0xf0) //此行有按键按下
{
recode=(P1&0xf0)|0x0f; //列码
return((~scode)+(~recode)); //按键坐标
}
else
scode=(scode<<1)|0x01; //下一行判断
}
}
}
return(0);
}
void main()
{uchar key,temp;
while(1)
{ key=keyscan();
switch(key)
{
case 0x11: temp=0; break;
case 0x21: temp=1; break;
case 0x41: temp=2; break;
case 0x81: temp=3; break;
case 0x12: temp=4; break;
case 0x22: temp=5; break;
case 0x42: temp=6; break;
case 0x82: temp=7; break;
case 0x14: temp=8; break;
case 0x24: temp=9; break;
case 0x44: temp=10; break;
case 0x84: temp=11; break;
case 0x18: temp=12; break;
case 0x28: temp=13; break;
case 0x48: temp=14; break;
case 0x88: temp=15; break;
}
P2=num[temp];
delayns(); //延时去抖动干扰
}
}
第二种思路:
#include <reg51.h>
#include <intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
uchar num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89}; // LED共阳极段码
uchar k; //全局变化
void delayns(void) //延时去抖干扰
{
uint i;
for(i=300;i>0;i--);
}
uchar keyscan() //键盘扫描函数,用于识别那个键按下,并读取键值
{
uchar x,y,z;
P1=0xf0; //先对P1置数,行扫描
if(P1!=0xf0) //判断是否有键按下
{
delayns(); //延时去抖动干扰
if(P1!=0xf0) //再次确认按键按下
{
x=P1&0xf0; //保存列扫描时有键按下时的状态
P1=0x0f; //列扫描
if(P1!=0x0f)
y=P1&0x0f; //保存行扫描时有键按下时的状态
z=x|y; //取出键值
switch(z)
{case 0xe7: k=0; break;
case 0xd7: k=1; break; //对键值赋值
case 0xb7: k=2; break;
case 0x77: k=3; break;
case 0xeb: k=4; break;
case 0xdb: k=5; break;
case 0xbb: k=6; break;
case 0x7b: k=7; break;
case 0xed: k=8; break;
case 0xdd: k=9; break;
case 0xbd: k=10; break;
case 0x7d: k=11; break;
case 0xee: k=12; break;
case 0xde: k=13; break;
case 0xbe: k=14; break;
case 0x7e: k=15; break;
}
}
} return(k);
}
void main()
{ uint key;
uint n=0;
while(1)
{
key=keyscan(); //得到键值
n=key;
P2=num[n]; //P2口数码管显示
}
}
PS:大家有什么不同建议思路,可以和我交流哈,大家互相学习,QQ:1298522437