www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADMUX & Messkanal eintragen


Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du sollst ADC jedes Mal neu starten (ADCSRA |= (1<<ADSC);)

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder AFR aktivieren, das soll auch gehen

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der ADC wird bei mir vor jeder einzelnen Messungen mit
ADCSRA |= (1<<ADSC);
neu gestartet!!
was bedeutet denn AFR??

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die eigentliche Messung sieht wie folgt aus !!

 ADCSRA |= (1<<ADSC);
 while (!(ADCSRA & (1<<ADIF)));
 result += ADC;
 ADCSRA |= (1<<ADIF);

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Indiaca (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hast natürlich recht !! Hier im Anhang der Quelltext !!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, bei der Messung eines einzelnen Kanals funktioniert das ganz prima,
auch bei diesem Programm funktioniert ja die erste Messung.

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann würde ich erst mal das Programm so umbauen, dass die 8 Messungen
nacheinander durchgeführt werden...

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das haben wir auch gemacht, nur vier Messungen keine Schleife, kein nix.
Wir erhalten dann vier richtige Werte !!

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nicht unbedingt schneller:
ADMUX = (ADMUX & 1F) | channel;

zumindest würde ich sagen, dass es so gehen müsste...

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Indiaca (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ja, sorry, hab' wirklich uebersehen, was da Rahul geschrieben hat.
Natuerlich soll es so sein:
ADMUX = (ADMUX & F0) | channel;

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2Rahul:
Aber nur mit den neusten AVRs. 8 Kanaele brauchen ja nicht 5 bit

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich "bastel" momentan mit dem Mega64 rum...

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch Nachtrag:
Wenn man nur die oberen 3 Bit (0xE0) ausmaskiert, ist es universeller
einsetzbar...

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon richtig, das gebe ich zu, leider habe ich nicht viel mit den
maechtigsten AVRs zu tun gehabt

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.