ちょっと プログラムカウンタをAIでつくってもらったらできてしまった件
下のFBが完成図

まじですか・・ちゃんとうごくやないですか。
さすがに変数部分は再定義が必要です

メインのST部分はそのままコピペで完成
(*----------------------------------------------------------------------------------------
FUNCTION_BLOCK FB_PC_Retain_Latched_ClearByType
VAR_INPUT
Enable : BOOL; // カウント命令(立ち上がりで1回カウント)
Reset : BOOL; // TRUE で Count := MinVal(フラグはクリアされない)
Load : BOOL; // TRUE で Count := Preset(フラグはクリアされない)
Preset : DINT := 0; // プリセット値
Up : BOOL := TRUE; // TRUE=UP, FALSE=DOWN
Step : DINT := 1; // 正のステップ値
MinVal : DINT := 0; // 下限
MaxVal : DINT := 100; // 上限
Rollover : BOOL := FALSE;// TRUE=循環, FALSE=飽和
CLR_OVF : BOOL := FALSE;// TRUE で Latched_OVF をクリア
CLR_UDF : BOOL := FALSE;// TRUE で Latched_UDF をクリア
RetainPrevEn : BOOL := FALSE;// TRUE なら PrevEnable を RETAIN で保持
END_VAR
VAR_OUTPUT
Count : DINT := 0; // 現在カウント値(出力)
Overflow : BOOL := FALSE;// 今サイクルで上方向越え発生(パルス)
Underflow : BOOL := FALSE;// 今サイクルで下方向越え発生(パルス)
Latched_OVF : BOOL := FALSE;// ラッチ済み上溢れ(個別クリア)
Latched_UDF : BOOL := FALSE;// ラッチ済み下溢れ(個別クリア)
Changed : BOOL := FALSE;// 今サイクルで Count が変化
END_VAR
VAR RETAIN
Ret_Count : DINT := 0; // 保持カウント値
Ret_PrevEn : BOOL := FALSE;// 保持する立ち上がり判定
Ret_Latched_OVF : BOOL := FALSE;// 保持ラッチOVF
Ret_Latched_UDF : BOOL := FALSE;// 保持ラッチUDF
END_VAR
VAR
PrevEnable_local : BOOL := FALSE; // 非保持版の立ち上がり検出用
END_VAR
------------------------------------------------------------------------------------------*)
(* 出力に保持値を反映 *)
Count := Ret_Count;
Latched_OVF := Ret_Latched_OVF;
Latched_UDF := Ret_Latched_UDF;
(* 個別クリア *)
IF CLR_OVF THEN
Ret_Latched_OVF := FALSE;
END_IF;
IF CLR_UDF THEN
Ret_Latched_UDF := FALSE;
END_IF;
(* Reset / Load 優先(フラグは個別クリアに従う) *)
IF Reset THEN
Ret_Count := MinVal;
Overflow := FALSE;
Underflow := FALSE;
Changed := TRUE;
ELSIF Load THEN
Ret_Count := Preset;
Overflow := FALSE;
Underflow := FALSE;
Changed := TRUE;
ELSE
Overflow := FALSE;
Underflow := FALSE;
Changed := FALSE;
(* 立ち上がり検出とカウント処理 *)
IF RetainPrevEn THEN
IF (Enable AND NOT Ret_PrevEn) THEN
IF Up THEN
IF (Ret_Count + Step_No) > MaxVal THEN
Overflow := TRUE;
Ret_Latched_OVF := TRUE;
IF Rollover THEN
Ret_Count := MinVal + ((Ret_Count + Step_No) - (MaxVal + 1));
ELSE
Ret_Count := MaxVal;
END_IF;
ELSE
Ret_Count := Ret_Count + Step_No;
END_IF;
Changed := TRUE;
ELSE
IF (Ret_Count - Step_No) < MinVal THEN
Underflow := TRUE;
Ret_Latched_UDF := TRUE;
IF Rollover THEN
Ret_Count := MaxVal - (MinVal - (Ret_Count - Step_No)) + 1;
ELSE
Ret_Count := MinVal;
END_IF;
ELSE
Ret_Count := Ret_Count - Step_No;
END_IF;
Changed := TRUE;
END_IF;
END_IF;
Ret_PrevEn := Enable;
ELSE
IF (Enable AND NOT PrevEnable_local) THEN
IF Up THEN
IF (Ret_Count + Step_No) > MaxVal THEN
Overflow := TRUE;
Ret_Latched_OVF := TRUE;
IF Rollover THEN
Ret_Count := MinVal + ((Ret_Count + Step_No) - (MaxVal + 1));
ELSE
Ret_Count := MaxVal;
END_IF;
ELSE
Ret_Count := Ret_Count + Step_No;
END_IF;
Changed := TRUE;
ELSE
IF (Ret_Count - Step_No) < MinVal THEN
Underflow := TRUE;
Ret_Latched_UDF := TRUE;
IF Rollover THEN
Ret_Count := MaxVal - (MinVal - (Ret_Count - Step_No)) + 1;
ELSE
Ret_Count := MinVal;
END_IF;
ELSE
Ret_Count := Ret_Count - Step_No;
END_IF;
Changed := TRUE;
END_IF;
END_IF;
PrevEnable_local := Enable;
END_IF;
END_IF;
(* 出力反映(明示代入) *)
Count := Ret_Count;
Overflow := Overflow;
Underflow := Underflow;
Latched_OVF := Ret_Latched_OVF;
Latched_UDF := Ret_Latched_UDF;
(*
END_FUNCTION_BLOCK
*)


コメント