www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Gleitkommazahlen im EEPROM speichern


Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was für ein EEPROM, welche Plattform, welche Programmiersprache, welche 
Datentypen?

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst es in C mit einer union machen...

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie würde das funktionieren? Bin leider kein C-Profi..

Autor: Johannes M. (johnny-m)
Datum:

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

z.B.:
union{
uint8_t bytes[4];
float wert;
} zahl;
//...
zahl.wert = 1.23456;
//...
for(i = 0; i < 4; i++)
{
    eeprom_write(zahl.bytes[i]);
}

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und warum nicht den float-Wert direkt zuweisen?

MW

Autor: Andreas Posch (andyp17)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Bruno (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht 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??

Autor: Bruno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da gebe ich dir völlig recht.

Autor: Michael Wilhelm (Gast)
Datum:

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

MW

Autor: Andreas Posch (andyp17)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, danke... werd ich gleich mal probieren... Danke erstmal!!


mfg
Andy

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder einfach einen Pointer verwenden
int i;
char ^p;
float f;

p = &f;
for (i=0, i<4, i++)
  eeprom_write(^p++);

Autor: überleger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder als Text speichern. Dann sieht man gleich, ob es geklappt hat.

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auslesen könntest du über Zeiger (hier double):
Lesefunktion(&Double_Variable,(uint8_t*)0,sizeof(double));
und schreiben so:
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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, viele Wege führen nach (EEP-) ROM...

Autor: Andreas Posch (andyp17)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Little Helper (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thilo M. (Gast)
Datum:

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

Autor: Jupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.