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
Der ADC wird bei mir vor jeder einzelnen Messungen mit ADCSRA |= (1<<ADSC); neu gestartet!! was bedeutet denn AFR??
Die eigentliche Messung sieht wie folgt aus !! ADCSRA |= (1<<ADSC); while (!(ADCSRA & (1<<ADIF))); result += ADC; ADCSRA |= (1<<ADIF);
Das bringt auch nichts, man sieht doch nicht, was ud mit result weiter machst. Entweder die volle Quelle her, oder wird da keiner was verstehen.
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...
Ja, bei der Messung eines einzelnen Kanals funktioniert das ganz prima, auch bei diesem Programm funktioniert ja die erste Messung.
dann würde ich erst mal das Programm so umbauen, dass die 8 Messungen nacheinander durchgeführt werden...
Das haben wir auch gemacht, nur vier Messungen keine Schleife, kein nix. Wir erhalten dann vier richtige Werte !!
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!!
nicht unbedingt schneller: ADMUX = (ADMUX & 1F) | channel; zumindest würde ich sagen, dass es so gehen müsste...
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!!
Na ja, sorry, hab' wirklich uebersehen, was da Rahul geschrieben hat. Natuerlich soll es so sein: ADMUX = (ADMUX & F0) | channel;
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...
Noch Nachtrag: Wenn man nur die oberen 3 Bit (0xE0) ausmaskiert, ist es universeller einsetzbar...
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.