Wenn 16#0d = 13.0 dezimal ist, wie soll dann 13.1 dargestellt werden...?
(...)
Hintergrund ist ein Modbus-Teilnehmer der Reals sendet und diese zum wegschicken halbiert weil ein Modbus-Register bekanntermaßen nur 16bit hat.
16#0d ist
NICHT 13.0 !
16#0000000D = L#13 = 13 dezimal als Ganzzahl
16#41500000 = REAL#13.0 = 13.0 als Gleitpunktzahl
UDINT_TO_REAL() macht die Umwandlung von 13 Ganzzahl zu 13.0 Gleitpunktzahl (16#0000000D --> 16#41500000)
Du brauchst aber vermutlich gar keine Konvertierung, sondern musst den REAL-Wert beim Modbus-Empfänger einfach nur wieder zusammensetzen.
Das Übertragungsprotokoll Modbus kennt keinen FLOAT/REAL Datentyp, sondern nur 16-Bit Register. Ein 32-Bit REAL-Wert liegt da üblicherweise in 2 aufeinanderfolgenden Registern und kann durch zusammenhängendes Lesen der 2 Register am Stück übertragen werden und beim Empfänger werden die 2x 16-Bit Register = 4 Byte zu 32-Bit zusammengefasst. Im einfachsten Fall bei Siemens nimmt man einfach die 4 aufeinanderfolgenden 8-Bit Bytes und packt sie in ein 32-Bit DWORD oder gleich direkt in eine REAL-Variable. (Je nach Endianness der Empfänger CPU muss dabei H-Word und L-Word getauscht werden.)
Du könntest dem Modbus-Lese-Baustein direkt die Adresse Deiner REAL-Variable übergeben (die 4 Bytes direkt als REAL deklarieren) und den Auftrag, die 2 Register des REAL-Wertes in diese Adresse zu lesen (ich weiß jetzt nicht, ob der Compiler das so zuläßt). Oder Du liest die 2 Register in einen 2-WORD-Empfangspuffer oder in einen 4-BYTE-Empfangspuffer und setzt daraus ein 32-Bit-DWORD zusammen (per AT oder einzeln zusammenbasteln). Zum Schluß muß das entstandene 32-Bit-Bitmuster
OHNE Konvertierung direkt in eine REAL-Variable kopiert werden: myRealVar := DWORD_TO_REAL(dwordWert);
Bei folgender Deklaration mit den AT-Sichten hast Du 4 Variablen mit verschiedenen Datentypen auf der selben Adresse liegen und kannst das 32-Bit-Bitmuster nach Belieben herauslesen und in die REAL-Variable kopieren (wenn die Endianness passt):
Code:
ByteBuffer : ARRAY [0..3] OF BYTE; //die 4 empfangenen Bytes
WordBuffer AT ByteBuffer : ARRAY [0..1] OF WORD; //die ursprünglichen 2 Modbus-Register
dwordVar AT ByteBuffer : DWORD; //das 32-Bit-Bitmuster
realVar AT ByteBuffer : REAL; //das 32-Bit-Bitmuster als REAL-Wert interpretiert
myRealVar : REAL;
Falls immer noch Unklarheit besteht, wie der Modbusteilnehmer den Gleitpunktwert codiert und verschickt, dann nenne uns mal um welches Gerät es sich handelt, am besten mit Link zum Handbuch.
Harald