#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
uchar disnum,temp,key,num;
uchar code table_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					   0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0};
delay(uchar);    //函数声明
uchar keyscan();
void main()
{	
	disnum=16;
	wela=1;
	P0=0XFE;  //第一个数码管位选
	wela=0;
	while(1)
	{
	num=keyscan();	  //用num读取矩阵键盘扫描函数的返回值
	P0=table_du[num];  //送段选num
	dula=1;
	dula=0;
	}	
}

uchar keyscan()    //矩阵键盘扫描函数
{
    P3=0xf0;  //让P3.0、P3.1、P3.2、P3.3等于0，P3.4、P3.5、P3.6、P3.7等于1
	temp=P3;  //用temp读取P3口当前的值
	temp=temp&0xf0;  //把temp的值和0xf0作与运算，即保持高4位变，低4位为0
	if(temp!=0xf0)    //如果此时的temp不等于0xf0，说明有按键被按下了
	{
		delay(10);      //延时约10ms
		if(temp!=0xf0)  //再次判断是否真的有按键按下(即消除前沿抖动)
		{
			temp=P3;        //如果有按键按下，temp重新读取P3口的值
			temp=temp|0X0f;  //作按位或，即保持高4位不变，低4位为1
			P3=temp;        //把temp的值赋给P3口
			key=P3;         //然后用key读取P3口的值，作为按键的键值
			switch(key)   //让每一个键值和数码管显示的数对应起来
			{
				case 0xee:disnum=0;  //当key的值为0xee时，disnum的值为0
							break;
				case 0xde:disnum=1;  //当key的值为0xde时，disnum的值为1
							break;
				case 0xbe:disnum=2;
							break;
				case 0x7e:disnum=3;
							break;
				case 0xed:disnum=4;
							break;
				case 0xdd:disnum=5;
							break;
				case 0xbd:disnum=6;
							break;
				case 0x7d:disnum=7;
							break;
				case 0xeb:disnum=8;
							break;
				case 0xdb:disnum=9;
							break;
				case 0xbb:disnum=10;
							break;
				case 0x7b:disnum=11;
							break;
				case 0xe7:disnum=12;
							break;
				case 0xd7:disnum=13;
							break;
				case 0xb7:disnum=14;
							break;
				case 0x77:disnum=15;
							break;
			}
		}
	}
return disnum;  //返回disnum作为函数值
}

delay(uchar x)  //延时函数
{
	uchar a,b;
	for(a=x;a>0;a--)
		for(b=200;b>0;b--);
}