Float als 4 Byte im EEprom speichern

Gast #2745189
Hallo zusammen,
stehe hier jetzt vor einem Problem.
Ich programmiere in C, verwende zur kalibrierung des ADC eine Float Zahl 
32 Bit breit.
Wie kann ich diese Zahl als 4 Bytes zerlegen, um sie dann im EEprom zu 
speichern.
Vermule mal, mit indirekter Adressierung oder so.....
Bitte Hilfe.
LG Dirk
#2745194
Dirk F schrieb:
> Hallo zusammen,
> stehe hier jetzt vor einem Problem.
> Ich programmiere in C, verwende zur kalibrierung des ADC eine Float Zahl
> 32 Bit breit.
> Wie kann ich diese Zahl als 4 Bytes zerlegen, um sie dann im EEprom zu
> speichern.
> Vermule mal, mit indirekter Adressierung oder so.....
> Bitte Hilfe.
> LG Dirk

Mit einer Union kannst du das machen.
#2745211
Hallo Peter II,

>warum willst du es erst zerlegen, kann kann auch mehre byte auf einmal
speicher?

Die I2C Interfaces die ich kenne wollen die übertragenen Daten 
byteweise. Auch die Libfunktionen die ich kenne wollen das so. Die Frage 
ist also nachvollziehbar. Auch die Tatsache dass ein 32 float 
abgespeichert werden soll.

Gut, wie wäre es möglich. Union über float und uint8_t[4]. Danach kannst 
Du die Bytes einzeln adressieren. Über "union" belesen.

Andere Möglichkeit: Die float in einer Schleife mit vier Durchläufen 
jeweils um 8 bit nach rechts shiften und zerlegen, verunden, casten, 
eepromroutine aufrufen.

Grüße
Gast #2745212
Friedrich Janus schrieb:
> Die I2C Interfaces die ich kenne wollen die übertragenen Daten
> byteweise. Auch die Libfunktionen die ich kenne wollen das so. Die Frage
> ist also nachvollziehbar
ich gehe davon aus das er es intern speicher will, also nichts mit i2c.

float eeFooFloat EEMEM;

float  f;

eeprom_write_block (eeFooFloat ,&f, sizeof(f));
Gast #2745216
Hallo,
danke für die Tips.
Mit Unions kenne ich mich leider nicht aus.

Alsi die Float Zahl wird doch als 4 Bytes im Speicher der MC gehalten.
Wie komme ich denn einfach an diese 4 Bytes einzeln ran, um die dann ins 
EEprom zu schreiben.
Mit der indirekten Adtessierung kann man doch einen Pointer auf das 
erste Byte erzeugen, dann aufs zweite u.s.w.

Kann mir bitte jemand kurz ein Beispiel in C hier schreiben.

Danke
Gast #2745220
Dirk F schrieb:
> Wie komme ich denn einfach an diese 4 Bytes einzeln ran, um die dann ins
> EEprom zu schreiben.
du musst da nicht rankommen, es gibt fertige funktionen zum speicher 
eines floats.

ich habe schon ein beispiel hingeschrieben und Klaus Wachtler hat noch 
den link auf die fertige funktion - was brauchst du noch?
Gast #2745227
Hallo, sorry habe vergessen zu sagen, dass ich auf einem PIc18 mit 
HI-TECH C Compiler arbeite.
Also fertige AVR Rotinen nützen mir leider nicht, ich brauche reinen 
C-Code.
LG  DIrk
#2745483
Dirk schrieb:
> Super,
> danke für die Hilfe. Werde es gleich nach dem Kaffee mal ausprobieren.

Und gleich danach kaufst du dir ein C-Buch oder fängst zumindest an, das 
hier
http://openbook.galileocomputing.de/c_von_a_bis_z/
durchzuarbeiten.

Das
> Mit Unions kenne ich mich leider nicht aus.
> Muss es nicht b[3]; heißen?
sind deutliche Indizien dass du keines hast aber dringend eines brauchen 
würdest. Es gibt noch zig-tausend andere Kleinigkeiten ohne die du nicht 
verünftig programmieren kannst, die alle in den Büchern stehen und an 
denen du ohne Literatur verzweifeln wirst.
#2745486
Helmut Lenzen schrieb:
> typedef union {
> float f;
> unsigned char b[4];
> } FB;
>
>
> FB fb;
>
> fb.f = 1234.0;   float rein
>
> b1 = b[0];    byte raus

Man kann sich allerdings auch den ganzen Umstand mit Definition eines 
eigenen Datentypen und umkopieren des Float sparen:
1
float f; // meine Variable
2

3
unsigned char* b = (unsigned char*)&b;
4

5
b1 = b[0];
6
.
7
.
8
.
Gast #2745508
Hi zusammen, ja, ein C-Buch habe ich schon, habe mich auch eben mal in 
die Union eingelesen.
Das Programm läuft jetzt.
Gruß Dirk


//********************EEwriteD Float 32 *********
void EEwriteD(unsigned int adr, double dat) /* write a Double Float of 
data to EEPROM */
{
union {
float f;
unsigned char b[4];
} test ;

test.f = dat;  //  float rein

 EEwrite (adr+0,test.b[0]);    // 1. Byte
 EEwrite (adr+1,test.b[1]);    // 2. Byte
 EEwrite (adr+2,test.b[2]);    // 3. Byte
 EEwrite (adr+3,test.b[3]);    // 4. Byte
}
(Firma: EleLa - www.elela.de) #2745518
Das bezweifle ich, dass das jetzt richtig geht.

lese mal über Unterschiede zwischen double und float und werde Dir 
darüber klar dass es bei einem Typecast einen Genauikeitsverlust gibt.

Dennoch empfehle ich ausschließlich "long double" zu verwenden, damit 
Dein Programm erst recht langsam wird.
Gast #2745521
Markus Müller schrieb:
> lese mal über Unterschiede zwischen double und float und werde Dir
> darüber klar dass es bei einem Typecast einen Genauikeitsverlust gibt.

bei einem atmel sind beide gleich, und es gibt doch auch keinen 
Datenverlust. Und bei dem pics scheint es auch so zu sein.
#2745524
Markus Müller schrieb:
> lese mal über Unterschiede zwischen double und float und werde Dir
> darüber klar dass es bei einem Typecast einen Genauikeitsverlust gibt.

Wenn man davon absieht, dass Hi-Tech für PIC18 in der 
Standardeinstellung keinen Unterschied zwischen float und double macht, 
und beide sowieso nur 24 Bits gross sind. Man kann wahlweise auch 32 
Bits kriegen, aber das wars dann auch.
#2745531
Keine Frage. Wenn man nicht grad mit 24-bit float und 32-bit double 
arbeitet, dann ist schon die blosse Verwendung des double Typs 
eigentlich Selbstverarschung. Bei AVRs ja auch, es suggeriert mehr als 
tatsächlich drin ist. Bei float sieht man das wenigstens.
Gast #2745613
Hallo,
also ich habe die Kalibrierung des 24 Bit Wertes vom ADC mit Float (24 
Bit) und mit Double (32 Bit)  verglichen.
Bei Double kan man feiner kalibrieren.
Meinen Hi-Tech C18 habe ich auf 32 Bit beim Typ Double eingestellt.

Der 23 Bit Wert + Vorzeichen (18 Bit rauschfrei) vom ADC entspricht 
einer Spannung von 0...5 V.
Hatte vorhrt mit LONG (INT 32 Bit) gearbeitet, war aber zu ungenau.

Danke für die gute Hilfe, ist schon ne feine Sache so ein Forum....
LG Dirk
Gast #2745657
>Der 23 Bit Wert + Vorzeichen (18 Bit rauschfrei) vom ADC entspricht
einer Spannung von 0...5 V. Hatte vorhrt mit LONG (INT 32 Bit) 
gearbeitet, war aber zu ungenau.

Na dann viel Glueck. Denn Longint mit 32bit hat 9 signifikante Stellen. 
Float mit 32bit hat nur 6 signifikante Stellen. Etwas anderes waere 
double mit 64bit. Das hat 15 signifikante Stellen.
Gast #2745725
>>>Na dann viel Glueck. Denn Longint mit 32bit hat 9 signifikante Stellen.
>>>Float mit 32bit hat nur 6 signifikante Stellen. Etwas anderes waere
>>>double mit 64bit. Das hat 15 signifikante Stellen.

Das Problem bei Longint 32 Bit ist, dass ich bei der Multiplikation des 
18 Bit Messwertes mit dem Skalierungsfaktor als LONGINT mit dem Ergebnis 
schnell an die 32 Bit Grenze stoße. 64 Bit INT kann mein Compiler nicht.

Deshalb  der Weg:
Messwet 18 Bit mit Faktor x als double skalieren und dann wieder in 
longint32 zurückwandeln.

ALs Ergebnis kann ich bei einem Messbereich von 5 V  6 Nachkommastellen 
darstellen, das reicht.

Gruß Dirk

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.