Hallo, ich versuche einen Floatwert aus einem EEPROM auszulesen, der mit einem PIC18F Mikrocontroller abgelegt wurde. Der Floatwert ist -97,812808, auf dem EEPROM sind die Bytes 0x85, 0xC3, 0xA0, 0x29 gespeichert. Auslesen will ich mit einem AVR System. Anscheinend sind die Bytes vertauscht (big endian/little endian), ich erhalte aber laut IEEE754 Definition von float für den o.g. Wert 0xC2 0xC3 0xA0 0x28. Kann es sein, dass ich nicht nur die Reihenfolge der Bytes beim Umwandeln von Bytes zu float vertauschen muss, sondern auch ein bit für das Vorzeichen von links nach rechts tauschen muss? Gruß, Ralf
Hier noch ein Nachtrag: Das ist der Code, der auf dem PIC18 Controller den Wert 97,812808 ausgibt aber auf einem ATmega328 nur null ergibt (auch mit Vertauschen der Byte Reihenfolge). typedef union { float value; unsigned char byte_val[4]; unsigned int int_val[2]; } float_byte_int; void read_float() { float CPCoeff; float_byte_int tmp; tmp.byte_val[0]=0x85; tmp.byte_val[1]=0xC3; tmp.byte_val[2]=0xA0; tmp.byte_val[3]=0x29; CPCoeff = tmp.value; }
Ralf H. schrieb: > Kann es sein, dass ich nicht nur die Reihenfolge der Bytes beim Umwandeln > von Bytes zu float vertauschen muss, sondern auch ein bit für das > Vorzeichen von links nach rechts tauschen muss? Also ich als Arduino-Programmierer weiß, dass der GCC-Compiler IEEE Gleitkommazahlen vom "single" Datentyp verwendet. IEEE-Gleitkommazahlen werden wohl in der Digitaltechnik fast überall verwendet, wo mit Gleitkommazahlen gearbeitet wird. Aber nicht bei Microchip und Deinem Compiler für den Pic-Controller. Ich habe mal gegoogelt wo der Unterschied in den 32 Bits liegen könnte und habe für meinen Arduino eine Konvertierungsfunktion mit Beispielprogramm gemacht. Vielleicht hilft's (Code ist ein "Arduino-Sketch" mit Ausgabe auf Serial):
1 | /**************************
|
2 | The IEEE754 standard says:
|
3 | 1 bit sign
|
4 | 8 bit exponent
|
5 | 23 bit mantissa
|
6 | |
7 | Microchip variation for Pic says:
|
8 | 8 bit exponent
|
9 | 1 bit sign
|
10 | 23 bit mantissa
|
11 | **************************/
|
12 | |
13 | float PicArrayToIEEEFloat(unsigned long picFloat) |
14 | {
|
15 | static union |
16 | {
|
17 | float value; |
18 | unsigned long lword; |
19 | } ieeeFloat; |
20 | |
21 | ieeeFloat.lword=((picFloat<<8) & (1L<<31)) | ((picFloat & 0xFF000000)>>1) | (picFloat & 0x7FFFFFL); |
22 | return ieeeFloat.value; |
23 | }
|
24 | |
25 | |
26 | void setup() |
27 | {
|
28 | Serial.begin(9600); |
29 | float f=PicArrayToIEEEFloat(0x85C3A029); |
30 | Serial.println(f,6); // print f with 6 decimals |
31 | }
|
32 | |
33 | void loop() |
34 | {}
|
Formatiert mit 6 Nachkommastellen erhalte ich: -97.812812 Aber das "single" Datenformat ist bekanntlich auch gar nicht auf 8 signifikante Stellen genau.
Ralf H. schrieb: > Hallo, > ich versuche einen Floatwert aus einem EEPROM auszulesen, der mit einem > PIC18F Mikrocontroller abgelegt wurde. Es wäre gut wenn du uns noch den Compiler nennen könntest, der für den PIC18 benutzt wurde ! XC8 oder C18 scheinen es nicht zu sein. Ich hänge mal einen Screenshot für C18 an. (XC8 scheint standardmäßig 24bit zu verwenden) Jürgen S. schrieb: > Also ich als Arduino-Programmierer ... Also ich als NICHT Arduino-Programmierer würde nie auf die Idee mit der seriellen Ausgabe kommen ;-)
Jürgen S. schrieb: > Microchip variation for Pic says: > 8 bit exponent > 1 bit sign > 23 bit mantissa Falsch, Microchip C18: 32-bit floating-point types are native to MPLAB C18 using either the double or float data types. MPLAB C18 utilizes the IEEE-754 floating-point standard to represent floating-point types. Microchip XC8: The MPLAB XC8 compiler supports 24- and 32-bit floating-point types. Floating point is implemented using either a IEEE 754 32-bit format, or a modified (truncated) 24-bit form of this. Format: Sign - Biased exponent - Mantissa
:
Bearbeitet durch User
Hallo, vielen Dank für die Hilfe. Ich benutze für den PIC18F252 einen PCH Version 4.065 Compiler der Firma CCS. Das Programm von Jürgen wandelt den Wert bei mit einem Arduino richtig um. Wäre nur noch die Frage warum der PIC diesen Wert so speichert (ist das Compiler oder PIC spezifisch?). Leider kann ich an dem Programm, das die Werte ins EEPROM schreibt nichts ändern. Ich nutze nur den PIC und den o.g. Compiler oder ein Arduino, um die Werte auszulesen. Der o.g. Compiler wurde meines Wissens auch für das Ursprungs-Programm genutzt, das die Werte ablegt. Gruß, Ralf
Ralf H. schrieb: > Ich benutze für den PIC18F252 einen PCH Version 4.065 Compiler der Firma > CCS. Dann musst du im Handbuch für diesen Compiler nachschauen ...
Jetzt habe ich es gefunden. Zitat CCS: CCS uses the same format Microchip uses in the 14000 calibration constants. Das sign bit sitzt am Anfang des zweiten Bytes. Vielen Dank für die Hilfe!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.