www.mikrocontroller.net

Forum: Compiler & IDEs float im EEPROM


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will ein float im EEPROM ablegen und auslesen. Klappt eigentlich 
auch. Aber ich will feststellen, ob da schon ein Wert abgelegt wurde, 
oder nicht (neuer Chip) und dann einen Standardwert nehmen. Das klappt 
nicht. µC: ATmega32

Ich habe:

float epromwert EEPROM;
float wert=0;
...
eeprom_read_block(&wert, &epromwert, sizeof(float));

Wenn ich wert mit

dtostrf (wert, 6, 3, text);

konvertiere, bekomme ich bei einem leeren EEPROM (FF) "NAN". Ok, so weit 
ja auch brauchbar. Jetzt dachte ich, ich prüfe mit

isnan (wert)

ob das Ergebnis aus dem EEPROM auslesen eine Zahl ist. Aber die Fkt. 
liefert immer 0
:-(

Wie mache ich's denn richtig?

Autor: Hermann-Josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florian,

eine interessante Fragestellung. Die beiden Funktionen in der avr-libc 
(Version 1.4.4) haben eine unterschiedliche "Meinung" darüber was ein 
NaN ist, ich denke, die richtige Definition müßte sich in IEEE-754 
finden, bei Interesse danach 'googeln' oder auch mal bei 
http://en.wikipedia.org/wiki/NaN vorbeischauen).

bei isnan() findet sich:
  CPI  r25, 0xFF  ; NaN is 0xffc0XXXX
  BRNE  .Lfalse
  CPI  r24, 0xC0
  BRNE  .Lfalse

bei dstrtof():
  cpi  r17, 0xff  ; NAN ?
  brne  1f

Es ist nicht auszuschliessen, dass avr-libc das noch nicht 100 %-ig 
implementiert (siehe auch 
https://savannah.nongnu.org/bugs/?group=avr-libc&f... , 
hier Item # 13330), ich würde das daher in der gegenwärtigen Situation 
'schmutzig' lösen und auf 0xffff (bzw. 2 Worte mit 0xffff) abprüfen. 
Wenn (float)0xfffffffff eine gültige Float-Zahl ist, dann hat man 
natürlich ein Problem... ich hab' gerade kein AVR-System hier, was käme 
denn da raus ?

Ciao
 Hermann-Josef

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah. Dann kann man sich ja totsuchen. Nachzuschauen, wie die Funktionen 
implementiert sind, käme mir nie in den Sinn. Ich gehe (blauäigig, wie 
ich wohl zugeben muß) davon aus, daß die Dinge so funktionieren, wie sie 
sollen.
Ich hatte es noch etwas dreckiger gemacht und in einen String gewandelt 
und dann mit strcmp auf "NAN" geprüft.

Aber der Test auf FF geht auch (in meinem Fall).

for (i=0; i<=6; i+=2)
{
  if (eeprom_read_word((uint16_t *)(&wert+i)) != 0xFFFF)
    is_number = 1;
}

Was mich jetzt nur noch stutzig macht, ist das ein double lediglich 4 
Bytes belegt, wie auch ein float.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, davon abgesehen, dass das gesamte Handling der IEEE754-
Sonderfeatures (Inf, NaN, Denormals) in der bestehenden
Implementierung unterbelichtet ist, ist es aber auch recht
blauäugig anzunehmen, dass ein 0xffffffff automatisch eine
gültige NaN wäre.  Den Test auf nicht programmierten EEPROM
solltest du also sinnvollerweise schon explizit gegen 0xffffffff
vornehmen.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

beim AVRGCC ist sizeof(double) == sizeof(float) Double ist (im Prinzip) 
nur eine typedef auf ein float.

Matthias

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg Wunsch
Ich ging ja nicht davon aus, daß das NaN ist, aber die Funktion isnan 
lieferte halt immer 0, das störte mich. Das die Implementierung nicht OK 
ist, kann man ja nicht unbdeingt wissen finde ich.

@Matthias Weißer
Aha. Wieder was gelernt (und vermutlich dann wieder vergessen, wenn ich 
es das nächste mal brauche :-( ) Ist halt doof, wenn man mehrere 
Sprachen kennt und immer wieder wechselt und dann Wissen transferieren 
will...

Danke.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Quellcode betrachtet die Funktion isnan() das Bitmuster
0xFFC0xxxx als NaN.

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.