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
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...
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...
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!
habt Ihr den AD-Wandler denn schon mal ohne das ganze Klimbim zum Laufen
bekommen?
Übrigens gute Teamarbeit, wenn zwei aus einer Gruppe (von 2?) das
Problem posten...
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!!
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.
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!!
stimmt... und wieder verdreht...
Ich hatte eben das gleiche Problem...
Es müsste/sollte aber "& E0" heissen, da das erste Bit des oberen
Nibble noch zur Adresse gehört...