[備忘録]三菱FX5U用のプログラムカウンタ[AI生成]

雑記ブログ
この記事は約8分で読めます。

ちょっと プログラムカウンタを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
*)

コメント

タイトルとURLをコピーしました