//STC8G1K08A 22.1184MHz
#include <reg52.h>
//#include <intrins.h>
#define LCH 3
#define RCH 2
sfr AUXR = 0x8E;
sfr P5 =0xc8;
sfr P0M0 = 0x94;
sfr P0M1 = 0x93;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P2M0 = 0x96;
sfr P2M1 = 0x95;
sfr P3M0 = 0xB2;
sfr P3M1 = 0xB1;
sfr P4M0 = 0xB4;
sfr P4M1 = 0xB3;
sfr P5M0 = 0xCA;
sfr P5M1 = 0xC9;

sfr ADC_CTRL = 0xBC;
sfr ADC_RESH = 0xBD;
sfr ADC_RESL = 0xBE;
sfr ADC_CFG = 0xDE;
sfr P_SW2 = 0xBA;

sbit EADC=IE^5;

#define ADCTIM (*(unsigned char volatile xdata *)0xFEA8)
#define P5PU   (*(unsigned char volatile xdata *)0xFE15)
#define P5SR   (*(unsigned char volatile xdata *)0xFE25)
#define P5DR   (*(unsigned char volatile xdata *)0xFE2D)

sbit LCHLED=P5^4;
sbit RCHLED=P5^5;

//code unsigned int db_level_val[]={60,53,50,47,46,44,43,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
//code unsigned int db_adcsp_val[]={0,1,2,3,4,5,6,7,8,10,11,12,14,15,17,19,22,25,28,31,35,39,45,51,57,64,71,80,91,102,114,127,144,161,181,203,228,256,287,323,362,407,456,512,574,644,723,812,911,1018,65535};
//code unsigned int db_adcsp_val[]={5,6,7,8,9,10,11,12,13,15,16,17,19,20,22,24,27,30,33,36,40,44,50,56,62,69,76,85,96,107,119,132,149,166,186,208,233,261,292,328,367,412,461,517,579,649,728,817,916,1022,65535};
//code unsigned int db_adcsp_val[]={91,127,181,256,362,512,574,644,723,812,911,1022,65535};
//                                21 18  15  12  9   6   5   4   3   2   1   0
bit LRTOGL;
unsigned char LdbPeak,RdbPeak,Ldbmin,Rdbmin;
unsigned int ADCVAL,Lmax,Rmax,Lmin,Rmin,Lamp,Ramp;
unsigned int cnt;

void ADC_init()
{
	P_SW2 |= 0X80;
//	ADCTIM=0X80+0X60+0X1F;//ADCTIM B7 CSSETUP B6B5 CSHOLD B4-B0 SMPDUTY
	ADCTIM=0X2A;//ADCTIM B7 CSSETUP B6B5 CSHOLD B4-B0 SMPDUTY
	P5PU=0XFF;
	P5SR=0X00;
	P5DR=0X00;
	P_SW2 &=0X7F;
//	ADC_CFG=0X2F;//ADCCFG  B5 RESFMT  B3-B0 SPEED
	ADC_CFG=0X21;//ADCCFG  B5 RESFMT  B3-B0 SPEED
	ADC_CTRL=0XC0;
	EADC=1;
}
void IO_init()
{
//XX XX P5.5 P5.4 XX XX XX XX
//      强推 强推
//0  0  1    1    0    0    0    0 P5M0=0X30
//0  0  0    0    0    0    0    0 P5M1=0X00

//XX XX XX XX 33   32   31   30
//            高阻 高阻 标准 标准
//0  0  0  0  0    0    0    0 P3M0=0X00
//0  0  0  0  1    1    0    0 P3M1=0X0c
	P5M0=0Xff;
	P5M1=0X00;
	P3M0=0X00;
	P3M1=0X0C;
}
void nop(void)
{
}

void sendLbyte(unsigned char byte)
{
	unsigned char i;
	i=8;
	EA=0;
		do
		{
			LCHLED=1;nop();
			LCHLED=byte&0x80;nop();
			LCHLED=0;nop();
			byte=(byte<<1);		 //左移位
		}while(--i);
	EA=1;
}
void sendRbyte(unsigned char byte)
{
	unsigned char i;
	i=8;
	EA=0;
		do
		{
			RCHLED=1;nop();
			RCHLED=byte&0x80;nop();
			RCHLED=0;nop();
			byte=(byte<<1);		 //左移位
		}while(--i);
	EA=1;
}
void sendpixL(unsigned long * color)
{
	sendLbyte(((unsigned char *)color)[2]);
	sendLbyte(((unsigned char *)color)[1]);
	sendLbyte(((unsigned char *)color)[3]);
}
void sendpixR(unsigned long * color)
{
	sendRbyte(((unsigned char *)color)[2]);
	sendRbyte(((unsigned char *)color)[1]);
	sendRbyte(((unsigned char *)color)[3]);
}
//unsigned char samp2Lednum(unsigned int amp)
//{
//	unsigned char i;
//	for(i=0;amp>=db_adcsp_val[i];i++);
//	return i;
//}
unsigned char samp2Lednum(unsigned int amp)
{
	return (amp/84)%20;
}
void SetLedR(unsigned char RchLednum)
{
		unsigned char i;
		unsigned long LevelColor;
			for(i=0;i<RchLednum;i++)
			{
				((unsigned char *)&LevelColor)[1]=i*2;
				((unsigned char *)&LevelColor)[2]=24-i*2;
				//if(i==Rdbmin){LevelColor=0x200020;}
				sendpixR(&LevelColor);
			}
			LevelColor=0;
			for(;i<15;i++)
			{
				if(i==RdbPeak){LevelColor=0x050500;}else{LevelColor=0;}
				sendpixR(&LevelColor);
			}
}
void SetLedL(unsigned char LchLednum)
{
		unsigned char i;
		unsigned long LevelColor;
			for(i=0;i<LchLednum;i++)
			{
				((unsigned char *)&LevelColor)[1]=i*2;
				((unsigned char *)&LevelColor)[2]=24-i*2;
				//if(i==Ldbmin){LevelColor=0x200020;}
				sendpixL(&LevelColor);
			}
			for(;i<15;i++)
			{
				if(i==LdbPeak){LevelColor=0x050500;}else{LevelColor=0;}
				sendpixL(&LevelColor);
			}
}
void Delay50us()		//@22.1184MHz
{
	unsigned char i, j;

	i = 2;
	j = 109;
	do
	{
		while (--j);
	} while (--i);
}
void Timer0Init(void)		//2500微秒@22.1184MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0xEE;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;
	ET0=1;
}

void main()
{
	bit LedSetFlag;
	unsigned char Ldb,Rdb,Peakcnt,Mincnt;
	unsigned char Ldisp,Rdisp,Ldbon,Rdbon;
	ADC_init();
	IO_init();
	Timer0Init();
	EA=1;
	while(1)
	{
		EA=0;
		Lamp=Lmax-Lmin;
		Ramp=Rmax-Rmin;
		EA=1;
		
		Ldb=samp2Lednum(Lamp);
		Rdb=samp2Lednum(Ramp);

		
		if(Ldb>LdbPeak){LdbPeak=Ldb;Peakcnt=0;}
		if(Rdb>RdbPeak){RdbPeak=Rdb;Peakcnt=0;}
		
		if(Ldisp<Ldbmin){Ldbmin=Ldisp;Mincnt=0;}
		if(Rdisp<Rdbmin){Rdbmin=Rdisp;Mincnt=0;}
		
		if(Ldb>Ldisp){Ldisp=Ldb;}
		if(Rdb>Rdisp){Rdisp=Rdb;}

		if(Ldbon!=Ldisp)
		{
			SetLedL(Ldisp);
			LedSetFlag=1;
		}
		Ldbon=Ldisp;
		
		if(Rdbon!=Rdisp)
		{
			SetLedR(Rdisp);
			LedSetFlag=1;
		}
		Rdbon=Rdisp;
		
		if(LedSetFlag){Delay50us();LedSetFlag=0;}

		if(cnt>=10)
		{
			cnt=0;
			if(Ldisp){Ldisp--;}
			if(Rdisp){Rdisp--;}
			EA=0;
			Lmax=1;
			Rmax=1;
			Lmin=1023;
			Rmin=1023;
			EA=1;
			Peakcnt++;
			if(Peakcnt>=20)
			{
				//clrled(12);
				//Ldbon=0;
				//Rdbon=0;
				SetLedL(Ldisp);
				SetLedR(Rdisp);
				Peakcnt=0;
				LdbPeak=0;
				RdbPeak=0;
			}
			Mincnt++;
			if(Mincnt>=60)
			{
				Mincnt=0;
				Ldbmin=15;
				Rdbmin=15;
			}
			while(Lmax<Lmin);
			while(Rmax<Rmin);
		}
	}
}

void adc() interrupt 5
{
	ADC_CTRL=0X80;
	((unsigned char *)&ADCVAL)[0]=ADC_RESH;
	((unsigned char *)&ADCVAL)[1]=ADC_RESL;
	if(LRTOGL)
	{
		if(ADCVAL>Lmax){Lmax=ADCVAL;}
		if(ADCVAL<Lmin){Lmin=ADCVAL;}
		ADC_CTRL=0xC0+RCH;
	}
	else
	{
		if(ADCVAL>Rmax){Rmax=ADCVAL;}
		if(ADCVAL<Rmin){Rmin=ADCVAL;}
		ADC_CTRL=0xC0+LCH;
	}
	LRTOGL=!LRTOGL;
}
void Timer0_25ms(void) interrupt 1
{
	cnt++;
}