mikrocontroller.net

Forum: Compiler & IDEs ATmega2560 - ADC 8 ... 16 funktionieren nicht


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Wer kann mir bei folgendem Problem helfen: Mit einem ATmega2560 will ich 
16 Analog-Digital-Konverter-Kanäle nutzen. Mit der unten gezeigten 
Funktion AnalogPort funktioniert das bei den Kanälen 0 bis 7 sehr gut 
(Spannungsmessung korrekt für U=0 bis 4800 mV). Wenn ich allerdings die 
Kanäle 8 bis 15 benutzen will, liefert die Funktion einem stark 
verrauschten Wert, der sich bei Spannungen zwischen 0 und 4.8 V zwischen 
3 und 4.8 V bewegt (also nur schwach von der Spannung abhängt).

Das Verhalten ist identisch auf zwei verschiedenen Prozessoren, die sich 
auf ihrer jeweils eigenen Platine befinden.

Die Zuordnung des Wertes channel auf die Register ADMUX und ADCSRB habe 
ich an Tabelle 129, Seite 295 des Prozessormanuals angepasst.

Der Compiler ist der von WinAVR. Programmer ist AVRDude und 
STK200-Dongle.
Hier noch die C-Schnipsel:

----------------------------------

Initialisierung:

DDRF = 0b00000000;    // Port F Pins (ADC1) all input
DDRK = 0b00000000;    // Port K Pins (ADC2) all input
PCMSK2 = 0b00000000;    // PCINT23:16=0 (Pin Change INTerrupt disabled)

----------------------------------
Funktion zum Auslesen des ADC mit channel=0...15:

float AnalogPort(char channel)
{
ADMUX = 0b01000000 | (channel & 0b00000111);
ADCSRA = 0b11000001;    // Bit 7: Enable ADC
        // Bit 6: Start Conversion
        // Bits 2,1,0: Teilerverhältnis von 32 (Original 101)
        // => 131.072 kHz bei 4 MHz Prozessortakt
        // (muss zwischen 50 kHz und 200 kHz liegen)

ADCSRB = channel & 0b00001000;  // Bit ACME=0: kein Comparatorbetrieb
                                // Bit MUX5 auf Channel-Bit 3

// wait until end of AD-Conversion
while ((ADCSRA & 0b01000000) == 0b01000000);

// get result
return (ADC*0.0047222*1000);  // Faktor zur Kalibrierung in mV
}

-----------------------------------
Fuse-Bits:
LFUSE = 0b11111101
HFUSE = 0b11011001
EFuse = 0b11111111

Autor: Florian Demski (code-wiz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ADMUX = 0b01000000 | (channel & 0b00000111);

Da fehlt eine 1 in der rechten Mask. MUX hat 4 Bits und nicht 3.

ADMUX = 0b01000000 | (channel & 0b00001111);

--- das sollte helfen.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das behebt das Problem leider nicht. Ich habe es eben ausprobiert.

Laut Datenblatt hat MUX übrigens 6 Bits: MUX4...MUX0 im Register ADMUX 
und MUX5 im Register ADCSRB. Laut Tabelle 129, Seite 296 muss man für 
"Single Ended Input" (also keinen differenziellen ADC) an Kanal 8

MUX5:0 = 0b100000

setzen. Nach deinem Beispiel würde ich 0b101000 nehmen.

Autor: Branko Golubovic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Markus,

 >ADCSRB = channel & 0b00001000;  // Bit ACME=0: kein Comparatorbetrieb
 >                               // Bit MUX5 auf Channel-Bit 3

Mit dieser Zeile bei Channel Wechsel bleibt Bit3 immer gesetzt.

Zuerst Bit 3 immer Löschen.

ADCSRB&=~0b00001000 ;

Und erst nach bedarf Setzen.

ADCSRB|=0b00001000 ;

Außerdem,
>// wait until end of AD-Conversion
>while ((ADCSRA & 0b01000000) == 0b01000000);

kannst du auch so schreiben:
while (ADCSRA & 0b01000000);

Gruß Branko

Autor: Branko Golubovic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und erst nach bedarf Setzen.
>ADCSRB|=0b00001000 ;

Richtig ist:
ADCSRB|= channel & 0b00001000 ;

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Branko,

Auch damit wird das Problem nicht gelöst.

 >ADCSRB = channel & 0b00001000;  // Bit ACME=0: kein Comparatorbetrieb
 >                               // Bit MUX5 auf Channel-Bit 3

> Mit dieser Zeile bei Channel Wechsel bleibt Bit3 immer gesetzt.

Dies ist eine bitweise UND-Verknüpfung, d. h. wenn channel von 8 auf 7 
wechselt, wird Bit3 (MUX5) auch wieder zurückgesetzt.

Ich habe dies zum Anlass genommen, mir die Werte von ADMUX, ADCSRA und 
ADCSRB mit den Messwerten und der Kanalnummer auf einem LC-Display nach 
der Wandlung ausgeben zu lassen. Alle Werte sind so, wie sie in obiger 
Routine gesetzt werden. Überrascht hatte mich zuerst nur, dass nach 
erfolgreicher Wandlung noch ADIF in ADCSRA automatisch gesetzt wurde 
(dies konnte ich aber inzwischen im Handbuch nachlesen).

Ich hoffe immer noch, dass jemand die zündende Idee oder Erfahrung zu 
diesem Problem hat. Könnte es irgendwie mit einer alternativen Funktion 
des Port K zu tun haben? Gehe ich recht in der Annahme, dass ADC0...ADC7 
an Port F und ADC8...ADC15 an Port K anliegen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus wrote:

> Gehe ich recht in der Annahme, dass ADC0...ADC7
> an Port F und ADC8...ADC15 an Port K anliegen?

So sagt es zumindest das Pinout im Datenblatt.

Als alternate functions werden lediglich der ADC und die pin-change
interrupts genannt.

Autor: Brako Golubovic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Markus,

Das Problem ist dass MUX-Bits auf 2 Register aufgeteilt ist ud du
folgende Fehler gemacht hast:
>ADMUX = 0b01000000 | (channel & 0b00000111);
OK. MUX 0 bis 2 sind ausgewählt.
>ADCSRA = 0b11000001;    // Bit 7: Enable ADC
>       // Bit 6: Start Conversion
>       // Bits 2,1,0: Teilerverhältnis von 32 (Original 101)
>       // => 131.072 kHz bei 4 MHz Prozessortakt
>       // (muss zwischen 50 kHz und 200 kHz liegen)
OK. Start Conversion

>ADCSRB = channel & 0b00001000;  // Bit ACME=0: kein Comparatorbetrieb
                                // Bit MUX5 auf Channel-Bit 3
Zu spät, Du hast Konversion schon gestartet!

Richtig ist zuerst ALLE MUX-Bits richtig einstellen und DANN Konversion
starten:
ADMUX = 0b01000000 | (channel & 0b00000111);
ADCSRB = channel & 0b00001000;
ADCSRA = 0b11000001;    // Bit 7: Enable ADC
      // Bit 6: Start Conversion


Branko

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Branko!

Genau das wars! Es war mir eben selbst aufgefallen und ich wollte genau 
dies hier posten. Die Lösung ist nur die Vertauschung der Zeilen mit den 
Zuweisungen für ADCSRA und ADCSRB.

Gratulation für diese Fehleranalyse aus der Ferne!

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.