quote:以下是引用木鸡在2005-07-22 15:27:41的发言:
上面的程序如果用局部变量做成库文件就完美了,我做了一个大体和你的差不多不过我用的是局部变量编的用起来很舒服
SUBROUTINE_BLOCK STRAIN:SBR1
TITLE=
VAR_INPUT
Sv:INT; //设定值
Pv:INT; //采样值
Kc:INT; //比例系数
Ki:INT; //积分系数(注意不是积分时间)
END_VAR
VAR_IN_OUT
PvLast:INT; //上一次采样值
OutLast:DINT; //上一次输出值
END_VAR
VAR_OUTPUT
Out:INT; //输出值
END_VAR
BEGIN
Network 1
// Pv(k-1)-Pv(k)
LD SM0.0
MOVW #PvLast, LW32
-I #Pv, LW32
Network 2
// 输入滤波
LDW> LW32, 1000 //若两次采样值之差的绝对值大于1000则表示是扰动。
OW< LW32, -1000
CRET
Network 3
// U(k)=U(k-1) + △U , △U= Kc(Sv-Pv)+ Ki[Pv(k-1)-Pv(k)]
LD SM0.0
MOVW #Pv, #PvLast //把当前采样值存为上一次采样值,为下一次准备
MOVW #Sv, LW36
-I #Pv, LW36 //得到偏差值
MUL #Kc, LD34 //Kc(Sv-Pv)
MUL #Ki, LD30 //Ki[Pv(k-1)-Pv(k)]
+D LD34, LD30 //△U= Kc(Sv-Pv)+ Ki[Pv(k-1)-Pv(k)]
/D 1000,LD30 //注意触摸屏内Kc和Ki带三位小数,所以要除以1000
+D LD30, #OutLast //U(k)=U(k-1) + △U
Network 4
// 上限限幅
LDD> #OutLast, 32760
MOVD 32760, #OutLast
Network 5
// 下限限幅
LDD< #OutLast, 0
MOVD 0, #OutLast
Network 6
// 输出
LD SM0.0
DTI #OutLast, #Out
END_SUBROUTINE_BLOCK