Gleitkommazahlen

Gast #2016946
Lesenswert?

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
Gast #2016960
Lesenswert?

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 :-)
Gast #2017375
Lesenswert?

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
  }
Gast #2017771
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren