Forum: Mikrocontroller und Digitale Elektronik float byte Umwandlung PIC18F


von Ralf H. (ralf8888)


Lesenswert?

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

von Ralf H. (ralf8888)


Lesenswert?

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;
}

von Jürgen S. (jurs)


Lesenswert?

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.

von Volker S. (vloki)


Angehängte Dateien:

Lesenswert?

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 ;-)

von Volker S. (vloki)


Lesenswert?

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
von Ralf H. (ralf8888)


Lesenswert?

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

von Volker S. (vloki)


Lesenswert?

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 ...

von Ralf H. (ralf8888)


Lesenswert?

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
Noch kein Account? Hier anmelden.