Forum: Mikrocontroller und Digitale Elektronik AVR: 6-Kanal ADC Geschwindigkeit ausreizen


von Jens (Gast)


Lesenswert?

Hallo,

auf einem mega8 möchte ich kontinuierlich nacheinander alle 6 AD 
Eingänge einlesen. Randbedingungen sind: das Sampling muss in 
gleichmässigen Zeitabständen erfolgen, und es muss so schnell wie 
möglich sein.
Abgesehen von der passenden analogen Beschaltung und der Wahl eines für 
die geforderte Genauigkeit passenden ADC-Prescalers dürfte der 
Freerunning Mode meine Forderungen erfüllen.
Der ADC IRQ wird aufgerufen, sobald ein neues Messergebnis vorliegt. Da 
beim Sprung in die ISR bereits die nächste Conversion läuft, bezieht 
sich das in der ISR abgeholte Ergebnis immer auf den vorhergehenden 
Kanal. In der ISR schalte ich dann jeweils den MUX auf den nächsten 
Kanal um (wobei der AVR ja erst mit Beginn der nächsten Conversion auf 
diesen Kanal umschaltet). Soweit klar (hoffe ich ;-)

Problem ist leider, dass der ADC sporadisch falsche Werte liefert, die 
völlig daneben liegen. Sie spiegeln weder den Wert des gewünschten 
Kanals wieder, noch irgend eines anderen Kanals. Häufig kommt der Wert 
192 (1100000). Auf meinem System laufen nebenher auch noch andere 
Interrupts, deren Laufzeit aber weit unterhalb der ADC-Abtastrate liegt. 
Es kann also nicht passieren, dass das Auslesen eines Kanals 
übersprungen wird.

Im Datenblatt finde ich unter dem Punkt "Changing Channel or Reference 
Selection" einen möglichen Hinweis, den ich aber leider nicht kapiere. 
Ich habs unten angehängt. Insbesondere Punkt 2 ist mir nicht klar. Muss 
ich im interruptgetriebenen free running mode immer 1 ADC clock cycle 
warten, bevor ich den MUX umschalten darf? Ich habe die ISR testhalber 
mit NOPs vollgekleistert um 1 ADC cycle zu warten, das half aber auch 
nicht.

Habt Ihr Ideen?
Danke Jens


If both ADFR and ADEN is written to one, an interrupt event can occur at 
any time. If the ADMUX Register is changed in this period, the user 
cannot tell if the next conversion is based on the old or the new 
settings. ADMUX can be safely updated in the following ways:
1. When ADFR or ADEN is cleared.
2. During conversion, minimum one ADC clock cycle after the trigger 
event.
3. After a conversion, before the Interrupt Flag used as trigger source 
is cleared.
When updating ADMUX in one of these conditions, the new settings will 
affect the next ADC conversion

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jens wrote:

> ... Muss
> ich im interruptgetriebenen free running mode immer 1 ADC clock cycle
> warten, bevor ich den MUX umschalten darf?

Ja, allerdings geht die Interrupt-Latenz da noch mit ein.

Eine wirkliche Idee kann ich dir leider auch nicht bieten.

von Benedikt K. (benedikt)


Lesenswert?

Geht mir ähnlich. Ohne Code kann man auch nur wild drauf los raten.
Ich würde auf irgendeinen versteckten Fehler wie einem Interrupt 
zwischen dem Zugriff auf eine 16bit Variable oder ähnliches tippen.

von Oliver (Gast)


Lesenswert?

Das Datenblatt ist da mal wieder etwas undeutlich. Ich verstehe das so:

>2. During conversion, minimum one ADC clock cycle after the trigger
>event.

bezieht sich, wie im Single-Run-Modus, nur auf die allererste Wandlung, 
weil die nicht sofort startet, sondern eben erst auf der nächsten 
ADC-Clock-Flanke. Ändert man das MUX-Register auf den nächsten Kanal, 
bevor die Wandlung tatsächlich gestartet ist, hat das noch Einfluß auf 
die erste Wandlung.
Im free-run-modus wird allerdings jede weitere Wandlung sofort 
gestartet. Da düfte dann nichts mehr schiefgehen.

>If both ADFR and ADEN is written to one, an interrupt event can occur at
>any time.
ist insofern nicht korrekt, als das eine Wandlung 13 ADC-Takte dauert, 
und damit der Interrupt nicht "any time", sondern genau alle 13 
ADC-Takte auftritt. "any time" ist das nur, wenn man nicht weiß, wann 
der ADC gestartet wurde.

Und selbst wenn beim Muxen etwas schief gehen sollte, dürfen ja keine 
völlig unsinningen Werte kommen, sondern dann würden die Werte des 
vorherigen oder nächsten Kanals gelesen.

Oliver

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
Noch kein Account? Hier anmelden.