温度的PID控制及程序示例

合集下载

温度的PID控制及程序示例

温度的PID控制及程序示例

温度的PID 控制一.温度检测部分首先要OK. 二、PID 调节作用 PID 控制时域的公式))()(1)(()(⎰++=dtt de Td t e Ti t e Kp t y 分解开来:(1) 比例调节器y(t) = Kp * e(t)e(k) 为当前的温差(设定值与检测值的插值) y(k) 为当前输出的控制信号(需要转化为PWM 形式)# 输出与输入偏差成正比。

只要偏差出现,就能及时地产生与之成比例的调节作用,使被控量朝着减小偏差的方向变化,具有调节及时的特点。

但是, Kp 过大会导致动态品质变坏,甚至使系统不稳定。

比例调节器的特性曲线. (2) 积分调节器y(t) = Ki * ∫(e(t))dt Ki = Kp/Ti Ti 为积分时间#TI 是积分时间常数,它表示积分速度的大小,Ti 越大,积分速度越慢,积分作用越弱。

只要偏差不为零就会产生对应的控制量并依此影响被控量。

增大Ti 会减小积分作用,即减慢消除静差的过程,减小超调,提高稳定性。

(3) 微分调节器y(t) = Kd*d(e(t))/dt Kd = Kp*Td Td 为微分时间#微分分量对偏差的任何变化都会产生控制作用,以调整系统输出,阻止偏差变化。

偏差变化越快,则产生的阻止作用越大。

从分析看出,微分作用的特点是:加入微分调节将有助于减小超调量,克服震荡,使系统趋于稳定。

他加快了系统的动作速度,减小调整的时间,从而改善了系统的动态性能。

三.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/Ti T为采样周期Kd = Kp*Td/T四.PID参数整定(确定Kp,Ts,Ti,Td):温度控制适合衰减曲线法,需要根据多次采样的数据画出响应曲线。

温度控制的PID算法的C语言程序

温度控制的PID算法的C语言程序

基于PID算法的温度控制系统89C51单片机,通过键盘输入预设值,与DS18B20测得的实际值做比较,然后驱动制冷或加热电路。

用keil C语言来实现PID的控制。

//PID算法温控C语言2008-08-17 18:58#include<reg51.h>#include<intrins.h>#include<math.h>#include<string.h>struct PID {unsigned int SetPoint; // 设定目标Desired Valueunsigned int Proportion; // 比例常数Proportional Constunsigned int Integral; // 积分常数Integral Constunsigned int Derivative; // 微分常数Derivative Constunsigned int LastError; // Error[-1]unsigned int PrevError; // Error[-2]unsigned int SumError; // Sums of Errors};struct PID spid; // PID Control Structureunsigned int rout; // PID Response (Output)unsigned int rin; // PID Feedback (Input)sbit data1=P1^0;sbit clk=P1^1;sbit plus=P2^0;sbit subs=P2^1;sbit stop=P2^2;sbit output=P3^4;sbit DQ=P3^3;unsigned char flag,flag_1=0;unsigned char high_time,low_time,count=0;//占空比调节参数unsigned char set_temper=35;unsigned char temper;unsigned char i;unsigned char j=0;unsigned int s;/***********************************************************延时子程序,延时时间以12M晶振为准,延时时间为30us×time***********************************************************/void delay(unsigned char time){unsigned char m,n;for(n=0;n<time;n++)for(m=0;m<2;m++){}}/*********************************************************** 写一位数据子程序***********************************************************/ void write_bit(unsigned char bitval){EA=0;DQ=0; /*拉低DQ以开始一个写时序*/if(bitval==1){_nop_();DQ=1; /*如要写1,则将总线置高*/}delay(5); /*延时90us供DA18B20采样*/DQ=1; /*释放DQ总线*/_nop_();_nop_();EA=1;}/*********************************************************** 写一字节数据子程序***********************************************************/ void write_byte(unsigned char val){unsigned char i;unsigned char temp;EA=0; /*关中断*/TR0=0;for(i=0;i<8;i++) /*写一字节数据,一次写一位*/{temp=val>>i; /*移位操作,将本次要写的位移到最低位*/temp=temp&1;write_bit(temp); /*向总线写该位*/}delay(7); /*延时120us后*/// TR0=1;EA=1; /*开中断*/}/*********************************************************** 读一位数据子程序***********************************************************/ unsigned char read_bit(){unsigned char i,value_bit;EA=0;DQ=0; /*拉低DQ,开始读时序*/_nop_();_nop_();DQ=1; /*释放总线*/for(i=0;i<2;i++){}value_bit=DQ;EA=1;return(value_bit);}/*********************************************************** 读一字节数据子程序***********************************************************/ unsigned char read_byte(){unsigned char i,value=0;EA=0;for(i=0;i<8;i++){if(read_bit()) /*读一字节数据,一个时序中读一次,并作移位处理*/ value|=0x01<<i;delay(4); /*延时80us以完成此次都时序,之后再读下一数据*/}EA=1;return(value);}/*********************************************************** 复位子程序***********************************************************/ unsigned char reset(){unsigned char presence;EA=0;DQ=0; /*拉低DQ总线开始复位*/delay(30); /*保持低电平480us*/DQ=1; /*释放总线*/delay(3);presence=DQ; /*获取应答信号*/delay(28); /*延时以完成整个时序*/EA=1;return(presence); /*返回应答信号,有芯片应答返回0,无芯片则返回1*/}/***********************************************************获取温度子程序***********************************************************/void get_temper(){unsigned char i,j;do{i=reset(); /*复位*/}while(i!=0); /*1为无反馈信号*/i=0xcc; /*发送设备定位命令*/write_byte(i);i=0x44; /*发送开始转换命令*/write_byte(i);delay(180); /*延时*/do{i=reset(); /*复位*/}while(i!=0);i=0xcc; /*设备定位*/write_byte(i);i=0xbe; /*读出缓冲区容*/write_byte(i);j=read_byte();i=read_byte();i=(i<<4)&0x7f;s=(unsigned int)(j&0x0f);s=(s*100)/16;j=j>>4;temper=i|j; /*获取的温度放在temper中*/}/*============================================================================= =======================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); // 微分项}/***********************************************************温度比较处理子程序***********************************************************/pare_temper(){unsigned char i;if(set_temper>temper){if(set_temper-temper>1){high_time=100;low_time=0;}else{for(i=0;i<10;i++){ get_temper();rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation}if (high_time<=100)high_time=(unsigned char)(rout/800);elsehigh_time=100;low_time= (100-high_time);}}else if(set_temper<=temper){if(temper-set_temper>0){high_time=0;low_time=100;}else{for(i=0;i<10;i++){ get_temper();rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation}if (high_time<100)high_time=(unsigned char)(rout/10000);elsehigh_time=0;low_time= (100-high_time);}}// else// {}}/***************************************************** T0中断服务子程序,用于控制电平的翻转,40us*100=4ms周期******************************************************/ void serve_T0() interrupt 1 using 1{if(++count<=(high_time))output=1;else if(count<=100){output=0;}elsecount=0;TH0=0x2f;}/***************************************************** 串行口中断服务程序,用于上位机通讯******************************************************/ void serve_sio() interrupt 4 using 2{/* EA=0;RI=0;i=SBUF;if(i==2){while(RI==0){}RI=0;set_temper=SBUF;SBUF=0x02;while(TI==0){}TI=0;}else if(i==3){TI=0;SBUF=temper;while(TI==0){}TI=0;}EA=1; */}void disp_1(unsigned char disp_num1[6]){unsigned char n,a,m;for(n=0;n<6;n++){// k=disp_num1[n];for(a=0;a<8;a++){clk=0;m=(disp_num1[n]&1);disp_num1[n]=disp_num1[n]>>1;if(m==1)data1=1;else_nop_();clk=1;_nop_();}}}/*****************************************************显示子程序功能:将占空比温度转化为单个字符,显示占空比和测得到的温度******************************************************/void display(){unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; unsigned char disp_num[6];unsigned int k,k1;k=high_time;k=k%1000;k1=k/100;if(k1==0)disp_num[0]=0;elsedisp_num[0]=0x60;k=k%100;disp_num[1]=number[k/10];disp_num[2]=number[k%10];k=temper;k=k%100;disp_num[3]=number[k/10];disp_num[4]=number[k%10]+1;disp_num[5]=number[s/10];disp_1(disp_num);}/***********************************************************主程序***********************************************************/main(){unsigned char z;unsigned char a,b,flag_2=1,count1=0;unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};TMOD=0x21;TL0=0x40;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 while(1){if(plus==0){EA=0;for(a=0;a<5;a++)for(b=0;b<102;b++){}if(plus==0){set_temper++;flag=0;}}else if(subs==0){for(a=0;a<5;a++)for(b=0;a<102;b++){}if(subs==0){set_temper--;flag=0;}}else if(stop==0) {for(a=0;a<5;a++)for(b=0;b<102;b++){} if(stop==0){flag=0;break;}EA=1;}get_temper();b=temper;if(flag_2==1)a=b;if((abs(a-b))>5) temper=a;elsetemper=b;a=temper;flag_2=0;if(++count1>30) {display();count1=0;}pare_temper();}TR0=0;z=1;while(1){EA=0;if(stop==0){for(a=0;a<5;a++)for(b=0;b<102;b++){} if(stop==0)disp_1(phil);// break;}EA=1;}}//DS18b20 子程序#include <REG52.H>sbit DQ=P2^1; //定义端口typedef unsigned char byte;typedef unsigned int word;//延时void delay(word useconds){for(;useconds>0;useconds--);}//复位byte ow_reset(void){byte presence;DQ=0; //DQ低电平delay(29); //480usDQ=1; //DQ高电平delay(3); //等待presence=DQ; //presence信号delay(25);return(presence);} //0允许,1禁止//从1-wire 总线上读取一个字节byte read_byte(viod){byte i;byte value=0;for (i=8;i>0;i--){value>>=1;DQ=0;DQ=1;delay(1);if(DQ)value|=0x80;delay(6);}return(value);}//向1-wire总线上写一个字节void write_byte(char val){byte i;for (i=8;i>0;i--) //一次写一个字节{DQ=0;DQ=val&0x01;delay(5);DQ=1;val=val/2;}delay(5);}//读取温度char Read_Temperature(void){union{byte c[2];int x;}temp;ow_reset();write_byte(0xcc);write_byte(0xBE);temp.c[1]=read_byte();temp.c[0]=read_byte();ow_reset();write_byte(0xCC);write_byte(0x44);return temp.x/2;}参考资料:你把这两个程序组合就可以了PID算法PID算法是本程序中的核心部分。

温度控制的PID算法的C语言程序

温度控制的PID算法的C语言程序

温度控制的P I D算法的C语言程序Document number:WTWYT-WYWY-BTGTT-YTTYU-2018GT基于PID算法的温度控制系统89C51单片机,通过键盘输入预设值,与DS18B20测得的实际值做比较,然后驱动制冷或加热电路。

用keilC语言来实现PID的控制。

超低温漂移高精度运算放大器0P07将温度一电压信号进行放大,便于A/D进行转换,以提高温度采集电路的可靠性。

模拟电路硬件部分见图2。

图2温度电压转换电路电控制执行电路的设计由输出来控制电炉,电炉可以近似建立为具有滞后性质的一阶惯性环节数学模型。

其传递函数形式为:可控硅可以认为是线形环节实现对水温的控制。

单片机输出与电炉功率分别属于弱电与强电部分,需要进行隔离处理,这里采用光耦元件TLP521在控制部分进行光电隔离,此外采用变压器隔离实现弱强电的电源隔离。

单片机PWM输出电平为0时,光耦元件导通,从而使三极管形成有效偏置而导通,通过整流桥的电压经过集电极电阻以及射集反向偏压,有7V左右的电压加在双向可控硅控制端,从而使可控硅导通,交流通路形成,电阻炉工作;反之单片机输出电平为0时,光耦元件不能导通,三极管不能形成有效偏置而截止,可控硅控制端电压几乎为零,可控硅截止从而截断交流通路,电炉停止工作。

此外,还有越限报警,当温度低于下限时发光二极管亮;高上限时蜂鸣器叫。

控制执行部分的硬件电路如下:图3控制执行部分电路3键盘及显示的设计键盘采用软件查询和外部中断相结合的方法来,低电平有效。

图3中按键AN1,AN2,AN3,AN4,AN5的功能定义如表1所示。

按键AN3与相连,采用外部中断方式,并且优先级定为最高;按键AN5和AN4分别与和相连,采用软件查询的方式;AN1则为硬件复位键,与R、C构成复位电路。

表1按键功能按键键名功能显示采用3位共阳LED静态显示方式,显示内容有温度值的十位、个位及小数点后一位,这样可以只用(RXD)口来输出显示数据,从而节省了单片机端口资源,在口和(TXD)的控制下通过74LS164来实现3位静态显示。

PID温控程序

PID温控程序

以下为PID温控程序,没有采用SFB41是因为些模块比较大,影响系统反应速度。

些温度控制系统不用微分(D)控制,只用PI控制Kc 为回路的增Ts 为采样的时间间隔Ti 为积分时间MDSPn 为采样时刻n的设定值PVn 为采样时刻n的过程变量值MX 为采样时刻n-1的积分项(又称为积分前项)PID运算公式1:MPN=KC*(SPN-PVN)PID运算公式2;MIN=KC*TS/TI*(SPN-PVN)+MXPID运算公式3:MN=MPN+MIN不用微分(D)控制,原工式为:MN=MPN+MIN+MDNPI运算程序对应的DB1:主程序对应的DB2:模拟输入量:IW2模拟输出量:PQDOKc 为回路的增Ts 为采样的时间间隔Ti 为积分时间MDSPn 为采样时刻n的设定值PVn 为采样时刻n的过程变量值MX 为采样时刻n-1的积分项(又称为积分前项)对应地址:网络1和 2 是模拟采集的“模拟输入量:IW2”和组态画面上Kc Ts Ti SPn PVn 的设定值。

实际操作中不需要。

改变模拟输入量:IW2观察模拟输出量变化:PQDO观察模拟输出量变化:PQDO观察模拟输出量变化:PQDO观察模拟输出量变化:PQDOOK!其他变量改变后一样能回到平衡:如改以下值:Kc 为回路的增Ts 为采样的时间间隔Ti 为积分时间MDSPn 为采样时刻n的设定值以下为PID运算温控程序,没有采用SFB41是因为些模块比较大,影响系统反应速度。

些温度控制系统不用微分(D)控制,只用PI控制下面是主程序:FB2下面是各电机启动程序模拟量输入,数据格式转换模拟量输出,数据格式转换限制输出范围:0~32767停止后全部清零,为组态画面变量编写的程序以下为模拟给PN当前值,SP设定值,TI积分时间,TS采样时间,KC增益量,结果:FB2我们看一下温度显示:Kc DB2。

DBD 66 为回路的增Ts DB2。

DBD74 为采样的时间间隔Ti DB2。

温度控制的PID算法 及C程序实现

温度控制的PID算法 及C程序实现

温度控制与PID算法温度控制与PID算法j较为复杂,下面结合实际浅显易懂的阐述一下PID控制理论,将温度控制及PID算法作一个简单的描述。

1.温度控制的框图这是一个典型的闭环控制系统,用于控制加热温区的温度(PV)保持在恒定的温度设定值(SV)。

系统通过温度采集单元反馈回来的实时温度信号(PV)获取偏差值(EV),偏差值经过PID调节器运算输出,控制发热管的发热功率,以克服偏差,促使偏差趋近于零。

例如,当某一时刻炉内过PCB板较多,带走的热量较多时,即导致温区温度下降,这时,通过反馈的调节作用,将使温度迅速回升。

其调节过程如下:温度控制的功率输出采用脉宽调制的方法。

固态继电器SSR的输出端为脉宽可调的电压U OUT 。

当SSR的触发角触发时,电源电压U AN通过SSR的输出端加到发热管的两端;当SSR的触发角没有触发信号时,SSR关断。

因此,发热管两端的平均电压为U d=(t/T)* U AN=K* U AN其中K=t/T,为一个周期T中,SSR触发导通的比率,称为负载电压系数或是占空比,K 的变化率在0-1之间。

一般是周期T固定不便,调节t, 当t在0-T的范围内变化时,发热管的电压即在0-U AN之间变化,这种调节方法称为定频调宽法。

下面将要描述的PID 调节器的算式在这里的实质即是运算求出一个实时变化的,能够保证加热温区在外界干扰的情况下仍能保持温度在一个较小的范围内变化的合理的负载电压系数K。

2.温度控制的两个阶段温度控制系统是一个惯性较大的系统,也就是说,当给温区开始加热之后,并不能立即观察得到温区温度的明显上升;同样的,当关闭加热之后,温区的温度仍然有一定程度的上升。

另外,热电偶对温度的检测,与实际的温区温度相比较,也存在一定的滞后效应。

这给温度的控制带来了困难。

因此,如果在温度检测值(PV)到达设定值时才关断输出,可能因温度的滞后效应而长时间超出设定值,需要较长时间才能回到设定值;如果在温度检测值(PV)未到设定值时即关断输出,则可能因关断较早而导致温度难以达到设定值。

PID调节温度控制实例(西门子S7-300)

PID调节温度控制实例(西门子S7-300)

PID调节温度控制实例(西门⼦S7-300)控制要求
1.⽔罐⽔温设置在50℃
2.误差值在±1℃
硬件配置
设计⽅案
1.采样:使⽤ PT100 热电阻经过变送器把⽔缸温度传送给S7-300 PLC。

2. 数据的处理:在 S7-300 PLC 中经过 PID 调节运算输出模拟量信号到功率调节器中。

3.温度调节:在功率调节器中把对应的模拟量转化为对应的功率来驱动热得快;
程序编写
1. 创建名称为PID调节的⼯程,添加CPU314C-2DP.西门⼦CPU314C-2DP,⾃带有模
拟量输⼊输出通道,⽆需扩展模块,在这⾥我们要注意他们的地址,以及输⼊输出的测量类型与测量范围。

这次试验⽤的是4-20mA的变送器,输出我们采⽤0-10V电压输出,这些参数需要在硬件组态时进⾏设置,设置好以后注意编译保存下载。

2.程序的编写
3.PID 调节
⾸先在开始菜单中打开PID 调节⾯板,如下图所⽰:。

PID控制算法实例_电机_温度

PID控制算法实例_电机_温度

实验十七 直流电机控制实验一、 实验目的1. 学习数字控制器的模拟化设计方法;2. 学习数字PID 控制器的设计方法;3. 学习PWM 控制理论;4. 学习数字PID 控制器在DSP 上的实现方法。

二、实验设备 计算机,CCS 2.0版软件,实验箱、DSP 仿真器、导线。

三、基础理论 PID 控制器(按闭环系统误差的比例、积分和微分进行控制的调节器)自30年代末图1 模拟PID 控制期出现以来,在工业控制领域得到了很大的发展和广泛的应用。

它的结构简单,参数易于调整,在长期应用中已积累了丰富的经验。

特别是在工业过程控制中,由于被控制对象的精确的数学模型难以建立,系统的参数经常发生变化,运用控制理论分析综合不仅要耗费很大代价,而且难以得到预期的控制效果。

在应用计算机实现控制的系统中,PID 很容易通过编制计算机语言实现。

由于软件系统的灵活性,PID 算法可以得到修正和完善,从而使数字PID 具有很大的灵活性和适用性。

实现PID 控制的计算机控制系统如图1所示,其中数字PID 控制器是由软件编程在计算机内部实现的。

1、PID 控制规律的离散化PID 控制器是一种线性调节器,这种调节器是将系统的给定值r 与实际输出值y 构成的控制偏差y r c -=的比例(P )、积分(I )、微分(D ),通过线性组合构成控制量,所以简称PID 控制器。

连续控制系统中的模拟PID 控制规律为:])()(1)([)(0dtt de T dt t e T t e K t u D t I p ++=⎰ (式1)式中)(t u 是控制器的输出,)(t e 是系统给定量与输出量的偏差,P K 是比例系数,I T 是积分时间常数,D T 是微分时间常数。

其相应传递函数为:)11()(s T sT K s G D I p ++= (式2) 比例调节器、积分调节器和微分调节器的作用:(1)比例调节器:比例调节器对偏差是即时反应的,偏差一旦出现,调节器立即产生控制作用,使输出量朝着减小偏差的方向变化,控制作用的强弱取决于比例系数P K 。

温度控制的PID算法 及C程序实现

温度控制的PID算法 及C程序实现

温度控制与PID算法温度控制与PID算法j较为复杂,下面结合实际浅显易懂的阐述一下PID控制理论,将温度控制及PID算法作一个简单的描述。

1.温度控制的框图这是一个典型的闭环控制系统,用于控制加热温区的温度(PV)保持在恒定的温度设定值(SV)。

系统通过温度采集单元反馈回来的实时温度信号(PV)获取偏差值(EV),偏差值经过PID调节器运算输出,控制发热管的发热功率,以克服偏差,促使偏差趋近于零。

例如,当某一时刻炉内过PCB板较多,带走的热量较多时,即导致温区温度下降,这时,通过反馈的调节作用,将使温度迅速回升。

其调节过程如下:温度控制的功率输出采用脉宽调制的方法。

固态继电器SSR的输出端为脉宽可调的电压U OUT 。

当SSR的触发角触发时,电源电压U AN通过SSR的输出端加到发热管的两端;当SSR的触发角没有触发信号时,SSR关断。

因此,发热管两端的平均电压为U d=(t/T)* U AN=K* U AN其中K=t/T,为一个周期T中,SSR触发导通的比率,称为负载电压系数或是占空比,K 的变化率在0-1之间。

一般是周期T固定不便,调节t, 当t在0-T的范围内变化时,发热管的电压即在0-U AN之间变化,这种调节方法称为定频调宽法。

下面将要描述的PID 调节器的算式在这里的实质即是运算求出一个实时变化的,能够保证加热温区在外界干扰的情况下仍能保持温度在一个较小的范围内变化的合理的负载电压系数K。

2.温度控制的两个阶段温度控制系统是一个惯性较大的系统,也就是说,当给温区开始加热之后,并不能立即观察得到温区温度的明显上升;同样的,当关闭加热之后,温区的温度仍然有一定程度的上升。

另外,热电偶对温度的检测,与实际的温区温度相比较,也存在一定的滞后效应。

这给温度的控制带来了困难。

因此,如果在温度检测值(PV)到达设定值时才关断输出,可能因温度的滞后效应而长时间超出设定值,需要较长时间才能回到设定值;如果在温度检测值(PV)未到设定值时即关断输出,则可能因关断较早而导致温度难以达到设定值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

温度的PID 控制一.温度检测部分首先要OK. 二、PID 调节作用 PID 控制时域的公式))()(1)(()(⎰++=dtt de Td t e Ti t e Kp t y 分解开来:(1) 比例调节器y(t) = Kp * e(t)e(k) 为当前的温差(设定值与检测值的插值) y(k) 为当前输出的控制信号(需要转化为PWM 形式)# 输出与输入偏差成正比。

只要偏差出现,就能及时地产生与之成比例的调节作用,使被控量朝着减小偏差的方向变化,具有调节及时的特点。

但是, Kp 过大会导致动态品质变坏,甚至使系统不稳定。

比例调节器的特性曲线. (2) 积分调节器y(t) = Ki * ∫(e(t))dt Ki = Kp/Ti Ti 为积分时间#TI 是积分时间常数,它表示积分速度的大小,Ti 越大,积分速度越慢,积分作用越弱。

只要偏差不为零就会产生对应的控制量并依此影响被控量。

增大Ti 会减小积分作用,即减慢消除静差的过程,减小超调,提高稳定性。

(3) 微分调节器y(t) = Kd*d(e(t))/dt Kd = Kp*Td Td 为微分时间#微分分量对偏差的任何变化都会产生控制作用,以调整系统输出,阻止偏差变化。

偏差变化越快,则产生的阻止作用越大。

从分析看出,微分作用的特点是:加入微分调节将有助于减小超调量,克服震荡,使系统趋于稳定。

他加快了系统的动作速度,减小调整的时间,从而改善了系统的动态性能。

三.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/Ti T为采样周期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的参数。

大致计算出Kp,Ti,Td后代入公式,然后完善算法。

让系统运作多测试几次。

直到满意为止。

以下是网上找的一个示例程序#include<reg51.h>#include<intrins.h>#define N0 40536#define nop() _nop_()#define uchar unsigned char#define uint unsigned int/*程序中变量数组定义*/uchar idata table[]={"Real-time Temp:"};//第一行显示"Real-time Temp:"uchar idata table1[5];uchar data1,kp,ki,kd;uint t,hightime,count; //占空比调节参数uint rltemp,settemp=350;int e1,e2,e3,duk,uk;/*引脚定义*/sbit EOC=P2^6;sbit OE=P2^5;sbit START=P2^7;sbit lcden=P3^2;sbit lcdrw=P3^1;sbit lcdrs=P3^0;sbit pwm=P3^3;/******************************延时子程序*******************************/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=29;y>0;y--);}/******************************LCD忙检测*******************************/ bit lcd_busy(){bit result;lcdrw = 1;lcdrs = 0;lcden = 1;nop();nop();nop();nop();result = (bit)(P0&0x80);lcden = 0;return(result);}/****************************** LCD写命令子程序*******************************/ void write_com(uchar com){while(lcd_busy());//忙等待lcdrs = 0;lcdrw = 0;P1 = com;delay(5);lcden = 1;delay(5);lcden = 0;}/****************************** LCD写数据子程序*******************************/ void write_data(uchar date){while(lcd_busy()); //忙等待lcdrs = 1;lcdrw = 0;P1=date;delay(5);lcden = 1;delay(5);lcden = 0;}/******************************LCD初始化*******************************/ void lcd_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);}/****************************** 定时器初始化*******************************/ void time_init(){EA = 1;ET0 = 1;ET1 = 1;TR0 = 1;TR1 = 1;TMOD = 0x11;TH0 = N0/256;TL0 = N0%256;TH1 = 0X3C;TL1 = 0XB0;}/****************************** PID算法系数装载*******************************/ void Pid_init(){hightime= 0; //输出的占空比e1 = 0; //本次的温度差e2 = 0; //前一次的温度差e3 = 0; //两次前的温度差kp = 10; //需要根据试验确定参数ki = 5; //需要根据试验确定参数kd = 5; //需要根据试验确定参数}/******************************温度比较PID算法*******************************/void pid_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的输出结果需要除以10uk = 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; //设置饱和控制,else if(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 = 100;else if(uk<-100)uk = -100;e3 = e2;e2 = e1;}}}/******************************主函数*******************************/void main(){uint i;time_init();//定时器初始化Pid_init(); // PID初始化lcd_init();// LCD初始化table1[5]=0x43;table1[4]=0xdf;table1[2]=0x2e; //小数点摄氏度符号ASCII码for(i=0;i<15;i++) //带循环第一行显示"Real-time Temp:"{write_data(table[i]);delay(20);}while(1){t=data1*196/100;table1[3]=(t%100)%10+0x30;table1[1]=(t%100)/10+0x30;table1[0]=t/100+0x30; //以上温度数据转化rltemp = t; //给PID算法装载实际值write_com(0x80+0x45);//写LCD第二行的初地址for(i=0;i<5;i++) //该循环显示温度值{write_data(table1[i]);delay(20);}pid_ys();//运行温度比较PID算法}}/******************************温度采集转换的定时中断0.5s刷新一次数据*******************************/void timer0() interrupt 1{uint j;j++;if(j==20){OE = 0;START = 0;_nop_();START = 1;_nop_();START = 0;while(EOC==0);OE = 1;_nop_();data1 = P0;_nop_();OE = 0;j = 0;}TH0=N0/256;TL0=N0%256;}/****************************** PWM波输出的定时中断*******************************/ void timer1() interrupt 3{if(++count<=(hightime))pwm=0;else if(count<=100){pwm=1;}elsecount=0;TH1=0x3c;TL1=0xb0;}。

相关文档
最新文档