#include
unsigned char ledchar[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳极数码管
unsigned char keybuf[3][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0}}; //按键值缓存数组
sbit IN_1=P2^6; //3行
sbit IN_2=P2^5;
sbit IN_3=P2^4;
sbit OUT_1=P2^3; //4列
sbit OUT_2=P2^2;
sbit OUT_3=P2^1;
sbit OUT_4=P2^0;
void main()
{
unsigned char i,j;
unsigned char backup[3][4]={{0,0,0,0},{0,0,0,0},0,0,0,0}}; //按键值备份
EA=1;
TMOD=1;
TH0=0xFC; //1ms扫描一次按键
TL0=0x67;
ET0=1;
TR0=1;
P0=ledchar[0];
while(1)
{
for(i=0;i<=3;i++)
{
for(j=0;j<=4;j++)
{
if(backup[i][j]!=keybuf[i][j]) //有按键按下
{
if(backup[i][j]==1) //按键按下并弹起
{
P0=ledchar[i*4+j+1];
}
backup[i][j]=keybuf[i][j];
}
}
}
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char keyin=0;
static unsigned char keyout[3][4]={ {0x00, 0x00, 0x00, 0x00},{0x00, 0x00, 0x00, 0x00},{0x00, 0x00, 0x00, 0x00}, };
static unsigned char i=0;
TH0=0xFC;
TL0=0x67;
keyout[keyin][0]=(keyout[keyin][0]<<1)|OUT_1; //消抖
keyout[keyin][1]=(keyout[keyin][1]<<1)|OUT_2;
keyout[keyin][2]=(keyout[keyin][2]<<1)|OUT_3;
keyout[keyin][3]=(keyout[keyin][3]<<1)|OUT_4;
for(i=0;i<=4;i++) //判断键值,0为弹起,1为按下
{
if((keyout[keyin][i]&0x0f)==0x00)
{
keybuf[keyin][i]=0;
}
else if((keyout[keyin][i]&0x0f)==0x0f)
{
keybuf[keyin][i]=1;
}
}
keyin++;
keyin=keyin&0x02; //keyin值为0,1,2
switch(keyin)
{
case 0:IN_1=1;IN_2=0;IN_3=0;break;
case 1:IN_1=0;IN_2=1;IN_3=0;break;
case 2:IN_1=0;IN_2=0;IN_3=1;break;
default : break;}
}