Gleitkommazahlen

Gast #2016946
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 #2016949
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.
:-)
Gast #2016955
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
Angehängte Dateien:
Gast #2016960
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
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
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.
Gast #2017820
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);

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.