Ich versuche schon länger einen Weg zu finden, einen Floatwert z.B. -12.4 in einen normalem EEPROM abzuspeichern. Das Auslesen aus dem EEPROM sollte auch gehen, um wieder eine Floatzahl daraus zu machen. Wie macht man das am schlausten? Vielen Dank für die Unterstützung im Voraus.
Eine floatzahl ist nichts weiter als mehrere Bytes. Du musst also nur herausfinden, wie mehrere Bytes ins EEPROM zu schreiben sind bzw. daraus gelesen werden sollen. Du könntest Dich beispielsweise daran orientieren, wie Strings im EEPROM abgespeichert werden können, das sind ja auch nichts anderes als mehrere Bytes. Und bei floatzahlen ist's sogar noch einfacher, da die Anzahl der Bytes bekannt ist, während sie bei Strings von deren Länge abhängt. Der Operator sizeof() liefert die Anzahl der Bytes, die eine Variable groß ist; bei float ist das in der Regel 4. Vielleicht ist ja der eine oder andere Anhaltspunkt dabei.
Kleines Beispiel in C: unsigned char i,j; float wert; unsigned int adresse; //lesen for(i=0;i<sizeof(wert);i++) { eeprom_lesen(adresse,k); adresse ++; if (i<sizeof(wert)-1) { wert = k; wert = wert << 1; } wert = k; } //schreiben for(i=0;i<sizeof(wert);i++) { eeprom_schreiben(adresse,(unsigned char)wert); adresse++; wert = wert >> 1; } ungetestet, schnell hingetippt MW
O nein. Das kann so nicht gehen. Was soll wohl das Ergebnis von wert = wert << 1; oder wert = wert >> 1; sein? Außerdem überschreibt Deine Leseroutine bei jedem Schleifendurchlauf wert mit dem letzten gelesenen Byte. Ich würd's so machen: unsigned char i; float wert; unsigned char* pwert; unsigned int adresse; //lesen pwert = (unsigned char *) &wert; for (i = 0; i < sizeof(wert); i++) { eeprom_lesen(adresse, k); adresse++; *pwert = k; pwert++; } //schreiben pwert = (unsigned char *) &wert; for (i = 0; i < sizeof(wert); i++) { eeprom_schreiben(adresse, *pwert); adresse++; pwert++; }
Warum so kompliziert? avr-libc hat doch schon alles an Board: float my_float, my_erg; my_float = -12.4; eeprom_write_block(&my_float, (void*) 20, sizeof(my_float)); my_float = 0; eeprom_read_block (&my_float, (void*) 20, sizeof(my_float)); my_erg = my_float; Den EEPROM-Ptr habe ich kurz quick&dirty gecastet, sorry dafür. Stefan
@Stefan: Ich kenne und verwende avr-libc nicht, mir ging es um die Darstellung des Prinzips. @Michael: Das verbessert nichts. Was meinst Du denn, was dabei 'rauskommt, wenn Du einen float - Wert shiftest?
(Nachtrag:) Mal kurz den folgenden Code einem anderen* C-Compiler zum Fraß vorgeworfen: float bla; float fusel; bla = 12.34; fusel = bla >> 8; Die Antwort des Compilers ist unmissverständlich: test.c(25) : error C2296: '>>' : illegal, left operand has type 'float' test.c(25) : error C2297: '>>' : illegal, right operand has type 'float' Tja, das ist wohl undefiniert. *) mangels momentaner Verfügbarkeit eines anderen war's MSVC++ 6.0
Hi Stimmt. Die << >> Operatoren sind für floating point Zahlen genausowenig erlaubt wie der % Operator. Aber den M$ VC++ Compiler (für C++) in Version 6 sollte man nicht unbedingt als Referenz verwenden. Der ist an einigen Stellen etwas, naja, kaputt. Der 7er soll da deutlich besser sein. Das weiß ich allerdings nur aus zweiter Hand. Matthias
@Rufus: stimmt, Dein Code ist vom Lerneffekt sicher besser. Die EEPROM-Blockbefehle haben allerdings den Vorteil, dass i.d.R. das EEPROM nur einmal beschrieben werden muss (solange die Daten innerhalb einer EEPROM-Page liegen). Stefan
@Matthias: VC++ 6 ist kein sonderlich standardkonformer C++-Compiler, das mag stimmen. Aber als C-Compiler hält er sich an C90 (ANSI-C). Meinen Test habe ich unter anderem deshalb mit C und nicht C++ angestellt (letzteres kann ja >> und << auch überladen, was wiederum ganz spannende Resultate liefern kann). @Stefan: D'accord. Nachdem man ein Prinzip verstanden hat, ist es sinnvoll und angebracht, Vereinfachungen zu verwenden. (Bist Du Dir mit den EEPROM-Schreibvorgängen absolut sicher? Das kann doch byteweise ohne Berücksichtigung irgendwelcher Pages beschrieben werden; so etwas wie Pages ist doch IMHO nur beim Beschreiben von Flash-ROMs zu berücksichtigen. Irre ich mich?)
@Rufus: >(Bist Du Dir mit den EEPROM-Schreibvorgängen absolut sicher? Das kann >doch byteweise ohne Berücksichtigung irgendwelcher Pages beschrieben >werden; so etwas wie Pages ist doch IMHO nur beim Beschreiben von >Flash-ROMs zu berücksichtigen. Irre ich mich?) Ganz sicher bin ich mir nie - ich bin Programmierer und kein Leichenbestatter ;-) Das EEPROM kann man entweder byteweise beschreiben oder gleich eine ganze Page (= 4 Bytes) füllen und dann "am Stück" programmieren. Da ein Schreibzyklus ca. 8,5ms dauert (unabhängig, ob nur ein oder alle 4 Bytes der Page beschrieben werden), kann dies schon ein erheblicher Zeitvorteil sein. Allerdings: ich habe das gerade mal verifiziert und bin bei beiden Möglichkeiten auf dieselbe Zeit gekommen - ca. 8s für 200 Schreibzyklen. Dann habe ich mir mal den Source von eeprom_write_block angeschaut: dort werden alle Bytes einzeln programmiert, die Page-Option wird nicht verwendet. Viele Grüße, Stefan
Ich muss die Sache mit den Pages zurücknehmen: Die page-weise EEPROM-Programmierung scheint nur einem externen Programmer vorbehalten zu sein. Über im Microcontroller zugängliche Register hat man dagegen keinen (dokumentierten) Zugriff auf die Page-Programmierung. Ich habe übersehen, dass sich das Kapitel "Memory Programming" ausschliesslich auf den externen Zugriff bezieht. Viele Grüße, Stefan
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.