Hallo, ich möchte auf meinem Eigenbau-Wecker die Temperatur in Zehntel-Grad anzeigen. Dazu muss diese ( erg=lsb-0.25+((0x10-cnt_r)/0x10) ) Formel implementiert werden. Wenn ich jedoch mit double loslege, dann fliegt mir der Flash um die Ohren, da der Controller schon ziemlich voll ist. Welche Ideen gibts hier ? Gruß Andreas
Das ganze mit Hundert (oder noch mehr) Multiplizieren und dann mit ganzen Zahlen rechnen. Ne Division durch 0x10 sollte doch das gleiche sein wie Division durch 16 (?). Dann entspricht das ganze einer Rechtverschiebung um 4. Vielleicht hilft dir das. Steffen
Zunächst obige Formel etwas umbauen um alles ganzzahlig in 1/16 Grad zu rechnen. Danach ganzzahlig mal 10 durch 16.
Falls Du es selber nicht hinbekommst.... Stichwort wäre dann: fixed point arithmetic, siehe Artikel Festkommaarithmetik Oder du bemühst die Forensuche, es gibt einige Threads zu dem Thema. Oder die "Abschreiblösung" für den DS18S20: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=24879 900ss
Hi 900ss, vielen Dank! Das ist de richtige Tipp ... Gruß Andreas
Gast^2 wrote:
> vielen Dank! Das ist de richtige Tipp ...
Du meinst den Link zu AVRFreaks?
Hab ich befürchtet ;-) Damit lernst du es nicht. :-)
Gruß 900ss
A. K. wrote: > Zunächst obige Formel etwas umbauen um alles ganzzahlig in 1/16 Grad zu > rechnen. Danach ganzzahlig mal 10 durch 16. Alles ganzahlig, wie A. K. schon geschriben hat. erg = Ergebnis der Wandlung erg_10 = Ergebnis in 1/10 Grad
1 | int16_t erg_10 = 0; |
2 | int16_t erg = getWandlungsErgebnis(); |
3 | |
4 | erg_10 += (erg >> 3); |
5 | erg_10 += (erg >> 1); |
=> erg/8 + erg/2 = erg/8 + 4*erg/8 = 5/8 * erg = 10/16 * erg Achtung: funktioniert nur mit Werten >= 0 Hoffe aber, dass du die Idee bekommen hast, das signed-Bit noch passend zu manipulieren ist aber auch kein Problem.
Christian L. wrote:
> => erg/8 + erg/2 = erg/8 + 4*erg/8 = 5/8 * erg = 10/16 * erg
Wenn du dir die Formel im Eingangspost mal genauer ansiehst, dann wirst
du feststellen, dass deine Methode etwas übersieht und somit hier
falsche Ergebnisse liefert.
900ss
N'abend, ich habe das jetzt so gelöst und erfolgreich getestet: Eingabe uint8_t -> msb, lsb, cnt_p_c, cnt_r, uint16t -> erg
1 | erg=msb; // baut 16-Bit-Zahl zusammen (9BIT Auflösung) |
2 | erg<<=8; // |
3 | erg|=lsb;// |
4 | erg>>=1; // eliminate bit0 |
5 | |
6 | //erg=lsb-0.25+((cnt_p_c-cnt_r)/cnt_p_c);
|
7 | erg<<=4; // *16 |
8 | erg-=4; // -(4/16) |
9 | erg+=(cnt_p_c-cnt_r); // +(cnt_p_c-cnt_r) |
10 | erg*=10; // *10 gibt 1. Nachkommastelle, *100 gibt 1.+2. Nachkomaastelle |
11 | erg>>=4; // division /16 |
voila, erg enthält jetzt die Temp*10 bzw. *100 Gruß und Danke für die Tipps Andreas
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.