#include "regx52.h"
#define uchar unsigned char
#define uint unsigned int


uchar code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  //0~9共阴显示子码
uchar code dispbit[]={0xfd,0xfb,0xf7,0xef};			//数码管位选码 低电平为选通   P11 P12 P13 P14




uchar dispbuf[]={0,0,0,0};	


uchar num=0;		//键值
uchar i=0;		//显示
uchar anjiancishu=0;	 //按键次数
 
uint disnum;


bit order=0;			 //命令
bit distime_5ms_ok=0;	//显示时间
bit keytime_10ms_ok=0; //扫描时间




//*****************************************键盘扫描

void matrixkey_csan()
{
 static uchar keystate=0;				//键状态
 static uchar keybuf1=0;			//键值缓存1
 static uchar keybuf=0;
 
 				//键值缓存

   	switch(keystate)				//判断状态
	 {
	  case 0:						//状态0
      P3=0X0F;						//赋0X0F给P2
      if(P3!=0x0f)					//判断有无按下
	   {					   
	    keystate=1;					//按下状态为1
	   }
	   break;						//跳出SWITCH语句
		
	
	
	  case 1:						//状态1
	  if(P3!=0x0F)					//再判断有无按下
	   {
	    keystate=2;					//有则改为状态2
		keybuf1=P3;				//将当前键值给缓存1
		P3=0xf0;					//交换行列线电平
		keybuf=P3;				//再将第二键值赋给缓存0
	    }
				
	   else
	    {
		keystate=0;					//如果没有按下 则返回状态1
		}
		
		break;						//跳出SWITCH语句

	  case 2:						//状态2

	  P3=0xf0;
	  if(P3==0xf0)					//判断松开了吗
	   {
	   	keystate=0;				   //松开则状态改为0  


						//********************//键值处理

	  anjiancishu++;					//按键次数++
	  keybuf=keybuf|keybuf1;		//2个键值合并
	  keybuf=~keybuf;				//键值取反

	  switch(keybuf)					//判断键值
	   {
				   	case 0x11 :num=1;break;			//1
				   	case 0x21 :num=2;break;			//2
				   	case 0x41 :num=3;break;			//3
				   	case 0x81 :num=4;break;			//。。
					case 0x12 :num=5;break;			//。。
					case 0x22 :num=6;break;
				   	case 0x42 :num=7;break;
				   	case 0x82 :num=8;break;
				   	case 0x14 :num=9;break;
					case 0x24 :num=0;break;			//0
					case 0x44 :order=1;break;			//清0
					case 0x84 :order=1;break;
					case 0x18 :order=1;break;
					case 0x28 :order=1;break;
					case 0x48 :order=1;break;
					case 0x88 :order=1;break;  
	   }




	     if(anjiancishu<5)				  //按键次数小于5次 （四位数码管显示）
	       {
		   disnum=disnum*10+num;		   //原数扩大10倍 实现输入一位左移一位
	       }


		 if(order==1)								//命令处理  如果ORDER
		 {
		   disnum=0;								//显示内容清0
		   anjiancishu=0;							//按键次数清0
		   order=0;									//标志位清0
		 }
		 		
		
		 dispbuf[3]=disnum/1000%10;
		 dispbuf[2]=disnum/100%10;					//dissnum/100%10;
		 dispbuf[1]=disnum/10%10;		 		//  /10%10;
		 dispbuf[0]=disnum/1%10;


	 }
	 
	 break;
}


	   
}   											 






//*****************************************显示函数
void display()
{
 static uchar cont;					   //显示位数



 P0=dispcode[dispbuf[cont]];

 P1=dispbit[cont];

 cont++;
 if(cont==4)
   cont=0;


}




//*****************************************主函数

main()
{
IE=0x82;				//TIMER0
TMOD=0x01;				//方式1
TH0=(65536-5000)/256;	//定时5MS
TL0=(65536-5000)%256;	//定时5MS
TR0=1;
while(1)
 {
  
   if(keytime_10ms_ok)
   {
     matrixkey_csan();
	 keytime_10ms_ok=0;      		//时间标志清0
   }

   if(distime_5ms_ok)
   { 
	 display();
	 distime_5ms_ok=0;
   }
 }
}


//********************************时间中断  给标志位

void timer0() interrupt 1
{
static uchar timer=0;

TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
timer++;
distime_5ms_ok=1;

if(timer==2)
 {
  keytime_10ms_ok=1;
  timer=0;
 }

}