Main Content

Generated Code Structure for Multirate Models

This example assumes that you have generated Structured Text code from a Simulink® model. If you have not yet done so, see Generate Structured Text from the Model Window.

The example in this topic shows generated code for the CODESYS Version 2.3 IDE. Generated code for other IDE platforms looks different.

  1. Open the plcdemo_multirate model. This model has two sample rates. To open the model, enter:

    openExample('plcdemo_multirate');

  2. Open the PLC Coder app. Click the PLC Code tab.

  3. Click Generate PLC Code.

    The Simulink PLC Coder™ software generates Structured Text code and places it in current_folder/plcsrc/plcdemo_multirate.exp.

  4. If you do not have the plcdemo_multirate.exp file open, open it in the MATLAB® editor and examine the Structured Text code.

    The generated code contains a global time step counter variable:

    VAR_GLOBAL
        plc_ts_counter1: DINT;
    END_VAR

    In this example, there are two rates, and the fast rate is twice as fast as the slow rate, so the time step counter counts to 1, then resets:

    IF plc_ts_counter1 >= 1 THEN 
          plc_ts_counter1 := 0;
    ELSE 
          plc_ts_counter1 := plc_ts_counter1 + 1;
    END_IF;

    The generated code for blocks running at slower rates executes conditionally based on the corresponding time step counter values. In this example, the generated code for Gain1, Unit Delay1, and Sum1 executes every other time step, when plc_ts_counter1 = 0, because those blocks run at the slow rate. The generated code for Gain, Unit Delay, Sum, and Sum2 executes every time step because those blocks run at the fast rate.

    SS_STEP: 
            
            (* Gain: '<S1>/Gain' incorporates:
             *  Inport: '<Root>/U1'
             *  Sum: '<S1>/Sum'
             *  UnitDelay: '<S1>/Unit Delay' *)
            rtb_Gain := (U1 - UnitDelay_DSTATE) * 0.5;
            
            (* Outport: '<Root>/Y1' *)
            Y1 := rtb_Gain;
            IF plc_ts_counter1 = 0 THEN 
                
                (* UnitDelay: '<S1>/Unit Delay1' *)
                UnitDelay1 := UnitDelay1_DSTATE;
                
                (* Gain: '<S1>/Gain1' incorporates:
                 *  Inport: '<Root>/U2'
                 *  Sum: '<S1>/Sum1' *)
                rtb_Gain1 := (U2 - UnitDelay1) * 0.5;
                
                (* Outport: '<Root>/Y2' *)
                Y2 := rtb_Gain1;
            END_IF;
            
            (* Outport: '<Root>/Y3' incorporates:
             *  Sum: '<S1>/Sum2'
             *  UnitDelay: '<S1>/Unit Delay' *)
            Y3 := UnitDelay_DSTATE - UnitDelay1;
            
            (* Update for UnitDelay: '<S1>/Unit Delay' *)
            UnitDelay_DSTATE := rtb_Gain;
            
            IF plc_ts_counter1 = 0 THEN 
                
                (* Update for UnitDelay: '<S1>/Unit Delay1' *)
                UnitDelay1_DSTATE := rtb_Gain1;
                
            END_IF;

In general, for a subsystem with n different sample times, the generated code has n-1 time step counter variables, corresponding to the n-1 slower rates. Code generated from parts of the model running at the slower rates executes conditionally, based on the corresponding time step counter values.