温度的PID控制及程序示例.doc
《温度的PID控制及程序示例.doc》由会员分享,可在线阅读,更多相关《温度的PID控制及程序示例.doc(9页珍藏版)》请在冰豆网上搜索。
温度的PID控制
一.温度检测部分首先要OK.
二、PID调节作用
PID控制时域的公式
分解开来:
(1)比例调节器
y(t)=Kp*e(t)
e(k)为当前的温差(设定值与检测值的插值)
y(k)为当前输出的控制信号(需要转化为PWM形式)
#输出与输入偏差成正比。
只要偏差出现,就能及时地产生与之成比例的调节作用,使被控量朝着减小偏差的方向变化,具有调节及时的特点。
但是,Kp过大会导致动态品质变坏,甚至使系统不稳定。
比例调节器的特性曲线.
(2)积分调节器
y(t)=Ki*∫(e(t))dtKi=Kp/TiTi为积分时间
#TI是积分时间常数,它表示积分速度的大小,Ti越大,积分速度越慢,积分作用越弱。
只要偏差不为零就会产生对应的控制量并依此影响被控量。
增大Ti会减小积分作用,即减慢消除静差的过程,减小超调,提高稳定性。
(3)微分调节器
y(t)=Kd*d(e(t))/dtKd=Kp*TdTd为微分时间
#微分分量对偏差的任何变化都会产生控制作用,以调整系统输出,阻止偏差变化。
偏差变化越快,则产生的阻止作用越大。
从分析看出,微分作用的特点是:
加入微分调节将有助于减小超调量,克服震荡,使系统趋于稳定。
他加快了系统的动作速度,减小调整的时间,从而改善了系统的动态性能。
三.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
P
δS
PI
1.2δS
2Tr
PID
0.8δS
1.2Tr
0.4Tr
大致计算出Kp,Ti,Td后代入公式,然后完善算法。
让系统运作多测试几次。
直到满意为止。
以下是网上找的一个示例程序
#include
#include
#defineN040536
#definenop()_nop_()
#defineucharunsignedchar
#defineuintunsignedint
/*程序中变量数组定义*/
ucharidatatable[]={"Real-timeTemp:
"};//第一行显示"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>0;y--);
}
/******************************
LCD忙检测
*******************************/
bitlcd_busy()
{
bitresult;
lcdrw=1;
lcdrs=0;
lcden=1;
nop();nop();nop();nop();
result=(bit)(P0&0x80);
lcden=0;
return(result);
}
/******************************
LCD写命令子程序
*******************************/
voidwrite_com(ucharcom)
{
while(lcd_busy());//忙等待
lcdrs=0;
lcdrw=0;
P1=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/******************************
LCD写数据子程序
*******************************/
voidwrite_data(uchardate)
{
while(lcd_busy());//忙等待
lcdrs=1;
lcdrw=0;
P1=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/******************************
LCD初始化
*******************************/
voidlcd_init()
{
lcden=0;
write_com(0x38);
delay(5);
write_com(0x0f);
delay(5);
write_com(0x06);
delay(5);
write_com(0x01);
delay(5);
write_com(0x80);
delay(5);
write_com(0x01);
}
/******************************
定时器初始化
*******************************/
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 {
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=uk+duk;
if(uk>100)
uk=10