ADMUX & Messkanal eintragen

Gast #283142
Lesenswert?

Hallo,

ich habe folgendes Problem:

In meinem Programm möchte ich in einer Schleife Spannungen an
verschiedenen Kanälen messen (ADC 0 bis ADC 7). In meiner Messroutine
wird der ADC wie folgt initiallisiert:

 ADCSRA = (1<<ADEN) | (1<< ADPS2) | (1<< ADPS1);
// ADC aktivieren und Frequenzvorteiler auf 64 einstellen
 ADMUX = ADMUX | channel;
// AN channel (0x00 bis 0x07) liegt die zumessende Spannung an
 ADMUX |= (1<<REFS1) | (1<<REFS0);
// interne Referenzspannung nutzen

Nun variiere ich channel durch eine Schleife. Dies packe ich dann unter
anderem in die Mainschleife!
Nun entsteht dabei folgendes Problem: Beim ersten Durchlauf macht der
ADC alles richtig ich bekomme meine Spannungen korrekt angezeigt
(UART), aber ab dem zweiten Durchlauf wird bei jeder Messung immer nur
die letzte Spannung ausgegeben.
Ich vermute es liegt an ADMUX, irgendwie gelingt es mir nicht ihn nach
der Messung wieder in den Ursprungszustand zurückzusetzen.

Ich hoffe mir kann jemand helfen, der das Problem kennt und/oder auch
schon hatte.

Danke
         Indiaca
Gast #283148
Lesenswert?

Indem du ADMUX |= channel machst, setzt du IMHO irgendwann alle
Adress-Bits des Multiplexers.

Sicherer wäre es so: ADMUX = (ADMUX & 0x1F) | channel;

Dann ist es ja auch so, dass der ADC seine Messung zuende führt, und
dann erst den Kanal wechselt. Vielleicht liegt es ja daran...
Gast #283150
Lesenswert?

interessanter Weise benutzt du als Schleifenindex "i" ein uint_8
(8bit) und als Endwert "mittel" ein uint_16. Da würde ich mich auch
auf eine "Sorte" festlegen (uint_16 i).
Dann hast du "return result/=mittel" geschrieben. Wieso weist du
result das noch zu? "return result/mittel" würde völlig reichen
(result ist ne lokale Variable)...

Und irgendwie habe ich das Programm diese Woche schon in einem anderen
Thread gelesen...
Gast #283151
Lesenswert?

Ja, okay, da hast du recht, aber diese beiden Dinge sind doch nur
Schönheitsfehler, hab ich geändert, aber funktioniert dadurch nicht
besser, trotzdem danke.
Und ja, ein alter Thread existiert schon, mein Platzgegüber John hat es
wohl auch schon probiert :) Wir arbeiten zusammen an einer Steuerung für
eine Solarmessung an Tandemzellen!
Gast #283156
Lesenswert?

Es funktioniert, ist zwar sehr unelegant, aber es geht!!
habe vor der Mainschleife den gesamten ADMUX-Grundzustand gespeichert

a=ADMUX;

und stelle vor jeder Messung diesen Grundzustand wieder her!!

ADMUX=a;

wenn es hierzu jedoch noch schönere Lösungen gibt, bin ich dafür sehr
dankbar!!
Gast #283158
Lesenswert?

1. Ist auch klar, wieso es so aussah:
ADMUX = ADMUX | channel;
Nach der vierten Messung aendert sich gar nichts mehr (0x11 | irgenwas
macht 0x11).
Da hilft wirklich
ADMUX = (ADMUX & 1F) | channel;
2. Ich wuerde trotzdem mit den Variablen vorsichtiger umgehen. Man
braucht ja kaum long int, wenn es hervorragend mit char geht.
Bei diesem ICC AVR weiss man nie, wie es rumgeht.
Gast #283159
Lesenswert?

Mit den Variablen hast du wohl recht ich sollte da etwas mehr drauf
achten, was dort wie und mit wieviel Speicherverbrauch abgelegt wird.
Aber mit

ADMUX = (ADMUX & 1F) | channel;

hat es auch nicht geklappt, das habe ich ja probiert, wie oben schon
von dir beschrieben!!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren