Forum: Mikrocontroller und Digitale Elektronik Gleitkommazahlen im EEPROM speichern


von Andreas P. (andyp17)


Lesenswert?

Hallo,

Vielleicht ist das jetzt eine dumme Frage, aber ich weiß momentan nicht 
weiter bzw. ich will nix falsch machen.

Wie ist es am sinnvollsten Gleitkommazahlen (zB. 1,002345) byteweise in 
einem EEPROM abzuspeichern? Wie zerlegt man diese? Gibt es da fixe 
Richtlinien?

Ich hoffe, ich konnte mich verständlich ausdrücken :)
Danke schonmal...


mfg
Andy

von Johannes M. (johnny-m)


Lesenswert?

Was für ein EEPROM, welche Plattform, welche Programmiersprache, welche 
Datentypen?

von Andreas P. (andyp17)


Lesenswert?

EEPROM ist eigentlich egal... aber konkret ist es ein 24AA08 von 
Microchip (über TWI ansprechbar)
Programmiersprache sollte C sein und uC ein Mega168.
Datentypen: float zu uint8_t (Array)

Aber eigentlich wollte ich nur wissen, ob es eine prinzipielle 
Vorgehensweise für diese "Umrechnung" gibt - unabhängig von 
Programmiersprache und Plattform.

von Johannes M. (johnny-m)


Lesenswert?

Du kannst es in C mit einer union machen...

von Andreas P. (andyp17)


Lesenswert?

Und wie würde das funktionieren? Bin leider kein C-Profi..

von Johannes M. (johnny-m)


Lesenswert?

Profi bin ich auch nicht (d.h. ich verdiene nicht mit C-Programmierung 
mein Geld)...

z.B.:
1
union{
2
uint8_t bytes[4];
3
float wert;
4
} zahl;
5
//...
6
zahl.wert = 1.23456;
7
//...
8
for(i = 0; i < 4; i++)
9
{
10
    eeprom_write(zahl.bytes[i]);
11
}

von Andreas P. (andyp17)


Lesenswert?

OK, ich versteh nicht ganz, was der Code macht. Warum schreibst du in 
der for-Schleife zahl.bytes? Welchen Wert nimmt bytes hier an?
Ich kenn mich mit dem union nicht ganz aus...

Danke für die Geduld mit mir... :)


mfg

von Michael Wilhelm (Gast)


Lesenswert?

Und warum nicht den float-Wert direkt zuweisen?

MW

von Andreas P. (andyp17)


Lesenswert?

@MW:
Naja, ich muss das EEPROM ja byteweise beschreiben. Da muss ich die Zahl 
umwandeln

von Johannes M. (johnny-m)


Lesenswert?

Ein float ist 4 Bytes (32 Bit) lang. In der union werden der float 
und 4 einzelne Bytes (uint8_t ) an der selben Stelle im Speicher 
abgelegt. Wenn in den float ein Wert geschrieben wird, kann jedes 
einzelne Byte des float über das Byte-Array ausgelesen werden.

von Johannes M. (johnny-m)


Lesenswert?

1
                        Bits 31...0
2
float wert: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
3
            bytes[0] bytes[1] bytes[2] bytes[3]
OK?

von Bruno (Gast)


Lesenswert?

Kann man mit der eeprom.h nicht auch float zuweisen? Man muß nur mit dem 
Speicherbereich aufpassen. Kann mich aber auch irren.

von Johannes M. (johnny-m)


Lesenswert?

@Bruno:
Da oben steht was von einem externen EEPROM, das über TWI 
angeschlossen ist, da nützt ihm die eeprom.h überhaupt nix! Er kann 
sich zwar eine Funktion schreiben, die einen float übermittelt, was aber 
nichts daran ändert, dass diese Funktion dann die Aufteilung in einzelne 
Bytes übernehmen muss...

von Andreas P. (andyp17)


Lesenswert?

@Bruno: Ich verwende ein externes EEPROM

@Johannes: OK, ist mir nun klar. Und wie mache ich es dann umgekehrt, 
wenn ich die 4 Bytes wieder auslese und ich diese in eine float-Zahl 
umwandeln möchte??

von Bruno (Gast)


Lesenswert?

da gebe ich dir völlig recht.

von Michael Wilhelm (Gast)


Lesenswert?

Sorry, externes EEPROM überlesen, aber zurücklesen genauso. 4 x Byte aus 
dem EEPROM holen und float für die Weiterverarbeitung nehmen.

MW

von Andreas P. (andyp17)


Lesenswert?

D.h. mit Zahl.Bytes hol ich die Daten aus dem EEPROM und mit Zahl.Wert 
kann ich dann weiterarbeiten??

von Johannes M. (johnny-m)


Lesenswert?

Andreas Posch wrote:
> D.h. mit Zahl.Bytes hol ich die Daten aus dem EEPROM und mit Zahl.Wert
> kann ich dann weiterarbeiten??
Genau. Musst nur aufpassen, dass Du Schreiben und Lesen in der selben 
Reihenfolge machst, sonst gibt's Datenmüll...

...und auf Groß- und Kleinschreibung achten! "Zahl.Bytes" ist nicht 
gleich "zahl.bytes"...

BTW: Das "eeprom_write" oben war natürlich nur als eine Art 
Pseudo-Funktion gedacht, da musst Du dann eben eine entsprechende 
Funktion einbauen, die ein einzelnes Byte ins EEPROM schreibt...

von Andreas P. (andyp17)


Lesenswert?

OK, danke... werd ich gleich mal probieren... Danke erstmal!!


mfg
Andy

von Martin (Gast)


Lesenswert?

Oder einfach einen Pointer verwenden
1
int i;
2
char ^p;
3
float f;
4
5
p = &f;
6
for (i=0, i<4, i++)
7
  eeprom_write(^p++);

von überleger (Gast)


Lesenswert?

oder als Text speichern. Dann sieht man gleich, ob es geklappt hat.

von Thilo M. (Gast)


Lesenswert?

Auslesen könntest du über Zeiger (hier double):
1
Lesefunktion(&Double_Variable,(uint8_t*)0,sizeof(double));
und schreiben so:
1
Schreibfunktion(&Double_Variable,(uint8_t*)0,sizeof(double));

In Lese- und Schreibfunktion werden die Bytes ab der dort angegeben 
Startadresse aus dem EEPROM geholt und 'reingeschrieben.
Auf die Speicherbereiche musste natürlich achten.

Du kannst dir die 'eeprom.h' im GCC mal angucken, das hilft sicher 
weiter.

von Johannes M. (johnny-m)


Lesenswert?

Tja, viele Wege führen nach (EEP-) ROM...

von Andreas P. (andyp17)


Lesenswert?

So, das funktioniert ja schon wunderbar.
Nur müsste ich jetzt wissen (zur Kontrolle), wie man float auf 4 Byte 
umrechnet. Z.B. ergibt die Zahl 1.2345 vier Bytes mit den Werten:
byte[0] = 25
byte[1] = 4
byte[2] = 158
byte[3] = 63

Woher kommen diese??

Danke...

von Little Helper (Gast)


Lesenswert?

Am besten schaust du dir mal den Artikel in der Wikipedia an, denn die 
Speicherung ist nicht ganz trivial.

http://de.wikipedia.org/wiki/Gleitkommazahl

von Johannes M. (johnny-m)


Lesenswert?

Die Kontrolle ist doch die "Rückrechnung". Über den eigentlichen Aufbau 
der Gleitkommazahl (Vorzeichen, Mantisse, Exponent) brauchste Dir 
überhaupt keine Gedanken zu machen, wenn Du gewährleistest, dass beim 
Schreiben und Lesen jeweils die gleiche Reihenfolge eingehalten wird.

Eine Gleitkommazahl vom Typ float besteht in diesem Fall aus 32 Bit, 
die in 4 Bytes hintereinander im Speicher abgelegt werden und auf die 
man dort auch einzeln zugreifen kann...

von Oliver (Gast)


Lesenswert?

>Nur müsste ich jetzt wissen (zur Kontrolle),

Zur Kontrolle schreibst du deinen Floatwert ins Eeprom, und liest ihn 
dann wieder aus. Kommt der gleiche Wert wieder raus, stimmts.

Wenn du die Einzelbytes wirklich wissen willst, geht das am einfachsten, 
indem du dir mit dem Debugger einen im Ram gespeicherten Floatwert 
ansiehst.

Oliver

von Thilo M. (Gast)


Lesenswert?

Hier isses recht gut erklärt:
http://www.3dcenter.de/artikel/fp_format/
(auch die nachfolgenden Seiten lesen)

von Jupp (Gast)


Lesenswert?

>Wie ist es am sinnvollsten Gleitkommazahlen (zB. 1,002345) byteweise in
>einem EEPROM abzuspeichern? Wie zerlegt man diese? Gibt es da fixe
>Richtlinien?

Einfach in Bytes umrechnen, und abspeichern.

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.