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)
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)
Hallo Alexander,
vielen Dank für deinen Hinweis. Das Beispiel war tatsächlich nicht korrekt und wurde jetzt von mir angepasst.
Jetzt sollte alles wieder passen.
Stefan
Gerne.
Danke für die ganzen Beispiele, sinvolle und saubere Beispiele über IEC 61131-3 sind im Inet so gut wie nicht vorhanden.
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.
Hallo Rainer,
vielen Dank für den Hinweis. Das ist wirklich ein wichtiger Punkt den man beachten sollte, da sonst andere Speicherbereiche überschrieben werden.
Stefan