#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/*****************引脚定义*********************************/
sbit output=P2^5;
/********************************/
sbit CLOCK=P3^1;
sbit D_IN=P2^7;
sbit D_OUT=P2^6;
sbit _CS=P3^0;
/********************************/
sbit lcdrs=P2^0;
sbit lcdrw=P2^1;
sbit lcden=P2^2;
/********************************/
sbit in1=P2^3;
sbit in2=P2^4;
/********************************/
sbit led=P3^2;
sbit speaker=P3^3;
/*****************引脚定义*********************************/
/*****************变量定义(申明)*********************************/
int freq=500,pwm=0;
uchar setflag=0,pageflag=0,ok=0;
float pwm_temp=0;
float KP=100,KI=10,KD=0;
uint pul_count=0;
float ek=0,ek1=0,ek2=0;
float keytemp=0;
uchar code str[16]=" welcome! ";
uchar code str1[16]=" temperature PID";
uchar code str2[16]="set-T pra-T " ;
uchar code str3[16]="P: I: D:" ;
uchar code str4[16]="set-P: " ;
uchar code str5[16]="set-I: " ;
uchar code str6[16]="set-D: " ;
void Init(void);
uint adcread(uchar port);
void delay(uint n);
void writecom(uchar com);
void writedata(uchar date);
void initlcd();
float keyscan(void);
uchar keyscans(void);
void lcdnumdisplay(uchar pos,double f);
void lcdnumdisplays(uchar pos,double f);
uint read_pul();
void mypid(float Kp,float Ki,float Kd,uint count,uint point);
/*****************变量定义(申明)*********************************/
void main()
{
uchar i;float scantemp;
float adnum0=0;
float adnum1=0;
bit init0,init1,init2,init3,init4;
Init();
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str[i]); //huanyin
writecom(0x80+0x40);
for(i=0;i<16;i++)writedata(str1[i]); //shuming
delay(400);
while(1)
{
pwm_temp=500*(float)(adnum0)/4095;
//pwm=pwm_temp;
mypid(KP,KI,KD,adnum1,pwm_temp);
scantemp=keyscan();
if(adnum1>=pwm_temp-1.5&&adnum1<=pwm_temp+1.5)
{
led=0;
speaker=1;
}
else{
led=1;
speaker=0;
}
if(setflag==0)
{
adnum0=adcread(0);
adnum1=adcread(1)/10;
if(init0==0)
{
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str2[i]); //shuming
init0=1;init1=0;init2=0;init3=0;init4=0;
}
lcdnumdisplays(0x80+0x40,(float)pwm_temp); //pwm_temp
lcdnumdisplays(0x80+0x4a,(float)adnum1);
}
if(setflag!=0&&pageflag==0)
{
if(init1==0)
{
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str3[i]);
init0=0;init1=1;init2=0;init3=0;init4=0;
}
lcdnumdisplays(0x80+0x40,KP);
lcdnumdisplays(0x80+0x46,KI);
lcdnumdisplays(0x80+0x4D,KD);
}
if(setflag!=0&&pageflag==1)
{
if(init2==0)
{
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str4[i]);
init0=0;init1=0;init2=1;init3=0;init4=0;
}
lcdnumdisplays(0x80+0x40,scantemp);
if(ok==1){KP=scantemp;ok=0;}
}
if(setflag!=0&&pageflag==2)
{
if(init3==0)
{
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str5[i]);
init0=0;init1=0;init2=0;init3=1;init4=0;
}
lcdnumdisplays(0x80+0x40,scantemp);
if(ok==1){KI=scantemp;ok=0;}
}
if(setflag!=0&&pageflag==3)
{
if(init4==0)
{
initlcd();
writecom(0x80);
for(i=0;i<16;i++)writedata(str6[i]);
init0=0;init1=0;init2=0;init3=0;init4=1;
}
lcdnumdisplays(0x80+0x40,scantemp);
if(ok==1){KD=scantemp;ok=0;}
}
}
}
void mypid(float Kp,float Ki,float Kd,uint count,uint point)
{
static float Uk;
ek=point-count;
// if(ek>=5&&ek<=-5) //积分分离
{Uk=Kp*(ek-ek1)+Ki*ek+Kd*(ek-2*ek1+ek2);}
// else
// Uk=Kp*ek;
pwm=pwm+Uk;
if(pwm>freq)pwm=freq;
if(pwm<=0){pwm=0;in1=0;in2=1;}
if(pwm>0) {in1=1;in2=0;}
ek2=ek1;
ek1=ek;
}
uint read_pul()
{
uint t1,th1,th2;
uint val;
while(1)
{
th1=TH1;
t1=TL1;
th2=TH1;
if(th1==th2)
break;
}
val=th1*256+t1;
return val;
}
void delay(uint n)
{
uint i,j;
for(i=n;i>0;i--)
for(j=1;j>0;j--);
}
void Init(void)//初始化函数
{
TMOD=0x51;
TH0=(65536-10)/256;
TL0=(65536-10)%256;
EA=1;
ET0=1;
TR0=1;
TH1=0;
TL1=0;
TR1=1;
}
void Timer_0(void) interrupt 1
{
static ulong t_count=0;
static uint num_count=0;
TR0=0;
TH0=(65536-10)/256;
TL0=(65536-10)%256;
TR0=1;
num_count++;
// t_count++;
// if(t_count==2320)
// {
// t_count=0;
// TR1=0;
// pul_count=read_pul();
// TH1=0;
// TL1=0;
// TR1=1;
// }
if(num_count>freq)num_count=0; //1khz;
if(num_count<pwm)output=1;
else output=0;
}
void writecom(uchar com)
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void writedata(uchar date)
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void initlcd()
{
lcdrw=0;
writecom(0x38);delay(1);
writecom(0x0c);delay(1);
writecom(0x06);delay(1);
writecom(0x01);delay(5);
}
uint adcread(uchar port)
{
uint ad=0,i;
CLOCK=0;
_CS=0;
port<<=4;
for(i=0;i<12;i++)
{
if(D_OUT) ad|=0x01;
D_IN=(bit)(port&0x80);
CLOCK=1;
delay(1);
CLOCK=0;
delay(1);
port<<=1;
ad<<=1;
}
_CS=1;
ad>>=1;
return(ad);
}
void lcdnumdisplays(uchar pos,float f) //(0.001-99999) 精度低 但方便数据更新
{
uchar i;
writecom(pos);
if(f>65535&&f<0.001) for(i=0;i<5;i++)writedata(0x23);//超出范围 显示#
else if(f==0){writedata(0x30);for(i=0;i<4;i++)writedata(0x20);}
else
{
if((uint)f/10000!=0)
{
writedata((uint)f/10000+0x30);
writedata((uint)f%10000/1000+0x30);
writedata((uint)f%1000/100+0x30);
writedata((uint)f%100/10+0x30);
writedata((uint)f%10+0x30);
}
else
{
if((uint)f/1000!=0)
{
writedata(0+0x30);
writedata((uint)f/1000+0x30);
writedata((uint)f%1000/100+0x30);
writedata((uint)f%100/10+0x30);
writedata((uint)f%10+0x30);
}
else
{
if((uint)f/100!=0)
{
writedata((uint)f/100+0x30);
writedata((uint)f%100/10+0x30);
writedata((uint)f%10+0x30);
writedata(0x2e);
writedata((uint)(f*10)%10+0x30);
}
else
{
if((uint)f/10!=0)
{
writedata((uint)f/10+0x30);
writedata((uint)f%10+0x30);
writedata(0x2e);
writedata((uint)(f*10)%10+0x30);
writedata((uint)(f*100)%10+0x30);
}
else
{
writedata((uint)f%10+0x30);
writedata(0x2e);
writedata((uint)(f*10)%10+0x30);
writedata((uint)(f*100)%10+0x30);
writedata((uint)(f*1000)%10+0x30);
}
}
}
}
}
}
void lcdnumdisplay(uchar pos,float f0) //(0.00001-99999.99999) 精度高 但数据需刷屏更新
{
uchar temp;
ulong f;
writecom(pos);
f=(ulong)f0;
temp=f/10000; //整数部分
if(temp!=0)
{
writedata(temp+0x30);
writedata(f%10000/1000+0x30);
writedata(f%1000/100+0x30);
writedata(f%100/10+0x30);
writedata(f%10+0x30);
}
else
{
temp=f%10000/1000;
if(temp!=0)
{
writedata(temp+0x30);
writedata(f%1000/100+0x30);
writedata(f%100/10+0x30);
writedata(f%10+0x30);
}
else
{
temp=f%1000/100;
if(temp!=0)
{
writedata(temp+0x30);
writedata(f%100/10+0x30);
writedata(f%10+0x30);
}
else
{
temp=f%100/10;
if(temp!=0)
{
writedata(temp+0x30);
writedata(f%10+0x30);
}
else
{
temp=f%10;
if(temp!=0)
{
writedata(temp+0x30);
}
else writedata(0+0x30);
}