IEC 61131-3: UNION erweitern per Vererbung

In dem Post IEC 61131-3: Weitere Spracherweiterungen bin ich kurz auf die UNION eingegangen. Ein Leserkommentar hat mich auf die Möglichkeit hingewiesen, dass auch eine UNION per EXTENDS erweitert werden kann. Da dieses die Handhabung einer UNION vereinfacht und die Norm auch nicht darauf hinweist, will ich diese Möglichkeit in einem (sehr) kurzen Post vorstellen.

Wie schon zuvor in einem Post beschrieben, ist es mit einer UNION möglich, eigene Datentypen zu definieren, deren Elemente alle denselben Speicherplatz belegen. Hier nochmal das Beispiel, bei dem auf eine 16-Bit Variable auch jeweils einzeln auf das Low-Byte und auf das High-Byte zugegriffen werden kann.

TYPE U_Test :
UNION
  nVar1  : WORD;
  stVar2 : ST_Bytes;
END_UNION
END_TYPE
TYPE ST_Bytes :
STRUCT
  nLSB  : BYTE;
  nMSB  : BYTE;
END_STRUCT
END_TYPE

Dieses Beispiel zeigt, wie ohne Bit-Operationen aus einer Variablen vom Typ WORD das niedrigere Byte (LSB) und das höherwertige Byte (MSB) ermittelt werden.

PROGRAM MAIN
VAR
  uVar     : U_Test;
  nA, nB   : BYTE;
END_VAR

uVar.nVar1 := 16#1234;
nA := uVar.stVar2.nLSB;  // Wert: 16#34 (LSB)
nB := uVar.stVar2.nMSB;  // Wert: 16#12 (MSB)

EXTENDS bei UNION

Etwas eleganter kann die gleiche Aufgabe auch mit Vererbung gelöst werden. Hierbei erbt der Verbund U_Test von ST_Bytes.

TYPE U_Test EXTENDS ST_Bytes :
UNION
	nVar1   : WORD;
	// stVar2  : ST_Bytes;	// kann entfallen, wird von ST_Bytes geerbt.
END_UNION
END_TYPE

Der Zugriff auf nLSB und nMSB muss jetzt nicht mehr über eine explizit deklarierte Variable in der UNION erfolgen.

uVar.nVar1 := 16#1234;
nA := uVar.nLSB;    // Wert: 16#34 (LSB)
nB := uVar.nMSB;    // Wert: 16#12 (MSB)

Author: Stefan Henneken

I’m Stefan Henneken, a software developer based in Germany. This blog is just a collection of various articles I want to share, mostly related to Software Development.

5 thoughts on “IEC 61131-3: UNION erweitern per Vererbung”

  1. Hallo

    Ich glaube die Beispiele sind durcheinander geraten, müsste der Code nicht wie folgt sein?
    Beim ersten Besipeil ist nvar2 vom Typ ST_BYTES, und dann nachher ist der code so?
    nA := uVar.nvar2.nLSB; // Wert: 16#34 (LSB)
    nB := uVar.nvar2.nMSB; // Wert: 16#12 (MSB)

      1. Gerne.

        Danke für die ganzen Beispiele, sinvolle und saubere Beispiele über IEC 61131-3 sind im Inet so gut wie nicht vorhanden.

  2. Hallo
    Eine interessante Möglichkeit, die ich mittlerweile auch nutze. Dabei bin ich nun allerdings auf einen Stolperstein gestossen:
    Der Compiler zieht zur Grössenbestimmung einer Union nur die in ihr definierten Elemente heran, jedoch nicht die Grösse des Datentyps, von dem sie abgeleitet wird. Ist dieser Datentyp größer als das größte Element der Union, kann man also über das Ende der Union hinausschreiben und jede Menge Unheil anrichten.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: