各位大侠,大家好:
今天查PID资料,发现PID竟然分位置式PID和增量式PID。请问咱S7-300的FB41 是位置式PID还是增量式PID,在哪里能够看出来,谢谢。
如下是在网上下载的FB41的SCL程序,请大家指点,谢谢。
IF #COM_RST THEN //PID初始化
#sIanteilAlt := #I_ITLVAL ;
#LMN := 0.0 ;
#QLMN_HLM := FALSE ;
#QLMN_LLM := FALSE ;
#LMN_P := 0.0 ;
#LMN_I := 0.0 ;
#LMN_D := 0.0 ;
#LMN_PER := W#16#0 ;
#PV := 0.0 ;
#ER := 0.0 ;
#sInvAlt := 0.0 ;
#sRestInt := 0.0 ;
#sRestDif := 0.0 ;
#sRueck := 0.0 ;
#sLmn := 0.0 ;
#sbArwHLmOn := FALSE ;
#sbArwLLmOn := FALSE ;
#ER := 0.0;
#LMN_D := 0.0;
ELSE
#rCycle := DINT_TO_REAL( TIME_TO_DINT( #CYCLE ) ) / 1000.0 ; //采样时间转换为浮点数值
#Istwert := DINT_TO_REAL( INT_TO_DINT( WORD_TO_INT ( #PV_PER ) ) ) * 0.003616898 ;
#Istwert := #Istwert * #PV_FAC + #PV_OFF ; //外设输入转换为浮点数值
IF NOT #PVPER_ON THEN //过程变量选择
#Istwert := #PV_IN ;
END_IF;
#PV := #Istwert ;
#ErKp := #SP_INT - #PV ; //计算偏差
IF #ErKp < -#DEADB_W THEN
#ER := #ErKp + #DEADB_W ;
ELSIF #ErKp > #DEADB_W THEN
#ER := #ErKp - #DEADB_W ;
ELSE
#ER := 0.0 ;
END_IF;
#ErKp := #ER * #GAIN ; //偏差比例增益
#rTi := DINT_TO_REAL( TIME_TO_DINT( #TI ) ) / 1000.0 ;
#rTd := DINT_TO_REAL( TIME_TO_DINT( #TD ) ) / 1000.0 ;
#rTmLag := DINT_TO_REAL( TIME_TO_DINT( #TM_LAG ) ) / 1000.0 ;
IF #rTi < #rCycle * 0.5 THEN //积分时间必须 >= 采样时间的0.5倍
#rTi := #rCycle * 0.5 ;
END_IF;
IF #rTd < #rCycle THEN //微分时间必须 >= 采样时间
#rTd := #rCycle ;
END_IF;
IF #rTmLag < #rCycle * 0.5 THEN //微分作用延时时间必须 >= 采样时间的0.5倍
#rTmLag := #rCycle * 0.5 ;
END_IF;
IF #P_SEL THEN //比例作用投入
#Panteil := #ErKp ;
ELSE
#Panteil := 0.0 ;
END_IF;
IF #I_SEL THEN //积分作用投入
IF #I_ITL_ON THEN //积分初始化
#Ianteil := #I_ITLVAL ;
#sRestInt := 0.0 ;
ELSIF #MAN_ON THEN //手动值输入时的积分量计算,用于用于手动切换自动无扰切换
#Ianteil := #sLmn - #Panteil - #DISV ;
#sRestInt := 0.0 ;
ELSE //积分计算
#Iant := ( #rCycle / #rTi ) * ( #ErKp + #sInvAlt ) * 0.5 + #sRestInt ;
IF ( ( #Iant > 0.0 AND #sbArwHLmOn ) OR #INT_HOLD ) OR ( #Iant < 0.0 AND #sbArwLLmOn )THEN //抗积分饱和
#Iant := 0.0 ;
END_IF;
#Ianteil := #sIanteilAlt + #Iant ; //当前积分值 := 上时刻积分值 + 本次积分量
#sRestInt := #sIanteilAlt - #Ianteil + #Iant ; //感觉 sRestInt一直等于0.0 ;?????不知为何,通过运行发现不为0.0,可能是浮点数计算误差
END_IF;
ELSE
#Ianteil := 0.0 ;
#sRestInt := 0.0 ;
END_IF;
#Diff := #ErKp ;
IF NOT #MAN_ON AND #D_SEL THEN //微分作用投入
#Verstaerk := #rTd / ( #rCycle * 0.5 + #rTmLag ) ;
#Danteil := ( #Diff - #sRueck ) * #Verstaerk ;
#RueckAlt := #sRueck ;
#RueckDiff := #rCycle / #rTd * #Danteil + #sRestDif ;
#sRueck := #RueckDiff + #RueckAlt ;
#sRestDif := #RueckAlt - #sRueck + #RueckDiff ; //同积分一样计算微分误差量
ELSE //
#Danteil := 0.0 ;
#sRestDif := 0.0 ;
#sRueck := #Diff ;
END_IF;
#dLmn := #Panteil + #Ianteil + #Danteil + #DISV ; //PID输出
IF #MAN_ON THEN //PID手动之打开
#dLmn := #MAN ;
ELSE
IF NOT #I_ITL_ON AND #I_SEL THEN //干扰量处理
IF #Ianteil > #LMN_HLM - #DISV AND #dLmn > #LMN_HLM AND #dLmn - #LMN_D > #LMN_HLM THEN
#rVal := #LMN_HLM - #DISV ;
#gf := #dLmn - #LMN_HLM ;
#rVal := #Ianteil - #rVal ;
IF #rVal > #gf THEN
#rVal := #gf ;
END_IF;
#Ianteil := #Ianteil - #rVal ;
ELSIF #Ianteil < #LMN_LLM - #DISV AND #dLmn < #LMN_LLM AND #dLmn - #LMN_D < #LMN_LLM THEN
#rVal := #LMN_LLM - #DISV ;
#gf := #dLmn - #LMN_LLM ;
#rVal := #Ianteil - #rVal ;
IF #rVal < #gf THEN
#rVal := #gf ;
END_IF;
#Ianteil := #Ianteil - #rVal ;
END_IF;
END_IF;
END_IF;
#LMN_P := #Panteil ;
#LMN_I := #Ianteil ;
#LMN_D := #Danteil ;
#sInvAlt := #ErKp ;
#sIanteilAlt := #Ianteil ;
#sbArwHLmOn := FALSE ;
#sbArwLLmOn := FALSE ;
IF #dLmn >= #LMN_HLM THEN //调节辆限幅(上限)
#QLMN_HLM := TRUE ;
#QLMN_LLM := FALSE ;
#dLmn := #LMN_HLM ;
#sbArwHLmOn := TRUE ;
ELSE
#QLMN_HLM := FALSE ;
IF #dLmn <= #LMN_LLM THEN //调节辆限幅(下限)
#QLMN_LLM := TRUE ;
#dLmn := #LMN_LLM ;
#sbArwLLmOn := TRUE ;
ELSE
#QLMN_LLM := FALSE ;
END_IF;
END_IF;
#sLmn := #dLmn ;
#dLmn := #dLmn * #LMN_FAC + #LMN_OFF ;
#LMN := #dLmn ;
#dLmn := #dLmn* 276.48 ;
IF #dLmn >= 32512.0 THEN
#dLmn := 32512.0 ;
ELSIF #dLmn <= -32512.0 THEN
#dLmn := -32512.0 ;
END_IF;
#LMN_PER := INT_TO_WORD( DINT_TO_INT( REAL_TO_DINT( #dLmn) ) ) ;
END_IF;