AUTHOR : Jiansiting

FAMILY : JZGK

NAME : CONT_C

VERSION : '2.0'

KNOW_HOW_PROTECT

VAR_INPUT

COM_RST : BOOL := FALSE; //完全重啟動

MAN_ON : BOOL := TRUE; //手動值打開

PVPER_ON : BOOL := FALSE; //外設過程變量打開

P_SEL : BOOL := TRUE; //比例作用打開

I_SEL : BOOL := TRUE; //積分作用打開

INT_HOLD : BOOL := FALSE; //積分作用保持

I_ITL_ON : BOOL := FALSE; //積分作用初始化

D_SEL : BOOL := FALSE; //微分作用打開

CYCLE : TIME := T#1S; //采樣時間

SP_INT : REAL := 0.0; //內部設定值

PV_IN : REAL := 0.0; //過程變量輸入

PV_PER : WORD := W#16#0; //外設過程變量

MAN : REAL := 0.0; //手動值

GAIN : REAL := 2.0; //比例增益

TI : TIME := T#20S; //積分復位時間

TD : TIME := T#10S; //微分時間

TM_LAG : TIME := T#2S; //微分作用時間延時

DEADB_W : REAL := 0.0; //死區帶寬

LMN_HLM : REAL := 100.0; //積分值上限

LMN_LLM : REAL := 0.0; //積分值下限

PV_FAC : REAL := 1.0; //過程變量因子

PV_OFF : REAL := 0.0; //過程變量偏移量

LMN_FAC : REAL := 1.0; //調節值因子

LMN_OFF : REAL := 0.0; //調節值偏移量

I_ITLVAL : REAL := 0.0; //積分作用的初始化值

DISV : REAL := 0.0; //幹擾變量

END_VAR

VAR_OUTPUT

LMN : REAL := 0.0; //調節值

LMN_PER : WORD := W#16#0; //外設調節值

QLMN_HLM : BOOL := FALSE; //達到調節值上限

QLMN_LLM : BOOL := FALSE; //達到調節值下限

LMN_P : REAL := 0.0; //比例分量

LMN_I : REAL := 0.0; //積分分量

LMN_D : REAL := 0.0; //微分分量

PV : REAL := 0.0; //

ER : REAL := 0.0; //誤差信號

END_VAR

VAR

sInvAlt : REAL := 0.0; //上周期比例偏差值

sIanteilAlt : REAL := 0.0; //上周期積分值

sRestInt : REAL := 0.0; //上周期積分偏差量(浮點數計算偏差)

sRestDif : REAL := 0.0; //上周期微分偏差量(浮點數計算偏差)

sRueck : REAL := 0.0; //

sLmn : REAL := 0.0; //上周期調節值

sbArwHLmOn : BOOL := FALSE; //上周期達到調節值上限

sbArwLLmOn : BOOL := FALSE; //上周期達到調節值下限

sbILimOn : BOOL := TRUE; //備用-本程序沒有使用該變量

END_VAR

VAR_TEMP

rCycle : REAL ; //采樣時間浮點值

Iant : REAL ; //積分增量

Diff : REAL ; //積分量

Istwert : REAL ; //過程變量浮點值

ErKp : REAL ; //偏差比例值

rTi : REAL ; //積分時間浮點值

rTd : REAL ; //微分時間浮點值

rTmLag : REAL ; //微分作用時間延時浮點值

Panteil : REAL ; //比例值

Ianteil : REAL ; //積分值

Danteil : REAL ; //微分值

Verstaerk : REAL ; //

RueckDiff : REAL ; //

RueckAlt : REAL ; //上周期積分量

dLmn : REAL ; //調節量

gf : REAL ; //Hilfwert

rVal : REAL ; //Real Hilfsvariable

END_VAR

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 ;

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 ;

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 = 32512.0 THEN

dLmn := 32512.0 ;

ELSIF dLmn

  • 上一篇:智能化戰場有何前瞻性設計?
  • 下一篇:怎麽用vb實現輸入(ip地址,本地端口號,和,遠
  • 相关文章
  • android app界面設計規範(dpi,dp,px等)
  • 請問日本亞馬遜有沒有安卓客戶端
  • 求大智慧高低點連線的指標公式,要求:
  • jsp怎麽上傳?求代碼!
  • 用C語言實現鏈表的算法
  • 有哪些關於太行山的傳說?
  • 計算機網絡軟件有哪些
  • copyright 2024編程學習大全網