在学习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