Problem bei der Umwandlung von binär auf dezimal

Gast #31689
Hallo,
ich möchte das AD-Wandler Ergebnis meines Atmega128 welches in den 
Registern ADCL und ADCH geschrieben wird in eine
Dezimalzahl umwandeln. Ich lasse mir den Inhalt beider Register auf 
einem Display anzeigen, die Umwandlung in eine Dezimalzahl mit diesem 
Code funktioniert jedoch nicht, was mache ich denn falsch ?

unsigned long int nkl;
unsigned long int nkh;
unsigned long int nk;

nkl=ADCL.0*1+ADCL.1*2+ADCL.2*4+
    ADCL.3*8+ADCL.4*16+ADCL.5*32+ADCL.6*64+ADCL.7*128;
nkh=ADCH.0*256+ADCH.1*512+ADCH.2*1024+ADCH.3*2048
    +ADCH.4*4096+ADCH.5*8192+ADCH.6*16384+ADCH.7*32768;
nk=nkl+nkh;

Compiler ist Codevision, danke für eure Hilfe.
Gast
Hallo Thomas,

du machst dir das Leben ein bisschen schwer. ADCL und ADCH sind doch 
zwei 8-bit-Register, die du doch ganz einfach auslesen und dann verODERn 
kannst (nachdem du das eine oder andere bit verschoben hast). Als 
Ergebnis erhältst du eine 16-bit-Zahl, für die auch eine 16-bit-Variable 
reicht (long int ist 32-bit). Und nicht vergessen, ADCL muss vor ADCH 
gelesen werden.

Gruß
Olaf
Gast
Du gehst das etwas falsch an... Stellen wir uns mal die beiden Register, 
ADCL und ADCH vor. Beide zusammen ergeben einen 16Bit-Wert (In C also 
ein Integer). Im Register ADCH stehen die 8 höherwertigen Bit des Wertes 
(hier X), im ADCL die 8 unteren (hier Y). Dein gewünschter Wert schaut 
bitweise also so aus:

0bXXXXXXXXYYYYYYYY

Man muss die Werte der Register nur gekonnt plazieren:

// Schnipp
unsigned int uiErgebnis;

uiErgebnis = (ADCH << 8);
uiErgebnis |= ADCL;
// Schnap

...und schon steht in uiErgebnis der vom ADC erzeugte Wert.
Die erste Aktion (das Schieben um 8 nach links) schiebt die X'e an die 
Position wo sie hin gehören, hinten rücken 0'en nach. 0bXXXXXXXX00000000
Jetzt verknüpfe ich den bisherigen Wert mit dem Wert im ADCL Register, 
genau 8 Bits lang, sie befinden sich natürlich 'automatisch' an den 
unteren acht Bitstellen auf Grund ihrer Wertigkeit, darüber stehen quasi 
wieder 0'en. Einfach ein logisches OR und alles ist an seinen Platz.
Gast
Da Olaf es erwähnt, da ADCL vor ADCH ausgelesen werden muss schaut der 
Schnipsel so aus:

unsigned int uiErgebnis;

uiErgebnis = ADCL;
uiErgebnis |= (ADCH << 8);
Gast
Danke ! Gute Erklärung ! Bin die Sache wohl falsch angegangen ...
Ich habe aber noch ein Problem. Ich lese ADCL und ADCH wie oben 
beschrieben (in der richtigen Reihenfolge ein) und lasse mir diese 
Register sowie uiergebnis auf dem LCD ausgeben.

Liegt der Eingang des AD-Wandlers auf 5V (=Referenzspannung)
erhalte ich

ADCH
00000011

ADCL
11111111

uiergebnis
1023

was soweit ja auch in Ordnung ist. Lege ich den Eingang jedoch auf GND, 
dann erhalte ich

ADCH
00000000

ADCL
00000000

uiergebnis
033 oder 239 oder was beliebiges

Der Inhalt von ADCH und ADCL wird richtig angezeigt, uiergebnis aber 
falsch (beliebiger Wert). Hat jemand eine Erklärung dafür ? Wenn ADCH 
und ADCL richtig angezeigt werden, wie kann es denn sein, dass 
uiergebnis nicht stimmt ?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 23 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.