Hallo,
ich will mit dem internen AD-Wandler eines Atmega eine Spannungswert
auslesen, in eine Gleitkommazahl umrechnen und auf einem LCD-Display
anzeigen lassen.
Zum Beispiel: 1 Bit im ergebnissregister des ADW entspricht 54,244mV.
Ich will jetzt in V umrechnen auf eine Stelle hinterm Komma und auf
einen LCD Display anzeigen lassen.
Könnte mir jemand helfen?
mfg peter
Ungeschickt.
Gleitkomma ist bäh.
Rechne es als Ganzzahl in mV aus, bei der Ausgabe verschiebst du dann
das Komma um 3 Stellen und lässt die letzten 2 Stellen weg.
:-)
Hallo,
@Floh
die idee ist eigentlich gar nicht schlecht.
Hier ist mal mein gesammter Programmcode, aber intressant ist nur der
Teil mit der Umrechnung. Ich habe ihn mit Anzeige Gleitkommazahl
makiert.
mfg peter
Peter schrieb:> Hier ist mal mein gesammter Programmcode
Du kommst aus der Assemblerecke. ;-)
Was du da im Programm versuchst, ist rjmp mit goto nachzubauen.
Ist eigentlich nicht zu empfehlen, da C selbst "bessere/gebräuchlichere"
Strukturen mitbringt, als unbedingte Sprünge irgendwohin.
Stichwort Funktionen.
Oder z.B. so was:
> Spannungswert = ADCH, ADCL;
da solltest du dich mal über den Kommaoperator schlau machen :-)
Mit Multiplikation:
Beitrag "Re: Float-Berechnung auf 8051 mit SDCC"
Ganz anderer Ansatz:
Nimm die Routinen zur Ausgabe von Zahlen von Peter Danegger, nur dass Du
nicht dezimale Werte subtrahierst / addierst, sondern die Aquivalente zu
1V, 0,1V etc.
Somit geht die Umwandlung ganz ohne Division und Multiplikation.
Der vorige Ansatz war nur als Ideenspender gedacht, er funktioniert bei
manchen Werten nicht korrekt (z.B. wird statt 0,210 0,20: ausgegeben).
Deshalb hier eine neue Version:
von den 1024 Werten weichen 26 um 0,001 vom korrekt gerundeten Wert ab,
damit kann man leben.
1
registerunsignedinti;
2
registercharc;
3
i=(x<<6)+6;//Schieben entfällt bei ADLAR=1, +6: runden
4
//i=(1023<<6)+6;//Test: ergibt 4,995
5
c='0';
6
while(i>=13107){c++;i-=13107;}//13107.2
7
putch(c);putch(',');
8
9
c='0';i+=i*4;i-=2;//das selbe wie i=i*5-2; (-2: Korrektur, da vorher Nachkommastellen abgeschnitten wurden)
10
while(i>=6553){c++;i-=6553;}//6553.6
11
putch(c);
12
13
c='0';i+=i*4;i*=2;i-=2;//das selbe wie i=10*i-2; aber kürzerer Code
14
while(i>=6553){c++;i-=6553;}
15
putch(c);
16
17
c='0';i+=i*4;i*=2;i-=2;
18
while(i>=6553){c++;i-=6553;}
19
putch(c);
Das alternativ Subtrahieren / Addieren habe ich absichtlich nicht
gemacht, da das Vorzeichen-Bit ein Bit Genauigkeit kostet.
Darf man kein printf() nehmen? Ansonsten:
unsigned long dV;
dV = ((unsigned long) ADC-Wert * 568789L) >> 20;
printf ("Spannung = %lu,%lu V", dV / 10, dV % 10);