基于PID的水温控制系统文档格式.docx
《基于PID的水温控制系统文档格式.docx》由会员分享,可在线阅读,更多相关《基于PID的水温控制系统文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
uchari;
for(i=0;
i<
8;
i++)
temp=0;
temp=dat&
0x01;
delay10us(10);
dat>
>
=1;
//先写低位。
}
ucharreaddata()//从ds18b20读数据。
uchardat;
dat>
//先读低位。
temp=1;
if(temp)
dat=dat|0x80;
//延时136us;
return(dat);
voidreadtemperature()
uchartemperh,temperl;
rst18b20();
writedata(0xcc);
//跳过读rom命令直接给器件发命令。
writedata(0x44);
//启动ds18b20读取温度。
//必须二次复位。
writedata(0xbe);
temperl=readdata();
//读取温度低字节。
temperh=readdata();
//读取温度高字节。
tvalue=temperh;
tvalue<
<
=8;
tvalue=tvalue|temperl;
//组成16位合成字。
if(tvalue<
0x0fff)//是否为正数。
w_fh=0;
else//负数转换程序。
w_fh=1;
tvalue=~tvalue+1;
temperature=tvalue*0.0625;
tvalue=(tvalue*6.25);
//温度转换,强制转换成整形数。
w_shi=tvalue/1000;
//十位
w_ge=tvalue%1000/100;
//个位
w_shif=tvalue%100/10;
//shifen位
w_baif=tvalue%10;
//baifenwei
voidinit()
{
P27=1;
TMOD=0x11;
TH0=0x3c;
//50ms采样一次;
TL0=0xb0;
//TH1=0x9c;
//TL1=0x9c;
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
EX0=1;
IT0=1;
ET0=1;
TR0=1;
ET1=1;
TR1=1;
voidrupttime1()interrupt3
{
/*if(--f==0)
P27=0;
if(--p==0)
p=20000;
f=g;
}*/
nnn++;
if(nnn==g){P27=0;
if(nnn==1000){P27=1;
nnn=0;
}
voidrupttime0()interrupt1
ucharmin,sec;
readtemperature();
if(--count==0)
time++;
//执行时间
t_min=time/60;
//分
min=t_min;
//保持
t_min=t_min/10;
//分十位
t_minf=min%10;
//分个位
t_sec=time%60;
//秒
sec=t_sec;
t_sec=t_sec/10;
//秒十位
t_ge=sec%10;
//秒个位
asciiset(40,2,0x28);
//'
('
asciiset(46,2,w_shi+0x30);
//温度十位
asciiset(52,2,w_ge+0x30);
//温度个位
asciiset(58,2,0x2e);
//‘.’
asciiset(64,2,w_shif+0x30);
//温度十分位
asciiset(70,2,w_baif+0x30);
//温度百分位
asciiset(76,2,0x29);
)'
asciiset(82,2,'
s'
);
asciiset(88,2,'
e'
asciiset(94,2,'
t'
asciiset(100,2,0x3a);
asciiset(106,2,shi);
asciiset(114,2,ge);
asciiset(120,2,'
C'
asciiset(90,36,0x3a);
//:
asciiset(96,36,t_min+0x30);
asciiset(102,36,t_minf+0x30);
//分个位
asciiset(108,36,0x3a);
//:
asciiset(114,36,t_sec+0x30);
asciiset(120,36,t_ge+0x30);
asciiset(66,25,'
u'
asciiset(72,25,'
k'
asciiset(78,25,'
:
'
asciiset(84,25,uk_qian+0x30);
//uk千位
asciiset(90,25,uk_bai+0x30);
//uk百位
asciiset(96,25,uk_shi+0x30);
//uk十位.
asciiset(102,25,uk_ge+0x30);
//uk个位.
asciiset(66,14,'
q'
asciiset(72,14,'
='
asciiset(78,14,q_ge+0x30);
asciiset(84,14,'
.'
asciiset(90,14,q_shif+0x30);
asciiset(96,14,q_baif+0x30);
count=20;
if(--cont==0)
xx+=1;
pointset((xx+10),(Z-(tvalue-2000)/140));
//温度曲线描述;
cont=500;
if(xx>
111)
{
xx=0;
clrscreen();
xyset();
//建立坐标系;
voidruptinte0()interrupt0//按键中断子函数
P2=0xff;
if(P2!
=0xff)
delay(8);
switch(P2)
case(0xfd):
set_temp++;
if(set_temp>
100);
temp=0;
break;
case(0xfb):
set_temp--;
default:
}
}
voidsettempdeal()
shi=set_temp/10+0x30;
ge=set_temp%10+0x30;
voidukdeal()//显示控制电压子函数
z_uk=(uint)uk;
uk_qian=z_uk/1000;
uk_bai=z_uk%1000/100;
uk_shi=z_uk%1000%100/10;
uk_ge=z_uk%10;
voidqdeal()//显示占空比子函数
uintx;
x=(uint)(bfb*100.0);
q_ge=x/100;
q_shif=x%100/10;
q_baif=x%10;
voidmain()
init();
rst();
setbacklight();
clrscreen();
cs=0;
zibigset(0x11);
send(0x81);
//设置ASCII字符类型;
send(0x01);
//6X10字体,字符为黑色;
send(0x83);
//设置绘图色;
send
(1);
//黑色;
xianhan(16,4,table1);
//水
xianhan(32,4,table2);
//温
xianhan(48,4,table3);
//控
xianhan(62,4,table4);
//制
xianhan(78,4,table5);
//系
xianhan(94,4,table6);
//统
xianhan(24,38,table7);
xianhan(40,38,table8);
asciiset(56,38,0x3a);
//显示冒号;
xianhan(64,38,table9);
xianhan(80,38,table0);
delay(500);
EA=1;
while
(1){
settempdeal();
//预设值处理
ukdeal();
//控制电压值处理
if(temperature>
=set_temp)
P27=0;
TR1=0;
elseif(temperature>
=(set_temp-4))
calcpid(set_temp,temperature);
bfb=(uk/220.0);
qdeal();
//占空比值处理
if(bfb>
=1.0)
{
TR1=0;
P27=1;
}
elseif(bfb<
=0.0)
P27=0;
}
else
{
TR1=1;
g=(uint)(bfb*1000);
else
#defineuintunsignedint//ki=0.003,kd=1084.0;
kp=1.3;
//80度;
#defineucharunsignedchar//ki=0.003,kd=1284.0;
kp=0.82;
floatki=0.003;
floatkd=1084.0;
floatkp=1.3;
floatek;
//当前偏差
floatek1;
//上一次偏差
floatek2;
//上上一次偏差
floatd_uk;
//当前偏差电压
floatuk1;
//上一次输出电压
floatuk;
//本次输出电压
//floatukmax;
//第一次偏差最大值
//floatsumerror;
//历史偏差和
/*voidcalcpiid(floats_temp,floatnow_temp)//积分分离增量式pid;
ukmax=5.0*(kp+kd);
ek=s_temp-now_temp;
if(ek>
1.0)
d_uk=kp*(ek-ek1)+kd*(ek-2*ek1+ek2);
else
d_uk=kp*(ek-ek1)+ki*ek+kd*(ek-2*ek1+ek2);
uk=d_uk+uk1;
ek2=ek1;
ek1=ek;
uk1=uk;
}*/
/*voidcalcpiiid(floats_temp,floatnow_temp)//遇限削弱积分法;
if(uk1>
=ukmax)
0);
d_uk+=ki*ek;
if(uk1<
if(ek<
d_uk+=I*ek;
uk=uk1+d_uk;
voidcalcpid(floats_temp,floatnow_temp)//增量式
//ukmax=5.0*(kp+ki+kd);
}
#defineuintunsignedint
#defineucharunsignedchar
ucharcodetable1[]={"
水"
};
ucharcodetable2[]={"
温"
ucharcodetable3[]={"
控"
ucharcodetable4[]={"
制"
ucharcodetable5[]={"
系"
ucharcodetable6[]={"
统"
ucharcodetable7[]={"
作"
ucharcodetable8[]={"
者"
ucharcodetable9[]={"
李"
ucharcodetable0[]={"
奕"
ucharcodetable00[]={"
度"
ucharcodetable01[]={"
时"
ucharcodetable02[]={"
间"
sbitcs=P1^0;
sbitsda=P1^1;
sbitsck=P1^3;
sbitcrst=P1^4;
voiddelay10us(uintn)
do{
_nop_();
}while(--n);
voiddelay(uintn)
delay10us(131);
voidsend(ucharda)
uinti;
sck=0;
sda=da&
0x80;
sck=1;
da<
voidrst()
sck=1;
cs=1;
crst=0;
delay(3);
crst=1;
delay(10);
voidclrscreen()
send(0x80);
voidasciiset(ucharx,uchary,uchara)//写阿斯科码;
send(0x07);
send(x);
send(y);
send(a);
voidsetbacklight()
send(0x8a);
send(110);
voidbitflash()//绘制图像;
uchari,j;
send(0x0e);
send(0);
send(104);
send(46);
46;
for(j=0;
j<
13;
j++)
send(table1[i*13+j]);
voidpointset(ucharx,uchary)//描点;
voiddanwei()//描坐标点;
uinti,j;
for(j=20;
111;
j+=10)
pointset(j,56);
for(i=45;
i>
14;
i-=10)
pointset(9,i);
voidzibigset(ucharx)//设置字体大小
send(0x82);
//设置汉字库类型;
//16X16字体,字符为黑色;
voidxianhan(ucharx,uchary,uchar*p)//写汉字;
send(0x08);
2;
send(p[i]);
voidxyset()//绘制坐标系
send(0x02);
//绘制x,y横纵坐标;
send(10);
//横坐标起点为10,终点为111;
send(55);
send(111);
//纵坐标起点为55,终点8;
send(3);
pointset(9,4);
//绘制箭头;
pointset(8,5);
pointset(11,4);
pointset(12,5);
pointset(110,54);
pointset(110,56);
pointset(109,53);
pointset(109,57);
danwei();
//绘制单位坐标点;
asciiset(2,0,'
T'
asciiset(120,54,'
zibigset(0x01);
xianhan(66,36,table01);
xianhan(78,36,table02);
xianhan(16,0,table2);
xianhan(28,0,table00);