hallo.
ich habe da ein problem. ich möchte eine double variable auf einem lcd
display anzeigen lassen. das ganze wurde für einen atmega32 geschrieben.
die funktion funktioniert soweit, aber da sind ungenauigkeiten drin.
zB. will ich die zahl 2.000001 anzeigen lassen. da zeigt er mir 2.000000
an.
ich hoffe, dass ihr mir helfen könnt. ich hab keine idee woran es
scheitert.
edit: der übergabewert cpoint besagt, wieviel stellen nach dem komma ich
angezeigt haben möchte. maximal sind in dieser funktion 6
nachkommastellen geplant.
1
void lcd_put_float(double dnumber, char cpoint)
2
{
3
char cz=0; //Schleifenzähler
4
char cbuffer[7]={0,0,0,0,0,0,0};
5
double dnach=0;
6
long lz=0; //Zwischenspeicher
7
if(dnumber<0) //Wenn die Zahl negativ ist, schreibe ein - und wandel die zahl ins positive
Ich wühle mich nun nicht durch den Code, denn da sind mir ein wenig zu
wenig Kommentare enthalten und das Rad wird vermutlich auch nicht mehr
wesentlich runder.
Du hast aus meiner Sicht zwei Probleme:
- Die Ausgabe von double: Das geht mit sprintf bzw. einer der "dtoa"
implementierungen (fast) ganz schmerzlos. Nur fast schmerzlos, weil
die Implementierungen auf den AVR ziemlich umfangreich sind und daher
viel Platz im Flash-Speicher wegnehmen. Aber machen kann man es so.
(Falls Du aus "akademischen" Gründen wirklich darauf Wert legst das
selbst zu implementieren ist das eine andere Frage.
- Die Abweichung der Ausgabe von erwarteten Wert: Dafür enthält der
Beitrag zu wenig Information. Falls Du wirklich 2.000001 ausgeben willst
und 2.000000 erhälst, so stellt sich die Frage ob eine Double die Zahl
2.000001 überhaupt so speichern kann. Dazu gibt es genügend Seiten im
Netz. Falls das so gespeichert werden kann (was ich mal ad-hoc mal nicht
als gegeben nehme), dann trace einfach durch Deinen Code und guck was
schief geht. Falls nicht, dann musst Du damit leben.
@ Patrick Höfler (absynthe666)
>ich habe da ein problem. ich möchte eine double variable auf einem lcd>display anzeigen lassen. das ganze wurde für einen atmega32 geschrieben.
Auf dem avr gcc sind double = float = einfache Genauigkeit mit 5-6
Dezimalstellen. Somit gibt es die 2.000001 einfach nicht, so genau kann
nicht aufgelöst werden.
>void lcd_put_float(double dnumber, char cpoint)
Warum neu erfinden? Sowas gibt es schon, sei es mit sprintf() oder
ftoa().
Patrick Höfler schrieb:> das ganze wurde für einen atmega32 geschrieben.
Bei 32 KB Flash würde ich auch eher zu sprintf raten. Die lib nimmt mit
float glaub ich so 1,5 KB an Flash. Dafür trägt es ungemein zur
Leserlichkeit/Wartbarkeit deines Programms bei, und wenn man das dann
auch öfter nutzt sind die 1,5 KB Flash gut investiert. Deine putint,
puthex funktionen für das LCD kannst du dann auch komplett weg lassen.
Via vsprintf kannst du dir dann auch eine eigene lcd_printf(xpos,ypos,
*format, ...)-Funktion schreiben.
Nur auf kleinen Tinys oder so würde ich auf printf verzichten, da der
Flash-Speicher dort oftmals schon knapp bemessen ist.
@ Timmo H. (masterfx)
>Nur auf kleinen Tinys oder so würde ich auf printf verzichten, da der>Flash-Speicher dort oftmals schon knapp bemessen ist.
Dort, und auch auf größeren uCs, nimmt man meist besser
Festkommaarithmetik.
Falk Brunner schrieb:> @ Timmo H. (masterfx)>>>Nur auf kleinen Tinys oder so würde ich auf printf verzichten, da der>>Flash-Speicher dort oftmals schon knapp bemessen ist.>> Dort, und auch auf größeren uCs, nimmt man meist besser> Festkommaarithmetik.
Jeder wie er es mag. Aber ich nehme, wenn ich genug Platz habe, lieber
die Standard Librarires. Wenn ich schnell rechnen muss (imu etc.) ist
das was anderes, aber für formatierte Ausgaben via uart oder LCD tue ich
mir diese Klimmzüge nicht mehr an. Da schreibt man je nach Komplexität
meist mehr Funktionen als nötig wo es mit printf etc. doch viel
einfacher, verständlicher und portabler ist.