#include <reg51.h>   
#include <intrins.h>                            
#include <absacc.h>
#include <string.h> 
#include <math.h>

#define   uchar  unsigned char
#define   uint   unsigned int
#define   COM8279   XBYTE [0x0A001]   //8279ƿ
#define   DATA8279  XBYTE [0x0A000]   //8279ݿ

sbit     FAN=P3^3;    //
sbit     DQ=P3^4;     //18B20ݿ
sbit     CR=P3^5;     //ˮ

unsigned int   temper;             //ǰ¶
unsigned int   temp;               //¶ȴȡ¶ֵем_Ҫ
unsigned int   set_temper=40;      //ǰ趨¶
unsigned int   p_2=4,p_1=0,p_0=0;  //ʾǰ趨¶ȣʮλλСλ
unsigned int   lock=0;             //
unsigned int   high_time,low_time,count=0;//ռձȵڲ 
unsigned int   keyval;	         //봫ݲ
unsigned int   time;             //ʱ
unsigned int   i;   //м_Ҫ
unsigned int   j=0; //м_Ҫ
unsigned int   s;   //м_Ҫ
unsigned int   h;   //м_Ҫ
//unsigned int   flag,flag_1=0; 

struct PID 
{ 
	unsigned int SetPoint; // 趨Ŀ Desired Value 
	unsigned int Proportion; //  Proportional Const 
	unsigned int Integral; // ֳ Integral Const 
	unsigned int Derivative; // ΢ֳ Derivative Const 
	unsigned int LastError; // Error[-1] 
	unsigned int PrevError; // Error[-2] 
	unsigned int SumError; // Sums of Errors 
}; 
struct PID spid; // PID Control Structure 
unsigned int rout; // PID Response (Output) 
unsigned int rin; // PID Feedback (Input) 

uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};  //ʮƶӦʮƣ18b20Сλ
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //LED "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "" "-"
uchar led[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //0Fļ
uchar data display[5]={0x00,0x00,0x00,0x00,0x00};     //ʾԪݣ4ݺһ              
uchar data temp_data[2]={0x00,0x00};   //¶ݷ

void delay();
void key();
void ledclr();

void long_delay(unsigned char time) 
{ 
	unsigned char m,n; 
	for(n=0;n<time;n++) 
		for(m=0;m<2;m++){} 
}

void get_temper()
{
	temper=display[2]*100+display[1]*10+display[0];
	set_temper=p_2*100+p_1*10+p_0;   
}

void delay(uint t)
{
  	for (;t>0;t--);
}

/*Initialize PID Structure*/ 
void PIDInit (struct PID *pp) 
{ 	memset ( pp,0,sizeof(struct PID)); } 

/*PID㲿*/ 
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) 
{ 
	unsigned int dError,Error; 
	Error = pp->SetPoint - NextPoint; // ƫ 
	pp->SumError += Error; //  
	dError = pp->LastError - pp->PrevError; // ǰ΢ ϴ-ϴ
	pp->PrevError = pp->LastError; 
	pp->LastError = Error; 
	return (pp->Proportion * Error 	+ pp->Integral * pp->SumError 	+ pp->Derivative * dError); // ++΢ 
} 

/*¶ȱȽϴӳ*/ 
compare_temper() 
{ 
	if(set_temper>temper) 
	{ 
		if(set_temper-temper>10) //101
		{ 
			high_time=100; 
			low_time=0; 
		} 
		else 
		{ 
			{ get_temper(); 
			rin = s; // Read Input 
			rout = PIDCalc ( &spid,rin ); // Perform PID Interation 
			} 
			if (high_time<=100) 
				high_time=(unsigned char)(rout/800); 
			else 
				high_time=100; 
			low_time= (100-high_time); 
		} 
	} 
	else if(set_temper<=temper) 
	{ 
		if(temper-set_temper>10) 
		{ 
			high_time=0; 
			low_time=100; 
		} 
		else 
		{ 
			{ get_temper(); 
			rin = s; // Read Input 
			rout = PIDCalc ( &spid,rin ); // Perform PID Interation 
			} 
			if (high_time<100) 
				high_time=(unsigned char)(rout/10000); 
			else 
				high_time=0; 
			low_time= (100-high_time); 
		} 
	} 

} 

/*T0жϷӳ  PWMƽķת 40us*100=4ms*/ 
void serve_T0() interrupt 1 using 2
{ 
	if(++count<=(high_time)) 
		CR=1; 
	else if(count<=100) 
	{ 
		CR=0; 
	} 
	else 
		count=0; 
	TH0=0xec; 
	TL0=0x78; 
} 


void intsvr1(void) interrupt 0 using 1  //ж
{
	COM8279=0x40;  //FIFO
	keyval=DATA8279;
	key();
}

void ledclr()  //
{
	COM8279 = 0xD3; //RAMFIFO  1101 0011
	delay(100);
	COM8279=0x00; //8279˫,ڱɨ裬,8ַʾ
	COM8279=0x32; //ʱӷƵ,ƵΪ18   0011 0010
	COM8279=0x70; //öʾ            0111 0000
	COM8279=0x90; //дʾ            1001 0000
}

void key()
{
	char u;
	EX0=0;  //ж
	/* ̣¶ */
	if(keyval==0x0DB)
	{
		lock=1-lock;		
		ledclr();		
		if(lock==1)
			DATA8279=0x38;   //L&UʾǷ			
		else
			DATA8279=0x3e;		
		delay(65535);		
		EX0=1;
		return;
	}
	if(lock==0)  //δʱ
	{
       if(keyval==0x0D0)
	   {
		   if(spid.Proportion<15)
		   {
		    spid.Proportion++;
		   }

	   }

	   if(keyval==0x0D8)
       {
		   if(spid.Proportion>1)
		   {
		    spid.Proportion--;
		   }
	   }

	   if(keyval==0x0D1)
       {
		   if(spid.Integral<15)
		   {
			spid.Integral++;
		   }
	   }

	   if(keyval==0x0D9)
	   {
		  if(spid.Integral>1)
		  {
		   spid.Integral--;
		  }
	   }

	   if(keyval==0x0D2)
	   {
		  if(spid.Derivative<15)
		  {
		   spid.Derivative++;
		  }
	   }

	   if(keyval==0x0DA)
	   {
		  if(spid.Derivative>1)
		  {
		   spid.Derivative--;
		  }
	   }

	   if(keyval==0x0C0) //Сλ
	   {
		  if(p_0==9)
		  {
			if(p_1==9)
			{
				p_2++;
				p_0=0;
				p_1=0;
			}
			else
			{
				p_1++;
				p_0=0;
			}
		  }
		  else
			p_0++;
	   }
	
       if(keyval==0x0C8)   //Сλ
	   {
		if(p_0==0)
		{
			if(p_1==0)
			{
				p_2--;
				p_1=9;
				p_0=9;
			}
			else
			{
				p_1--;
				p_0=9;
			}
		}
		else
	      p_0--;
	   }
	
	if(keyval==0x0C1)   //λ
	{
		if(p_1==9)
		{
			
			p_2++;
			p_1=0;
		}
		else
			p_1++;		
	}
	
	if(keyval==0x0C9)  //λ
	{		
		if(p_1==0)
		{
			p_2--;
			p_1=9;			
		}
		else
			p_1--;
	}
	
	if(keyval==0x0C2) //ʮλ
		p_2++;
	
	if(keyval==0x0cA) //ʮλ 
		p_2--;
	
	
	//**************** <0Ȼ>=80 ǿ趨Ϊ40*************
	
	if(!((0<=p_2)&&(p_2<8)))
	{
		ledclr();
		
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;
		DATA8279=0x40;		
		delay(65535);
		delay(65535);
		delay(65535);
		p_2=4;
		p_1=0;
		p_0=0;
		
		EX0=1;
		
		return;
	}
	
	//*********************** ʾú¶ ************************//
	
	if(keyval==0x0C8||keyval==0x0C0||keyval==0x0C1||keyval==0x0C9||keyval==0x0C2||keyval==0x0CA||keyval==0x0C3||keyval==0x0CB||keyval==0x0D3)
	{
	    ledclr();
	    u=led[p_2];
     	DATA8279=u;
		u=led[p_1];
		u=u+0x80;
		DATA8279=u;
		u=led[p_0];
		DATA8279=u;
		DATA8279=0x00;
		DATA8279=0x63;
		DATA8279=led[12];
		delay(20000);
		
		ledclr();
	    DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;
		delay(20000);
		
		ledclr();
		u=led[p_2];
		DATA8279=u;
		u=led[p_1];
		u=u+0x80;
		DATA8279=u;
		u=led[p_0];
		DATA8279=u;
		DATA8279=0x00;
		DATA8279=0x63;
		DATA8279=led[12];
		delay(20000);
		
		ledclr();
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;
		delay(20000);
	  
	    ledclr();
		u=led[p_2];
		DATA8279=u;
		u=led[p_1];
		u=u+0x80;
		DATA8279=u;
		u=led[p_0];
		DATA8279=u;
		DATA8279=0x00;
		DATA8279=0x63;
		DATA8279=led[12];
		delay(65535);

		EX0=1;
	}
	
	if(keyval==0x0D8||keyval==0x0D0||keyval==0x0D1||keyval==0x0D9||keyval==0x0D2||keyval==0x0DA)
	{
	    ledclr();
	    DATA8279=0x73;  //P
	    DATA8279=0x06;  //I
	    DATA8279=0xde;  //D.
	    DATA8279=0x00;
	    DATA8279=0x00;
	    u=led[spid.Proportion];
  	    DATA8279=u;
	    u=led[spid.Integral];
	    DATA8279=u;
	    u=led[spid.Derivative];
	    DATA8279=u;
	    delay(20000);
	    
	    ledclr();
	    DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;
        delay(20000);
	    
	    ledclr();
	    DATA8279=0x73;
	    DATA8279=0x06;
    	DATA8279=0xde;
        DATA8279=0x00;
	    DATA8279=0x00;
	    u=led[spid.Proportion];
  	    DATA8279=u;
	    u=led[spid.Integral];
	    DATA8279=u;
	    u=led[spid.Derivative];
	    DATA8279=u;
	    delay(20000);
	
	    ledclr();
	    DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;	 
		DATA8279=0x00;
	    delay(20000);
	    
	    ledclr();
	    DATA8279=0x73;
	    DATA8279=0x06;
	    DATA8279=0xde;
	    DATA8279=0x00;
	    DATA8279=0x00;
	    u=led[spid.Proportion];
  	    DATA8279=u;
	    u=led[spid.Integral];
	    DATA8279=u;
        u=led[spid.Derivative];
	    DATA8279=u;
	    delay(20000);
		
        delay(65535);
	    EX0=1;
	}
	EX0=1;
	}
	EX0=1;
}

void TempControl()  //ȿ
{	
	//ǰ¶ȱ趨¶ȸ1
	if((display[2]*100+display[1]*10+display[0])>((p_2*100+p_1*10+p_0)+10))
	{
		FAN=0;
		FAN=1;
	}
	else
	{
		FAN=0;
	}
	
}

/****************ʾ***************************/
void disp()
{
	char k;
	char u;
	
	COM8279 = 0xD3;//RAMFIFO  1101 0011
	delay(100);
	COM8279=0x00; //8279˫,ڱɨ裬,8ַʾ
	COM8279=0x32;//ʱӷƵ,ƵΪ18   0011 0010
	COM8279=0x70;	//öʾ              0111 0000
	COM8279=0x90;//дʾ              1001 0000
	
	if((display[2]*100+display[1]*10+display[0])<(p_2*100+p_1*10+p_0)-10)//״̬ʾ L
	{
		DATA8279=0x38;  
		DATA8279=0x00;		
	}
	else
	{
		if((display[2]*100+display[1]*10+display[0])>((p_2*100+p_1*10+p_0)+10))//ʾF
		{
			DATA8279=led[15];
			DATA8279=0x00;
		}
		else
		{
			DATA8279=0x73; //һλʾP  PID
		    DATA8279=0x00;
		}
	}
	
	for(k=2;k>=0;k--)  
	{
		u=led[display[k]];
		if(k==1)
		{
			u=u+0x80;//С
		}
		DATA8279=u;		
	}
	DATA8279=0x00;
	DATA8279=0x63;
	DATA8279=led[12];//ʾ
	
	delay(100);
	TempControl();
}

/*DS18B20λ*/
ow_reset(void)
{
	char presence=1;
	while(presence)
	{
		while(presence)
		{
			DQ=1;_nop_();_nop_();//Ӹ
			DQ=0;                                       
			delay(50);           //550 us
			DQ=1;                                        
			delay(6);             //66 us
			presence=DQ;         //presence=0 λɹ,һ
		} 
		delay(45);             //ʱ500 us
		presence=~DQ;         
	}
	DQ=1;                   //ߵƽ
}

/*DS18B20д*/
void write_byte(uchar val)
{ 
	uchar i;
	for(i=8;i>0;i--)
	{
		DQ=1;_nop_();_nop_();                   //Ӹ
		DQ=0;_nop_();_nop_();_nop_();_nop_();   //5 us
		DQ=val&0x01;                           //λƳ
		delay(6);                               //66 us
		val=val/2;                             //1λ
	}
	DQ=1;
	delay(1);
}

/*DS18B201ֽں*/
uchar read_byte(void)
{
	uchar i;
	uchar value=0;
	for(i=8;i>0;i--)
	{
		DQ=1;_nop_();_nop_();
		value>>=1;
		DQ=0;_nop_();_nop_();_nop_();_nop_();         //4 us
		DQ=1;_nop_();_nop_();_nop_();_nop_();         //4 us
		if(DQ)value|=0x80;
		delay(6);                                     //66 us
	}
	DQ=1;
	return(value);
}


/*¶Ⱥ*/
read_temp()
{
	ow_reset();                   //߸λ
	delay(200);
	write_byte(0xcc);             //
	write_byte(0x44);             //ת
	ow_reset(); 
	delay(1);
	write_byte(0xcc);             //
	write_byte(0xbe);
	delay(00);	
	temp_data[0]=read_byte();     //¶ֵĵֽ
	temp_data[1]=read_byte();     //¶ֵĸֽ
	temp=temp_data[1];
	temp<<=8;                                               
	temp=temp|temp_data[0];       // ֽںϳһͱ
	return temp;                 //¶ֵ
}

/*¶ݴ*/
work_temp(uint tem)
{
	uchar n=0;
	if(tem>6348)                   // ¶ֵж
	{tem=65536-tem;n=1;}           // ¶,־λ1
	display[4]=tem&0x0f;           // ȡСֵֵ
	s=((unsigned int)temp_data[0]&0x0f)*100/16;
	display[0]=ditab[display[4]];  // Сʾֵ
	display[4]=tem>>4;             // ȡмλ,ֵֵ
	display[3]=display[4]/100;     // ȡλݴ
	display[1]=display[4]%100;     // ȡλݴ
	display[2]=display[1]/10;      // ȡʮλݴ
	display[1]=display[1]%10;  
	/*λʾж*/
	if(!display[3]) 
	{
		display[3]=0x0a;           //λΪ0ʱʾ
		if(!display[2])
		{
			display[2]=0x0a;         //θλΪ0ʱʾ
		}
	}
	if(n){display[3]=0x0b;}       //¶ʱλʾ"-"
}


main()
{
	unsigned int flag_2=1,count1=0; 
	unsigned int phil[]={2,0xce,0x6e,0x60,0x1c,2};; 
	TMOD=0x21; 
	TH0=0xec; 
	TL0=0x78;
	
	
	SCON=0x50; 
	PCON=0x00; 
	TH1=0xfd; 
	TL1=0xfd; 
	PS=1; 
	EA=1; 
	EX1=0; 
	ET0=1; 
	ES=1; 
	TR0=1; 
	TR1=1; 
	high_time=50; 
	low_time=50; 
	PIDInit ( &spid ); // Initialize Structure 
	spid.Proportion = 10; // Set PID Coefficients 
	spid.Integral = 8; 
	spid.Derivative =6; 
	spid.SetPoint = 100; // Set PID Setpoint 

	EA=1;
	EX0=1;                             //ж,ⲿж1
	IT0=1;                              //ⲿж1ѡ½
	
	
	Disdata=0xff;                 //ʼ˿
	discan=0xff;
	
	COM8279 = 0xD3;//RAMFIFO  1101 0011
	delay(100);
	COM8279=0x00; //8279˫,ڱɨ裬,8ַʾ
	COM8279=0x32;//ʱӷƵ,ƵΪ18   0011 0010
	COM8279=0x70;	//öʾ              0111 0000
	COM8279=0x90;//дʾ              1001 0000
	
	for(h=0;h<4;h++)               //ʾ"0000"
	{display[h]=0;} 
	ow_reset();                   //תһ
	write_byte(0xcc);             //Skip ROM
	write_byte(0x44);             //ת
	for(h=0;h<100;h++)            //ʾ"0000"
	{disp();}
	delay(10000);
	
	while(1)
	{
		work_temp(read_temp());     //¶
		disp();                     //ʾ¶ֵ
		delay(10000);
		get_temper(); //PIDԤ
		compare_temper(); //PID	
	}
}