PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : uint8_t[4] -> float ergibt komische Rundungen



PCMan
09.01.2009, 20:34
Hallo Leute,
also im Moment funktioniert bei mir irgendwie garnix gescheit, ist mal ein Problem gelöst kommt gleich das nächste sinnlose Problem daher.
](*,)

Okay zum Problem: ich habe Messwerte, die typischerweise als floats vorliegen. Diese Floats sollen in ein seperates EEPROM. Die schnittstelle ist per IIC realisiert (mit p. fleuries library).

Wenn ich einen float Wert auf einen Chip speichern möchte habe ich folgende Funktion geschrieben:


void write_f(uint16_t adress, float f32)
{
union {
float r;
uint8_t i[sizeof(float)];
} u;
u.r = f32;

adress*=4; //in welche 4 zellen die einzelnen bytes kommen...
i2c_start_wait(EEPROM_CHIP_V+I2C_WRITE);
i2c_write(HIGHBYTE(adress)); //übertrage speicheradresse
i2c_write(LOWBYTE(adress));
i2c_write(u.i[3]); //schreibe 4 bytes
i2c_write(u.i[2]);
i2c_write(u.i[1]);
i2c_write(u.i[0]);

i2c_stop();
return;
}


Zum abrufen der Bytes auf dem Chip und für die Konversion zurück zu float habe ich folgende Funktion:



float read_f(uint16_t adress)
{
union
{
float f;
uint8_t i[sizeof(float)];
} u;

adress*=4;
i2c_start_wait(EEPROM_CHIP_V+I2C_WRITE);
i2c_write(HIGHBYTE(adress)); //übertrage speicheradresse
i2c_write(LOWBYTE(adress));
i2c_rep_start(EEPROM_CHIP_V+I2C_READ);

u.i[3] = i2c_readAck(); //schreibe die 4 bytes
u.i[2] = i2c_readNak();
u.i[1] = i2c_readNak();
u.i[0] = i2c_readNak();

i2c_stop();
return u.f;

}


Gut, wenn ich nun folgenden Aufruf tätige:



char str[16];
union
{
float f;
uint8_t i[sizeof(float)];
} u1;

union
{
float f;
uint8_t i[sizeof(float)];
} u2;

u1.f = 2.22;

u2.i[3] = u1.i[3];
u2.i[2] = u1.i[2];
u2.i[1] = u1.i[1];
u2.i[0] = u1.i[0];

dtostrf(u2.f,4,2,(char*)str);
lcd_puts(str);


... erhalte ich wie gewünscht 2.22 auf dem Display. Soll ja auch so sein.

Wenn ich aber die Bytes über das EEPROM abhole:



char str[16];
write_f(0, 2.22);
dtostrf(read_f(0),4,2,(char*)str);
lcd_puts(str);


Dann erhalte ich 2.23 auf's Display.
Kann mir bitte jemand erklären, wie es zu dieser Rundung kommt? Ich habe schon allesmögliche probiert, finde aber den Fehler nicht raus...
Ich meine, der einzige Unterschied ist doch nur, dass einmal die Daten per IIC auf nen externen Speicher übertragen werden, beim anderen Fall bleibt halt alles im RAM. Das Phänomen ist übrigens Speicherzellenunabhängig.

Viele Grüße und danke schön mal wieder,
Simon

Besserwessi
09.01.2009, 22:51
Sieht nach einem sehr komischen Fehler aus. Ich würde mal vermuten, das die daten nicht ganz richtig ins EEPROM geschreibenw erden oder gelesen werden. Ein Test wo die 4 Bytes einzeln statt einer float ausgegeben werden sollte da helfen.

PCMan
10.01.2009, 10:31
Hi.
Ja das habe ich auch schon getestet, aber da kam mir die Unterbringung der Bytes wie erwünscht vor. Ich habe mal versucht nich 4 Bytes auf einmal zu "Pagen" sondern 2*2 Bytes zu schicken mit einer StopBedingung dazwischen. Das funktioniert dann komischerweise so wie gewünscht. Der EEPROM Baustein 32LC24 unterstützt laut Datenblatt aber ein Pagen von 8 Bytes * 8 Pages sogar. Kann mir das nich erklären.
Grüße Simon