Структура сгенерированного кода для диаграмм Stateflow

Примеры в этой теме показывают сгенерированный код для IDE CoDeSys Version 2.3 PLC. Сгенерированный код для других платформ IDE выглядит по-другому.

Диаграмма Stateflow с основанными на событии переходами

Сгенерируйте код для графика Stateflow® ControlModule в модели plcdemo_stateflow_controller. Вот график:

Можно сопоставить состояния и переходы в графике к сгенерированному коду. Например, переход от Aborting состояния к Aborted появляется в сгенерированном коде как:

ControlModule_IN_Aborting: 
                    rtb_out := sABORTING;
                    (* During 'Aborting': '<S1>:11' *)
                    (* Graphical Function 'is_active': '<S1>:73' *)
                    (* Transition: '<S1>:75' *)
                    IF  NOT drive_state.Active THEN 
                        (* Transition: '<S1>:31' *)
                        is_c2_ControlModule := ControlModule_IN_Aborted;
                        (* Entry 'Aborted': '<S1>:12' *)
                        rtb_out := sABORTED;
                        (* Graphical Function 'stop_drive': '<S1>:88' *)
                        (* Transition: '<S1>:90' *)
                        driveOut.Start := FALSE;
                        driveOut.Stop := TRUE;
                        driveOut.Reset := FALSE;
                    END_IF;

Для получения дополнительной информации о встраивании функций, таких как start_drive, stop_drive, и reset_drive в сгенерированном коде смотрите Разделы Кода системы управления для функций MATLAB в диаграммах Stateflow.

Диаграмма Stateflow с абсолютным временем временная логика

Сгенерируйте код для диаграммы Stateflow Temporal в модели plcdemo_sf_abs_time. Вот график:

Можно сопоставить состояния и переходы в графике к сгенерированному коду. Например, переход от B состояния toc появляется как:

 Temporal_IN_B: 
                    (* During 'B': '<S1>:2' *)
                    temporalCounter_i1(timerAction := 2, maxTime := 4000);
                    IF temporalCounter_i1.done THEN 
                        (* Transition: '<S1>:8' *)
                        is_c2_Temporal := Temporal_IN_C;
                        temporalCounter_i1(timerAction := 1, maxTime := 0);
                    ELSE 
                        (* Outport: '<Root>/pulse' *)
                        pulse := 2.0;
                    END_IF;

Переменная temporalCounter_i1 экземпляр функционального блока PLC_CODER_TIMER заданный как:

FUNCTION_BLOCK PLC_CODER_TIMER
VAR_INPUT
    timerAction: INT;
    maxTime: DINT;
END_VAR
VAR_OUTPUT
    done: BOOL;
END_VAR
VAR
    plcTimer: TON;
    plcTimerExpired: BOOL;
END_VAR
CASE timerAction OF
    1:
        (* RESET *)
        plcTimer(IN:=FALSE, PT:=T#0ms);
        plcTimerExpired := FALSE;
        done := FALSE;
    2:
        (* AFTER *)
        IF (NOT(plcTimerExpired)) THEN
            plcTimer(IN:=TRUE, PT:=DINT_TO_TIME(maxTime));
        END_IF;
        plcTimerExpired := plcTimer.Q;
        done := plcTimerExpired;
    3:
        (* BEFORE *)
        IF (NOT(plcTimerExpired)) THEN
            plcTimer(IN:=TRUE, PT:=DINT_TO_TIME(maxTime));
        END_IF;
        plcTimerExpired := plcTimer.Q;
        done := NOT(plcTimerExpired);
END_CASE;
END_FUNCTION_BLOCK