温度的PID控制及程序示例文档格式.doc
《温度的PID控制及程序示例文档格式.doc》由会员分享,可在线阅读,更多相关《温度的PID控制及程序示例文档格式.doc(9页珍藏版)》请在冰豆网上搜索。
加入微分调节将有助于减小超调量,克服震荡,使系统趋于稳定。
他加快了系统的动作速度,减小调整的时间,从而改善了系统的动态性能。
三.PID算法:
由时域的公式离散化后可得如下公式:
y(k)=y(k-1)+(Kp+Ki+Kd)*e(k)-(Kp+2*Kd)*e(k-1)+Kd*e(k-2)
y(k)为当前输出的控制信号(需要转化为PWM形式)
y(k-1)为前一次输出的控制信号
e(k)为当前的温差(设定值与检测值的插值)
e(k-1)为一次前的温差
e(k-2)为二次前的温差
Kp为比例系数
Ki=Kp*T/TiT为采样周期
Kd=Kp*Td/T
四.PID参数整定(确定Kp,Ts,Ti,Td):
温度控制适合衰减曲线法,需要根据多次采样的数据画出响应曲线。
所以需要通过串口将采样时间t,输出y(t)记录下来,方便分析。
1)、不加入算法,系统全速加热,从常温加热到较高的温度的时间为Tk,则采样时间一般设为T=Tk/10。
2)、置调节器积分时间TI=∞,微分时间TD=0,即只加比例算法:
y(k)=y(k-1)+Kp*e(k)
比例带δ置于较大的值。
将系统投入运行。
(δ=1/Kp)
3)、待系统工作稳定后,对设定值作阶跃扰动,然后观察系统的响应。
若响应振荡衰减太快,就减小比例带;
反之,则增大比例带。
如此反复,直到出现如图所示的衰减比为4:
1的振荡过程时,记录此时的δ值(设为δS),以及TS的值(如图中所示)。
当采用衰减比为10:
1振荡过程时,应用上升时间Tr替代振荡周期TS计算。
系统衰减振荡曲线
图中,TS为衰减振荡周期,Tr为响应上升时间。
据表中所给的经验公式计算δ、TI及TD的参数。
表衰减曲线法整定计算公式
衰减率ψ
整定参数
调节规律
δ(1/Kp)
TI
TD
0.75
P
δS
PI
1.2δS
0.5TS
PID
0.8δS
0.3TS
0.1TS
0.9
2Tr
1.2Tr
0.4Tr
大致计算出Kp,Ti,Td后代入公式,然后完善算法。
让系统运作多测试几次。
直到满意为止。
以下是网上找的一个示例程序
#include<
reg51.h>
intrins.h>
#defineN040536
#definenop()_nop_()
#defineucharunsignedchar
#defineuintunsignedint
/*程序中变量数组定义*/
ucharidatatable[]={"
Real-timeTemp:
"
};
//第一行显示"
ucharidatatable1[5];
uchardata1,kp,ki,kd;
uintt,hightime,count;
//占空比调节参数
uintrltemp,settemp=350;
inte1,e2,e3,duk,uk;
/*引脚定义*/
sbitEOC=P2^6;
sbitOE=P2^5;
sbitSTART=P2^7;
sbitlcden=P3^2;
sbitlcdrw=P3^1;
sbitlcdrs=P3^0;
sbitpwm=P3^3;
/******************************
延时子程序
*******************************/
voiddelay(uintz)
{
uintx,y;
for(x=z;
x>
0;
x--)
for(y=29;
y>
y--);
}
LCD忙检测
bitlcd_busy()
{
bitresult;
lcdrw=1;
lcdrs=0;
lcden=1;
nop();
nop();
result=(bit)(P0&
0x80);
lcden=0;
return(result);
LCD写命令子程序
voidwrite_com(ucharcom)
while(lcd_busy());
//忙等待
lcdrw=0;
P1=com;
delay(5);
LCD写数据子程序
voidwrite_data(uchardate)
//忙等待
lcdrs=1;
P1=date;
LCD初始化
voidlcd_init()
write_com(0x38);
write_com(0x0f);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
定时器初始化
voidtime_init()
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
TMOD=0x11;
TH0=N0/256;
TL0=N0%256;
TH1=0X3C;
TL1=0XB0;
PID算法系数装载
voidPid_init()
hightime=0;
//输出的占空比
e1=0;
//本次的温度差
e2=0;
//前一次的温度差
e3=0;
//两次前的温度差
kp=10;
//需要根据试验确定参数
ki=5;
//需要根据试验确定参数
kd=5;
//需要根据试验确定参数
温度比较PID算法
voidpid_ys()
if(rltemp<
settemp) // 如果实际温度小于设定温度值
{
if(settemp-rltemp>
20)//如果相差20度(根据实际情况确定是多少)
{
hightime=100;
//全速加热
}
else //否则运行PID算法进行平滑加热
{
e1=settemp-rltemp;
duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3))/10;
//式
(1)因为Kp是10,输入放大了10倍,所以duk的输出结果需要除以10
uk=uk+duk;
/*****************************
式
(1)与上面提到的公式类似y(k)=y(k-1)+(Kp+Ki+Kd)*e(k)-(Kp+2*Kd)*e(k-1)+Kd*e(k-2)可以写成y(k)-y(k-1)=(kp*(e(k)-e(k))+ki*e(k)+kd*(e(k)-e(k-1)*2+e(k-2))式
(1)中duk相当于y(k)-(k-1)
*****************************/
if(uk>
100)
uk=100;
//设置饱和控制,
elseif(uk<
-100)
uk=-100;
if(uk<
0)
{
hightime=-uk;
}
else
hightime=uk;
e3=e2;
e2=e1;
}
if(rltemp>
=settemp) // 如果实际温度大于设定值
if(rltemp-settemp>
0)//只要实际温度与设定值不相等
hightime=0;
//停止加热
else /
e1=rltemp-settemp;
duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3));
uk=10