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
Was für ein EEPROM, welche Plattform, welche Programmiersprache, welche Datentypen?
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.
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 | }
|
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
@MW: Naja, ich muss das EEPROM ja byteweise beschreiben. Da muss ich die Zahl umwandeln
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.
1 | Bits 31...0 |
2 | float wert: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX |
3 | bytes[0] bytes[1] bytes[2] bytes[3] |
OK?
Kann man mit der eeprom.h nicht auch float zuweisen? Man muß nur mit dem Speicherbereich aufpassen. Kann mich aber auch irren.
@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...
@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??
Sorry, externes EEPROM überlesen, aber zurücklesen genauso. 4 x Byte aus dem EEPROM holen und float für die Weiterverarbeitung nehmen. MW
D.h. mit Zahl.Bytes hol ich die Daten aus dem EEPROM und mit Zahl.Wert kann ich dann weiterarbeiten??
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...
OK, danke... werd ich gleich mal probieren... Danke erstmal!! mfg Andy
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++); |
oder als Text speichern. Dann sieht man gleich, ob es geklappt hat.
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.
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...
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
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...
>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
Hier isses recht gut erklärt: http://www.3dcenter.de/artikel/fp_format/ (auch die nachfolgenden Seiten lesen)
>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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.