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.
1 | #include<stdio.h> |
2 | #include<conio.h> |
3 | |
4 | char c; |
5 | unsigned int i=0x0123<<6;//linksbündig entspricht 1,4208V ergibt 1,421 |
6 | //wenn das ADLAR-Bit in ADMUX gesetzt ist, entfällt das Schieben um 6
|
7 | |
8 | void main(void){ |
9 | putch(' '); |
10 | |
11 | i=( 1<<6); //ergibt 0,004 |
12 | i=( 1<<6)+2;//ergibt 0,005 |
13 | //i=(1023<<6)+2;//ergibt 4,995
|
14 | |
15 | c='0'; |
16 | while(i>=65536/ 5){c++;i-=65536/ 5;} //13107 |
17 | putch(c);putch(','); |
18 | |
19 | c='0'; |
20 | while(i>=65536/ 50){c++;i-=65536/ 50;} //1310 |
21 | putch(c); |
22 | |
23 | c='0'; |
24 | while(i>=65536/ 500){c++;i-=65536/ 500;} //131 |
25 | putch(c); |
26 | |
27 | c='0'; |
28 | while(i>=65536/5000){c++;i-=65536/5000;} //13 |
29 | putch(c); |
30 | |
31 | putch(' '); |
32 | |
33 | i=(1023<<6)+2;//ergibt 5,000 |
34 | |
35 | c='0'; |
36 | while(i>=65472/ 5){c++;i-=65472/ 5;} //13094 |
37 | putch(c);putch(','); |
38 | |
39 | c='0'; |
40 | while(i>=65472/ 50){c++;i-=65472/ 50;} //1309 |
41 | putch(c); |
42 | |
43 | c='0'; |
44 | while(i>=65472/ 500){c++;i-=65472/ 500;} //130 |
45 | putch(c); |
46 | |
47 | c='0'; |
48 | while(i>=65472/5000){c++;i-=65472/5000;} //13 |
49 | putch(c); |
50 | }
|
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 | register unsigned int i; |
2 | register char c; |
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);
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.