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
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.
Dirk F schrieb: > Wie kann ich diese Zahl als 4 Bytes zerlegen, um sie dann im EEprom zu > speichern. warum willst du es erst zerlegen, kann kann auch mehre byte auf einmal speicher? http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Block_lesen.2Fschreiben Die andere Frage ist ob ein float überhaupt sinnvoll ist. Auch aus einem ADC kommt kein float raus.
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
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));
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html#gac738db5e12a0369d332ca43563755095 http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html#ga88da5e9bf80b4acded6018314baab6cd
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
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?
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
typedef union { float f; unsigned char b[4]; } FB; FB fb; fb.f = 1234.0; float rein b1 = b[0]; byte raus usw.
Rainer S. schrieb: > Muss es nicht > b[3]; > heißen? wenn dein float aus 3 byte besteht ja, sonst nicht.
Super, danke für die Hilfe. Werde es gleich nach dem Kaffee mal ausprobieren.
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.
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 | .
|
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 }
Dirk schrieb: > Hi zusammen, ja, ein C-Buch habe ich schon, Arbeite es durch! Das ist wichtig, dass du dein Werkzeug (die Programmiersprache) auch kennst!
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.
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.
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.
Dirk F schrieb: > Vermule mal, mit indirekter Adressierung oder so..... Kann man: uin8t_t *p = (uint8_t *)&zahl; und dann p[0], p[1], ... p[sizeof(zahl)-1] verwenden. Unions sind ein Weg, das ist ein anderer.
Ach ja, ein Kastrierter float, auch noch deklariert als double. Dennoch programmiert man so nicht, wenn man den Code auf einen größeren Prozi portiert gibt es auf einmal Probleme.
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.
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
>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.
>>>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
ne 32b*32b MUL kann man sich auch selber schreiben, hier im Forum gabs dazu was bei denen die DDS ICs ansteuern.
Hallo PeterII,
>ich gehe davon aus das er es intern speicher will, also nichts mit i2c.
OOOps, der Fehler lag zwischen den Ohren.
Grüße
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.