Forum: Mikrocontroller und Digitale Elektronik Problem bei der Umwandlung von binär auf dezimal


von thomas wk. (Gast)


Lesenswert?

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.

von Olaf (Gast)


Lesenswert?

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

von Sascha Weitkunat (Gast)


Lesenswert?

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.

von Sascha Weitkunat (Gast)


Lesenswert?

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);

von thomas wk. (Gast)


Lesenswert?

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 ?

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
Noch kein Account? Hier anmelden.