IEEE-754 Konvertierung

Zuviel Werbung?
-> Hier kostenlos registrieren
Ich könnte aber REAL zuweisen und vielleicht noch ein einzens Array von Char[4]. Das ergibt keinen Sinn mehr.
Wenn man aber erst noch die "Indianer" in Reih und Glied aufstellen muss, bevor man die 32 Bit als REAL interpretieren kann, wäre zumindest ein array of byte[4] nicht ganz so absurd?
 
Vielen Dank für die Ausführung mit dem Zeiger und dem Workaround mit der Union. Ich werde das probieren. Kann sein, daß ich da nochmal auf euch zukommen muß, ich bin an der Stelle nicht sattelfest.

Also dürfen wir nun davon ausgehen, daß Du eine Lösung für die B&R-Steuerung suchst, und diese mit Codesys oder etwas ähnlichem programmiert wird? (ich kenne B&R nicht)

Die IDE heißt Automation Studio, basierend auf Microsoft's Visual Studio. Was für ein Compiler für ST verwendet wird weiß ich nicht; für C ist es allem Anschein nach der gcc. Für ST könnnte es ein angepasster gcc sein. Das OS in der CPU ist Linux basierend, die SPS wohl nur aufgesetzt. Siemens hat - ich spekuliere mal: aus Kopierschutzgründen - ihre eigenen FPGAs ("bare metal"), wodurch das booten mit einer kleinen Bootsequenz auf einer S7-1200 mindestens 10x schneller geht als auf einer B&R X20CPU. Dreh- und Angelpunkt von B&R ist "mapp", eine Art Framework (mappview, mapp services, mapp Dingsbums), vielgepriesen aber von unseren Ingenieuren so sehr verflucht, daß sie, basierend auf Windows' WPF was eigenes bauen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das widerspricht aber einer Union.
Ich glaube das ist ein allgemeiner Text. Und in ST wird das ähnlich funktionieren.

Es macht nur Sinn einer Union einer Variable zuzuweisen und die anderen Variablen auszulesen. Ich könnte aber REAL zuweisen und vielleicht noch ein einzens Array von Char[4]. Das ergibt keinen Sinn mehr.

Union Einmal Schreiben und den gewüschnten Datentyp lesen.
Ist besser als über Pointer auf unbekannte Datentypen zuzugreifen.

Die ursprüngliche Idee einer union in C war aber vermutlich nicht verschiedene Typen zu wandeln, sondern auf einer Adresse verschiedene Typen speichern zu können um eben Speicherplatz zu sparen, beispielsweise wie beim Windows COM Variant. Es heißt ja auch nicht, dass es nicht funktioniert oder nicht erlaubt ist, sondern dass der Code nicht ohne weitere Prüfung mit jedem anderen Compiler übersetzt genau das gleiche macht.
 
Die ursprüngliche Idee einer union in C war aber vermutlich nicht verschiedene Typen zu wandeln, sondern auf einer Adresse verschiedene Typen speichern zu können um eben Speicherplatz zu sparen, ...
Was nun die ursprüngliche Idee dahinter war, eine Möglichkeit für die Doppel(oder allgemeiner Mehrfach)Belegung eines SpeicherBereichs anzubieten, sollte eigentlich ziemlich schnuppe sein.
Dass sie aber funktionieren sollte, ohne ein Compiler-individuelles Eigenleben zu entwickeln, halte ich persönlich für unverhandelbar. Entweder DoppelBelegung oder keine DoppelBelegung - ZwischenStadien kann es doch eigentlich nicht geben und wüsste ich auch nicht zu rechtfertigen!?

Ich finde es immer wieder erschreckend, wenn ProgrammierSprachen bzw. Dialekte ersonnen werden, die weder reine TypeCastings (ohne jegliche Konvertierung) noch Möglichkeiten der DoppelBelegung (Union, AT, ReDefine, oder wie auch immer sie jeweils heissen mögen) anbieten. Die Erfahrung, dass ein elementares Bedürfnis nach solchen Möglichkeiten besteht und nicht wegzudiskutieren ist, gibt es doch schon so was von lange.
Die Angst vor einem "KontrollVerlust" des Compilers scheint sich aber immer wieder durchzusetzen, sehr zum Leidwesen der Programmierer und der Portabilität von Software.
 
Es ist ja nicht so, dass es in C nicht ca. 143 andere Möglichkeiten gibt das umzusetzen, ohne eine Variante mit undefiniertem oder unspezifiziertem Verhalten zu verwenden, welche dann eben auch unter jeder Umgebung funktioniert. Die Liste mit Ausnahmen und undefiniertem Verhalten ist bei C nunmal sehr lang, kann man sich dran orientieren wenn man portablen und zuverlässigen Code schreiben will, oder eben auch nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es ist ja nicht so, dass es in C nicht ca. 143 andere Möglichkeiten gibt das umzusetzen, ...
Mag sein, dass C genügend andere Möglichkeiten bietet und so sollte es bei C auch sein, zumal diese Sprache auch (Pozessor-nah) für BetriebsSysteme etc. verwendet wird und nicht nur für AnwenderProgramme unbedarfter HobbyProgrammierer.

Mich stört aber, wenn Sprachen für die SPS-Programmierung keinerlei Rücksicht auf Belange nehmen, die zum AlltagsGeschäft der SPS-Programmierung gehören.
TypeCasting hatte ich schon genannt und ferner gehört dazu insbesondere auch das Ansprechen einzelner Bits in BYTEs, WORDs etc..
Die ewigen Rückfragen in den hiesigen Threads nach genauer CPU-Bestellnummer, FW-Stand u.s.w. offenbaren es doch, wie sehr immer wieder geschludert und nach und nach aufgebohrt und nachgebessert wird bzw. werden muss. Dabei geht es doch nicht nur um spezielle features und Innovationen (dafür hätte ich Verständnis), sondern leider geht es auch um Grundlagen ('Basics'), an denen man nicht ständig herumexperimentieren und variieren müsste.
 
Problem gelöst. Für den nächsten der mit Automation Studio darüber stolpert:

Code:
VAR
    REAL_ACVolt : {REDUND_UNREPLICABLE} REAL;
    REAL_ACVolt2 : REFERENCE TO REAL;
    DWORD_ACVolt : DWORD;
 
END_VAR



PROGRAM _CYCLIC
    (* Insert code here *)

    
    DWORD_ACVolt := 16#4364b333;        // DWORD nach IEEE-754, U=228,7V in 2x16bit Modbus Registern des Stromzählers 
    REAL_ACVolt := DWORD_TO_REAL(DWORD_ACVolt); // führt zu falschem Ergebnis: 1.1306729E+09V
    REAL_ACVolt2 ACCESS ADR(DWORD_ACVolt);     //korrektes Ergebnis: 228,7V - deklariert als & Referenz

    
END_PROGRAM
 
Was lernen wir jetzt daraus?

1. DWORD_TO_REAL ist tatsächlich kein TypeCast, sondern eine TypeConversion DINT_TO_REAL oder UDINT_TO_REAL (welches von beiden, kann man an dem gezeigten Beispiel leider nicht sehen).

2. Um die Frage BigEndian oder LittleEndian muss man sich in diesem Fall ("Modbus-Format") keine Gedanken machen.

Etwas merkwürdig finde ich die Schreibweise 'REAL_ACVolt2 ACCESS ADR(DWORD_ACVolt);'. Da würde ich doch glatt überlesen, dass hier eine WertZuweisung (?) vorliegt :confused: .
 
Zurück
Oben