Hallo, ich versuche analoge werte vom AT89C51CC01 zu lesen. Jeder zweite Wert scheint falsch zu sein. 272 448 272 438 272 438 272 440 272 437 272 436 273 436 273 434 273 434 273 434 Der C-Code sieht so aus. ADCF = 0x80; // kanal P1.7 für ADC ADCON = 0x20; // Anfang ADC ADCON &= 0xF8; // Clear the field SCH[2:0] ADCON |= 0x07; // Select kanal ADCON |= 0x08; // Fangt Umrechnung im Stadard Mode an while((ADCON & 0x10)!= 0x10) {}// Warte flag ADCON &= 0xC7; // Clear the End of conversion flag ADC_Wert = (ADDH << 2)+(ADDL); printf("%i\n",ADC_Wert); ADC_Wert = 0x00; ich würde mich freuen wenn mir jemand helfen könnte. ich hoffe ich habe alle relevanten Angaben gemacht. Vielen Dank !!!!
Hallo Lars, setze in das Klammerpaar bei der while-Schleife ein Semikolon ! Also: while (.....) {;} oder while {....}; Carlos
Tschuldigung: Falsche Klammern beim 2. Beispiel: while (....); Carlos
> ADC_Wert = (ADDH << 2)+(ADDL);
Die Berechnung ist erst mal grundsätzlich falsch. Du musst ADDH um 8 Bit
verschieben, damit die 2 Bit, die in ADDH gelten an die richtige
Position kommen.
Zum anderen hast du mit dieser Anweisung keine Kontrolle darüber, in
welcher Reihenfolge ADDH und ADDL tatsächlich ausgelesen werden. Der
Compiler darf hier jede beliebige Reihenfolge benutzen.
Ich weiß jetzt nicht, wie das bei deinem µC ist, aber bei den Megas ist
es so, dass zwingend zuerst L und erst dann H ausgelesen werden muss.
Diese Reihenfolge ist aber nur durch
ADC_Wert = ADDL;
ADC_Wert += ADDH << 8;
garantiert.
Hallo Karl Heinz, da muss ich Dir leider widersprechen: die Berechnung ist genau richtig und läuft bei uns so schon seit einiger Zeit. Man muss nur darauf achten, daß ´ADC_Wert´ auch eine unsigned int-Variable ist, sonst klappts nicht und das Semikolon in der while-Klammer darf nicht fehlen. Carlos
Carlos schrieb: > Hallo Karl Heinz, > da muss ich Dir leider widersprechen: die Berechnung ist genau richtig In ADDH steht der Wert so, dass er um 2 Bit verschoben werden muss?` Das glaub ich dir nicht. Es sei denn es handelt sich um einen 4 Bit ADC, wobei sich dann aber die Frage stellt: wozu H und L Register. > Man muss nur darauf achten, daß ´ADC_Wert´ auch eine unsigned > int-Variable ist, sonst klappts nicht und das Semikolon in der > while-Klammer darf nicht fehlen. Das ist doch großer Unsinn. Der Semikolon in der Klammer hat nichts damit zu tun. Der leere Block ist eine leere Anweisung, die vom while abhängt. Das ist alles korrekt, du läufst da einem Phantom nach.
Karl Heinz Buchegger schrieb: > Carlos schrieb: >> Hallo Karl Heinz, >> da muss ich Dir leider widersprechen: die Berechnung ist genau richtig > > In ADDH steht der Wert so, dass er um 2 Bit verschoben werden muss?` > Das glaub ich dir nicht. Es sei denn es handelt sich um einen 4 Bit ADC, > wobei sich dann aber die Frage stellt: wozu H und L Register. Edit: Es gibt eine Möglichkeit, wann diese Berechnung richtig sein kann. Dann, wenn die Bits in den Registern so angeordnet sind ADDH ADDL D9 D8 D7 D6 D5 D4 D3 D2 0 0 0 0 0 0 D1 D0 Ob das so ist, weiß ich nicht. Ungewöhnlich wäre es allemal.
Hallo Karl Heinz, es ist leider ganz genau so, wie ich gesagt habe: der A/D-Wandler beim CC01er ist ein 10 Bit Wandler und die Ergebnis-Bits ADAT2 bis ADAT9 stehen im SFR ADDH und die Bits ADAT1 und ADAT0 stehen im SFR ADDL ganz rechts. Wenn Du also das 10 Bit-Ergebnis in einer unsigned int-Variablen zusammen bauen willst, schiebst Du ADDH um zwei Stellen nach links und addierst dazu ADDH. Und nichts anderes ! Und meines Wissens nach ist die Leer-Anweisung (=´NICHTS-Tun´, also warten) in ´C´ immer noch das reine Semikolon und kein leeres Klammern-Paar. Carlos.
Carlos schrieb: > der A/D-Wandler beim CC01er ist ein 10 Bit Wandler und die Ergebnis-Bits > ADAT2 bis ADAT9 stehen im SFR ADDH und die Bits ADAT1 und ADAT0 stehen > im SFR ADDL ganz rechts. > Wenn Du also das 10 Bit-Ergebnis in einer unsigned int-Variablen > zusammen bauen willst, schiebst Du ADDH um zwei Stellen nach links und > addierst dazu ADDH. > Und nichts anderes ! Ok. Diese Möglichkeit hab ich mir jetzt selbst auch schon zusammengereimt. Dann ist es das eben nicht. Was ist mit der Auslesereihenfolge der Register? Ist die wichtig? > Und meines Wissens nach ist die Leer-Anweisung (=´NICHTS-Tun´, also > warten) in ´C´ immer noch das reine Semikolon und kein leeres > Klammern-Paar. In diesem Punkt ist dein Wissen falsch. Ein leeres Klammernpaar ist eine perfekte leere Anweisung. Wenn dein Compiler das nicht mitmacht, dann ist der Compiler fehlerhaft.
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.