在学习PID指令时,虽然有框图,但理解还是感觉比较吃力,花了许多功夫最终还是用不好PID指令。对某些有自整定参数功能的PID指令如何实现所谓“自整定参数”的功能也是一头雾水。反反复复地看了许多关于PID方面的文章,也琢磨了一些自己的理解,下面是用S7-300的“STL源文件”编写的一段程序,纯粹当作练习:
FUNCTION_BLOCK FB 1
TITLE =
//KNOW_HOW_PROTECT
VERSION : 0.1
VAR_INPUT
PV : REAL ;
END_VAR
VAR_OUTPUT
out : INT ;
END_VAR
VAR
I : INT ; //积分时间(0.1s)
Kp : REAL ; //比例
Kd : REAL ; //微分增益
PV0 : REAL ; //上次过程值
SP : REAL ; //设定点
MV : REAL ; //输出值
_1 : BOOL ;
_2 : BOOL ;
EV : REAL ; //静差
END_VAR
VAR_TEMP
temp0 : REAL ;
temp1 : REAL ;
temp2 : BOOL ;
temp3 : BOOL ;
END_VAR
BEGIN
NETWORK
TITLE =
//积分时间设定:每次运算的周期
A M 0.0; //0.1s脉冲
CD C 0;
A #_1; //设定时间值
L #I;
S C 0;
AN C 0;
FP #_2;
= #_1;
NETWORK
TITLE =
//PID运算:MV=MV+Kp{(SP-PV)-Kd(PV-PV0)}
//
A #_1;
JNB _001;
L #PV;
L #PV0;
-R ;
L #Kd;
*R ;
T #temp0;
L #SP;
L #PV;
-R ;
T #EV;
L #temp0;
-R ;
L #Kp;
*R ;
T #temp1;
L #MV;
+R ;
T #MV;
_001: NOP 0;
NETWORK
TITLE =
//设置上限为100%
//运算结果超出上限是无意义的,例如当结果为150%时,实际上执行的是100%,更重要的是从
//150%返回到100%会使反应缓慢。
A( ;
L #MV;
L 1.000000e+002;
>=R ;
) ;
JNB _002;
L 1.000000e+002;
T #MV;
_002: NOP 0;
NETWORK
TITLE =
A( ;
L #MV;
L 0.000000e+000;
<=R ;
) ;
JNB _003;
L 0.000000e+000;
T #MV;
_003: NOP 0;
NETWORK
TITLE =
//将工程量(如温度值)转换为数字量输出,供数/模转换(模拟量输出)
L #MV;
L 2.764800e+002;
*R ;
RND ;
T #out;
NETWORK
TITLE =
//将本次过程值写入“上次过程值”,以准备下次运算
// ------刷新
L #PV;
T #PV0;
END_FUNCTION_BLOCK