#include "stc15.h"
#include <intrins.h>
#include <stdio.h>
#include <absacc.h>  
typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;


//延时函数,位操作,选择支路573,LED操作刷新,ULN2003刷新,数码管的刷新
void delay1ms()		//@11.0592MHz
{
	unsigned char i, j;
	_nop_();
	i = 11;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
void delayms(int n)		//@11.0592MHz
{
	unsigned char i, j;
  int k;
	for(k=0;k<n;k++)
	{
		delay1ms();	
	}
}
//***************位操作,置1,清0,取反,判断
u8 bitSet(u8 temp,u8 pos)
{
	temp =temp |(1<<pos);
	return temp;
}
u8 bitReset(u8 temp,u8 pos)
{
	temp &=~(1<<pos);
	return temp;
}

u8 bitTog(u8 temp,u8 pos)
{
  temp =temp ^(1<<pos);
	return temp;
}
u8 bitRead(u8 temp,u8 pos)
{
	u8 res;
  res =(temp>>pos) &0x01;
	return res;
}
//***************位操作,置1,清0,取反,判断

//***************选择573
#define LEDY 1  
#define SMGABCY 2
#define SMGCOMY 3
#define ULNY 4
#define NONE 5
void xz573(u8 x)
{
	switch(x)
	{
		case LEDY:
			P2=(P2&0x1F)|0x80;  //Y4  1000 0000
		break;
		
		case SMGABCY:
			P2=(P2&0x1F)|0xe0;  //Y7  1110 0000
			break;
		case SMGCOMY:
			P2=(P2&0x1F)|0xc0;  //Y6  1100
			break;
		case ULNY:
			P2=(P2&0x1F)|0xa0;  //Y5  1010
			break;			
		case NONE:
			P2=P2&0x1F;
			break;
	}
}

//LED___________________---
#define L1 0
#define L2 1
#define L3 2

u8 u8LED=0xff;

void LEDonx(u8 i)  //0
{
	u8LED = bitReset(u8LED,i);
}
void LEDoffx(u8 i)  //0
{
	u8LED = bitSet(u8LED,i);
}

void LEDtog(u8 i)
{
	u8LED =bitTog(u8LED,i);
}
void LEDdis(u8 temp)
{
	//关闭所有的通道
	xz573(NONE);
	//刷新P0数据
	u8LED=temp;
	P0=u8LED;
  xz573(LEDY);
	xz573(NONE);
}

//*************蜂鸣器继电器
u8 u8ULN=0x00;

void JDQonx()  //0
{
	u8ULN = bitSet(u8ULN,4);
}
void JDQoffx()  //0
{
	u8ULN = bitReset(u8ULN,4);
}

void FMQonx()  //0
{
	u8ULN = bitSet(u8ULN,6);
}
void FMQoffx()  //0
{
	u8ULN = bitReset(u8ULN,6);
}
void ULNdis(u8 temp)
{
	//关闭所有的通道
	xz573(NONE);
	//刷新P0数据
	u8ULN=temp;
	P0=u8ULN;
  xz573(ULNY);
	xz573(NONE);
}
//**********************************数码管,定时器动态扫描
//位码,段码,显示扫描,定时扫描,字符串翻译到LED8函数;
/*************  本地常量声明    **************/
u8 code t_display[]={                       //标准字库,共阴极,比赛共阳,取反
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};  //注意数码管的数据LED8[0]是不是对应TCOM[0]还是TCOM[8]
//u8 code T_COM[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};    //位码
/*************  本地变量声明    **************/
u8  LED8[8];        //显示缓冲
u8  display_index=0;  //显示位索引
bit B_1ms;          //1ms标志
u8  SMGbuf[20];
/********************** 显示扫描函数 ************************/
//void DisplayScan(void)
//{   
//    Send_595(~T_COM[display_index]);                //输出位码
//    Send_595(t_display[LED8[display_index]]);   //输出段码

//    P_HC595_RCLK = 1;
//    P_HC595_RCLK = 0;                           //锁存输出数据
//    if(++display_index >= 8)    display_index = 0;  //8位结束回0
//}

/********************** 显示扫描函数 ************************/
void DisplayScan(void)
{   
	
		  xz573(NONE);
			P0=0x00; 
	    xz573(SMGCOMY);  xz573(SMGCOMY);  xz573(SMGCOMY);
	    xz573(NONE); xz573(NONE); xz573(NONE);
	
			xz573(NONE);
			P0=T_COM[display_index]; 
	    xz573(SMGCOMY);  xz573(SMGCOMY);  xz573(SMGCOMY);
	    xz573(NONE); xz573(NONE); xz573(NONE);
	//段码
	
			xz573(NONE); xz573(NONE); xz573(NONE);
			P0=LED8[display_index]; //记得取反
	    xz573(SMGABCY); xz573(SMGABCY); xz573(SMGABCY);
	    xz573(NONE); xz573(NONE); xz573(NONE);
    if(++display_index >= 8)    display_index = 0;  //8位结束回0
}
void SMGconv()
{
	u8 i=0,j=0,temp=0;
	while(SMGbuf[i]!=0)
	{
		switch(SMGbuf[i])
		{
			case '0':temp=~t_display[0];break;
			case '1':temp=~t_display[1];break;
			case '2':temp=~t_display[2];break;
			case '3':temp=~t_display[3];break;
			case '4':temp=~t_display[4];break;
			case '5':temp=~t_display[5];break;
			case '6':temp=~t_display[6];break;
			case '7':temp=~t_display[7];break;
			case '8':temp=~t_display[8];break;
			case '9':temp=~t_display[9];break;
			case 'A':temp=~0x77;break;
			case 'B':temp=~0x7C;break;
		  case 'P':temp=~0x73;break;
			case '-':temp=~0x40;break;
			default:temp=0xFF;break;
		}
		if(SMGbuf[i+1]=='.')
		{
			temp &=0x7f;
			i++;
		}
		i++;
		
		LED8[j]=temp;
		j++;
	
	}
}


//***********************按键操作
int aaa=12;

int longtime=0;
u8 longkeyflag=0;

u8 key10ms=0;
u8 key10msflag=0;

u8 keyRead1(void)
{
	u8 keyx=0;
	if(P30==0)keyx=7;
	else if(P31==0)keyx=6;
	else if(P32==0)keyx=5;
	else if(P33==0)keyx=4;
	return keyx;
}

u8 keyRead4(void)   //开发板
{
	u8 keyx=0;
	
	P44=0;P42=1;P35=1;P34=1;
	if(P30==0)keyx=7;
	else if(P31==0)keyx=6;
	else if(P32==0)keyx=5;
	else if(P33==0)keyx=4;
	
	P44=1;P42=0;P35=1;P34=1;
	if(P30==0)keyx=11;
	else if(P31==0)keyx=10;
	else if(P32==0)keyx=9;
	else if(P33==0)keyx=8;
	
	P44=1;P42=1;P35=0;P34=1;
	if(P30==0)keyx=15;
	else if(P31==0)keyx=14;
	else if(P32==0)keyx=13;
	else if(P33==0)keyx=12;
	
	P44=1;P42=1;P35=1;P34=0;
	if(P30==0)keyx=19;
	else if(P31==0)keyx=18;
	else if(P32==0)keyx=17;
	else if(P33==0)keyx=16;
	
	return keyx;
}

u8 keyRead40(void)   //仿真的,没有P4
{
	u8 keyx=0;
	
	P24=0;P22=1;P35=1;P34=1;
	if(P30==0)keyx=7;
	else if(P31==0)keyx=6;
	else if(P32==0)keyx=5;
	else if(P33==0)keyx=4;
	
	P24=1;P22=0;P35=1;P34=1;
	if(P30==0)keyx=11;
	else if(P31==0)keyx=10;
	else if(P32==0)keyx=9;
	else if(P33==0)keyx=8;
	
	P24=1;P22=1;P35=0;P34=1;
	if(P30==0)keyx=15;
	else if(P31==0)keyx=14;
	else if(P32==0)keyx=13;
	else if(P33==0)keyx=12;
	
	P24=1;P22=1;P35=1;P34=0;
	if(P30==0)keyx=19;
	else if(P31==0)keyx=18;
	else if(P32==0)keyx=17;
	else if(P33==0)keyx=16;
	
	return keyx;
}


void KeyProc()
{
	u8 keydown;
	u8 keyup;
	u8 keyx;
	u8 keyold;
	
	if(key10msflag==1)
	{
		key10msflag=0;
	}
	else return;
	keyx=keyRead1();//仿真
	//keyx=keyRead40();//仿真
	//	keyx=keyRead4();//开发板
	keydown = keyx&(keyold^keyx);
	keyup =~keyx&(keyold^keyx);
	keyold=keyx;
	
	if(keydown)
	{
		longtime=0;
//		
//		if(keydown==7)aaa=aaa+10;
//		if(keydown==6)aaa=aaa-10;

//		sprintf(SMGbuf,"PPPPPP%2d",(unsigned int)aaa);
//		SMGconv();
	}
	if(keyup)
	{
		if(longkeyflag==0)
		{
			if(keyup==7)aaa=aaa+10;
			if(keyup==6)aaa=aaa-10;

		//	sprintf(SMGbuf,"PPPPPP%2d",(unsigned int)aaa);
		//	SMGconv();
		}
		else longkeyflag=0;
	
		
//		sprintf(SMGbuf,"AAAAAA%2d",(unsigned int)keyup);
//		SMGconv();
	}
	
	if(keyold &&(longtime>1000))
	{
		longtime=0;
		longkeyflag=1;
		if(keyold==7)aaa=aaa+1;
		if(keyold==6)aaa=aaa-1;
		//sprintf(SMGbuf,"BBBBBB%2d",(unsigned int)aaa);
		//SMGconv();	
	}
	
}













float wendu=12.56;
int sec=12;
int cnt1ms=0;
/* define constants */
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode
/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt 1
{
		cnt1ms++;
		key10ms++;
	  longtime++;
		if(key10ms==10)
		{
			key10msflag=1;
			key10ms=0;
		}
			
		if(cnt1ms==1001) //边界处理
		{
			cnt1ms=0;
	 		sec++;
			if(sec==59)sec=0;
			
		}
		
	 if(cnt1ms%500==0) //1ms的倍数
		{

		}
		
		
		if(cnt1ms%20==0) //1ms的倍数
		{

			
				KeyProc();//20ms读取一次按键
		}
		if(cnt1ms%1==0) //1ms的倍数
		{
				DisplayScan();  //1ms扫描显示一位	
		}

}

//********************************************************main
void main()
{
	int i;
	
	P0M0=0x00;	P0M1=0x00;
	P1M0=0x00;	P1M1=0x00;
	P2M0=0x00;	P2M1=0x00;
	P3M0=0x00;	P3M1=0x00;

	
	LEDdis(0xff);//开机关闭LED灯
  ULNdis(0x00);//开机关闭继电器和蜂鸣器

		

	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//开发板设置定时器模式
	//TMOD |= 0x01;		//仿真Proteus设置定时器模式

	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时

	ET0=1;//定时器0中断		
	sprintf(SMGbuf,"ABP65841");//熄灭数码管
	SMGconv();
	EA=1;//单片机总中断
	//xz573(LEDY);
	while(1)
	{

//			LEDdis(0xff);//开机关闭LED灯
//			ULNdis(0x00);//开机关闭继电器和蜂鸣器
//		delayms(1000);
//				
//			LEDdis(0x00);//开机关闭LED灯
//			ULNdis(0xff);//开机关闭继电器和蜂鸣器
//		delayms(1000);
//		
		
	}
	
}