Mapping of PLC and IEC process data

The TwinCAT PLC process data are cyclically mapped (copied) into the IEC process data (application objects) and vice versa at program runtime. Up to four process data areas (IO inputs, IO outputs, flag range, data area) can be declared in the PLC program as buffer variables for the mapping of the IEC<->PLC process data. The byte size of the buffers is freely selectable and may be different for each area. Unused ranges need not necessarily be declared.

In our introductory example we declare 4 PLC process data areas with 3000 bytes each:

PROGRAM MAIN
VAR
    AODB : ARRAY[0..49] OF ST_IEC870_5_101AODBEntry;

    init : BOOL := TRUE;
    initError : UDINT;

     inputs AT%IB0 : ARRAY[0..2999] OF BYTE;
    outputs AT%QB0 : ARRAY[0..2999] OF BYTE;
    memory AT%MB0 : ARRAY[0..2999] OF BYTE;
    data : ARRAY[0..2999] OF BYTE;

END_VAR

How the process data are to be mapped at runtime is specified during configuration of the application objects via the F_iecInitAOEntry function.
See also in: Definition and configuration of application objects.

The buffer variables were now declared as byte arrays. In order to improve access to the required data we define the individual variables a second time and allocate them to the corresponding byte/bit offset addresses. In case of a change in the byte array, the corresponding individual variable will be changed and inverted at the same time. However, this is not absolutely necessary. The bytes/bits of the byte array buffer variables can be accessed directly.

VAR_GLOBAL(* Memory offset 0..99 unused *)
  (* Single points *)
 msgSingle_0     AT%MX100.0 : BOOL;
    msgSingle_1     AT%MX100.1 : BOOL;
    msgSingle_2     AT%MX100.2 : BOOL;

  (* Double points *)
    (*      Bit 0..1 = first double point,
        Bit 2..3 = second double point, 
        Bit 4..5 = third double point, 
        Bit 6..7 = fourth double point *)
    msgDouble_0     AT%MB200    : BYTE;

  (* Regulating step values *)
    msgStep_0           AT%MB300    : BYTE;
    msgStep_1           AT%MB301    : BYTE;
    msgStep_2           AT%MB302    : BYTE;

  (* 32 bit strings *)
 msgBitStr_0     AT%MD400    : DWORD := 2#10001000_10001000_10001000_10001000;
    msgBitStr_1     AT%MD404    : DWORD := 2#10001000_10001000_10001000_10001000;
    msgBitStr_2     AT%MD408    : DWORD := 2#10001000_10001000_10001000_10001000;

  (* Measured values, normalized values *)
 msgNormalized_0     AT%MW500    : WORD;
    msgNormalized_1     AT%MW502    : WORD;
    msgNormalized_2     AT%MW504    : WORD;

  (* Measured values, scaled values *)
 msgScaled_0     AT%MW600    : INT;
    msgScaled_1     AT%MW602    : INT;
    msgScaled_2     AT%MW604    : INT;

  (* Measured values, short floating point values *)
 msgFloating_0   AT%MD700    : REAL;
    msgFloating_1   AT%MD704    : REAL;
    msgFloating_2   AT%MD708    : REAL;

  (* Integrated totals *)
 msgTotal_0      AT%MD800    : UDINT;
    msgTotal_1      AT%MD804    : UDINT;
    msgTotal_2      AT%MD808    : UDINT;

  (*#################################################################*)
    (* Single commands *)
 cmdSingle_0     AT%MX2100.0 : BOOL;
    cmdSingle_1     AT%MX2100.1 : BOOL;
    cmdSingle_2     AT%MX2100.2 : BOOL;

  (* Double commands *)
    (*      Bit 0..1 = first double command,
        Bit 2..3 = second double command, 
        Bit 4..5 = third double command, 
        Bit 6..7 = fourth double command *)
 cmdDouble_0     AT%MB2200       : BYTE;

  (* Regulating step commands *)
 cmdStep_0           AT%MB2300 : BYTE;
    cmdStep_1           AT%MB2301 : BYTE;
    cmdStep_2           AT%MB2302 : BYTE;

  (* 32 bit string commands *)
 cmdBitStr_0     AT%MD2400       : DWORD;
    cmdBitStr_1     AT%MD2404       : DWORD;
    cmdBitStr_2     AT%MD2408       : DWORD;

  (* Set point, normalized values *)
 cmdNormalized_0     AT%MW2500       : WORD;
    cmdNormalized_1     AT%MW2502       : WORD;
    cmdNormalized_2     AT%MW2504       : WORD;

  (* Set point, scaled values *)
 cmdScaled_0     AT%MW2600       : INT;
    cmdScaled_1     AT%MW2602       : INT;
    cmdScaled_2     AT%MW2604       : INT;

  (* Set point, short floating point values *)
 cmdFloating_0   AT%MD2700       : REAL;
    cmdFloating_1   AT%MD2704       : REAL;
    cmdFloating_2   AT%MD2708       : REAL;
END_VAR

Mapping of the IEC<->PLC process data in the substation

Process data in monitoring direction (slave->master information)

Example 1

Single point information (M_SP_NA_1) with the IOA = 100, PLC memory area, byte offset = 100, bit offset = 0.

msgSingle_0 == memory[100].0  -> Controlled station FB -> ... -> Controlling station

Example 2

Measured value, short floating point value (M_ME_NC_1) with the IOA = 700, PLC memory area, byte offset = 700, bit offset = 0 (irrelevant).

msgFloating_0 == memory[700..703] -> Controlled station FB -> ... -> Controlling station

Process data in control direction (master->slave commands)

Example 1

Single command state (C_SC_NA_1) with the  IOA = 10, PLC memory area, byte offset = 2100, bit offset = 0.

Controlling station -> ... -> Controlled station FB -> memory[2100].0 == cmdSingle_0

Example 2

Set point, short floating point value (C_SE_NC_1) with the IOA = 70, PLC memory area, byte offset = 2700, bit offset = 0 (irrelevant).

Controlling station -> ... -> Controlled station FB -> memory[2700..2703] == cmdFloating_0