Moin! Leider kann ich keinen Code posten, versuche aber, mein Anliegen ausreichend zu erklären: Ich möchte nacheinander und immer wieder 2 AD- Eingänge des Atmega8 abfragen (und erstmal per HTerm anzeigen). Dazu führe ich eingangs eine Init durch und ändere anschließend für jeden Einlesevorgang das "Mux-Register" entsprechend dem gewünschten AD- Eingang. Quasi: MUX = 1; wert1 = ADC; MUX = 2; wert2 = ADC; anzeigen(); Es kommt aber stets der gleiche Wert für beide Variablen dabei heraus!! Woran könnte das liegen?
Hi Programmiersprache? An welcher Stelle startest du den ADC und wartest auf das Ergebnis? MfG Spess
a: c b: ADSC (start convert) setze ich im Init, das Ergebnis hole ich mir später in der Schleife. Ich habe im Tutorial gelesen, dass ADSC vor dem ersten Muxen gesetzt werden soll, dennoch funktioniert es ja quasi auch so (ein bisschen). Ich kann mir vorstellen, dass ich vor jedem MUX- Wechsel bzw nach jedem Auslesen auch an den Status-Bits rumoperieren muss?!
Korrektur: Ich habe im Tutorial gelesen, dass ADSC > NACH < dem ersten Muxen gesetzt werden soll, dennoch funktioniert es ja quasi auch so (ein bisschen).
Hi
>Leider kann ich keinen Code posten,...
Wieso nicht? Sollen jetzt alle ihre Kristallkugeln putzen?
MfG Spess
Das kann ja nie schaden! Der Programmierrechner hängt nicht am Internet. Aber ich werds daheim versuchen..
Nach dem Ummuxen direkt eine Messung zu starten, geht meist daneben, da der MUX eine gewisse Zeit zum Umschalten braucht, im Bereich einiger hundert ns. Es kann nicht schaden, entweder nach dem Umschalten zu warten, oder aber den MUX direkt VOR dem Einlesen der vorherigen Messung umzuschalten. Das Einlesen geschieht entweder durch Interrupt oder per Polling des ADSC oder ADIF. Also nach Bestätigung des gültigen Ergebnisses wird erst umgemuxt, dann ADCL und ADCH eingelesen und weggespeichert und dann eine neue Messung gestartet. Das Einlesen verbraucht dann die Zeit, die der MUX zum Schalten benötigt. Alternativ kann man die Messungen auch immer mit einem festen Timerinterval starten, dann hat der MUX ewig genug Zeit.
Stephan R. schrieb: > Es kommt aber stets der gleiche Wert für beide Variablen dabei heraus!! > Woran könnte das liegen? Was hängt an den AD-Eingängen?
Wer lesen kann und diese Gabe nutzt, ist manchmal im Vorteil. Hier wieder ein Beweis. Datenblatt ATmega8: ------------------- However, the simplest method is to wait for the first conversion to complete, and then change the channel selection. Since the next conversion has already started automatically, the next result will reflect the previous channel selection. Subsequent conversions will reflect the new channel selection. Der ATmega8 macht also genau das, was im Datenblatt steht. - Das gefällt mir an den Dingern!
Es wird und wird nicht besser.. Ich frage mich, ob das START-CONVERT- Bit Einfluss auf die Messung hat. (Ich habe die INIT- Routine hier mit eingebaut.) int get_ad (int ch) { ADCSRA |= (1 << ADEN); // AD-Wandler enabled ADCSRA |= (0 << ADFR); // Free Running Mode aus ADMUX |= (1 << REFS0); // AVcc als Referenzspannung ADMUX |= (0 << REFS1); // ADMUX |= (0 << ADLAR); // Die 8 bit kommen in das Low-Register ADCSRA |= (1 << ADPS1); // Vorteiler ADCSRA |= (1 << ADPS0); // auf /8 ADCSRA |= (1 << ADSC); // convert an switch (ch) { case 0: ADMUX |= (0 << MUX0) | (0 << MUX1) | (0 << MUX2); break; case 1: ADMUX |= (1 << MUX0) | (0 << MUX1) | (0 << MUX2); break; case 2: ADMUX |= (0 << MUX0) | (1 << MUX1) | (0 << MUX2); break; } return ADC; }
|= ist was anderes als = Du meintest:
1 | case 0: ADMUX = (0 << MUX0) | (0 << MUX1) | (0 << MUX2); |
usw.
Edi R. schrieb: > |= ist was anderes als = > > Du meintest: case 0: ADMUX = (0 << MUX0) | (0 << MUX1) | (0 << MUX2); > usw. REfs dabei nicht vergessen. :-)
Stephan R. schrieb: > Löschen? Ich setzt doch bei jedem Switch eine neue Maske?! Nö. Mit "|=" werden Bits nur gesetzt. Gruß, Magnetus
Oha! Ein graues Wölkchen zieht auf! Heisst das, |= (0 << MUX0) rücksetzt das Bit nicht auf 0??
Hi Stephan, du machst in deinem Code 2 Fehler: 1. Du startest erst den ADC und setzt dann den Mux. Setzte deinen Switch-Block vor dem Initialisierungsblock. 2. Du wartest überhauüt nicht bis der ADC fertig ist. Sieh dazu die Anmerkungen von Travel Rec. weiter oben, oder schau mal ins AVR-GCC-Tutorial auf dieser Seite. Ein kleiner Tipp es reicht aus wenn du die ersten 7 Zeilen deines Initialisierungsblocks nur ein einziges Mal ausführst. Also einfach nur einmal vor deiner Hauptschleife in main().
Es läääääuft!! Es läuftesläuftesläuft!!!!! Init abgetrennt, Mux nach vorn geschoben, dem ganzen nen kleines Päuschen eingebaut und alles in Butter! Habt Dank!
Stephan R. schrieb: > Heisst das, > |= (0 << MUX0) > rücksetzt das Bit nicht auf 0?? Richtig. Zum gezielten zurücksetzen schreibt man z.B.: ADMUX &= ~((1<<MUX0)|(1<<MUX1)); Gruß, Magnetus
Denn ist dieser Code case 0: ADMUX = (0 << MUX0) | (0 << MUX1) | (0 << MUX2); wirkungslos??
Stephan R. schrieb: > case 0: ADMUX = (0 << MUX0) | (0 << MUX1) | (0 << MUX2); Er überschreibt dir halt deine gewünschte REFS einstellung, da diese auch im ADMUX register sind, mit 0.
Stephan R. schrieb: > Heisst das, > > |= (0 << MUX0) > > rücksetzt das Bit nicht auf 0?? Magnus Müller schrieb: > Richtig. Zum gezielten zurücksetzen schreibt man z.B.: > > ADMUX &= ~((1<<MUX0)|(1<<MUX1)); Stephan R. schrieb: > Denn ist dieser Code > > case 0: ADMUX = (0 << MUX0) | (0 << MUX1) | (0 << MUX2); > > > wirkungslos?? Magnus Müller schrieb: > Nö. Immerhin beschreibt er das Register mit dem Wert "0". Graue Wolke angekommen.
Hi
>dem ganzen nen kleines Päuschen eingebaut und alles in Butter!
Das Päuschen macht man mit:
while (ADCSRA & (1<<ADSC)
MfG Spess
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.