mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Träger AD- Wandler?


Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin!

Leider kann ich keinen Code posten, versuche aber, mein Anliegen 
ausreichend zu erklären:

Ich möchte nacheinander und immer wieder 2 AD- Eingänge des Atmega8 
abfragen (und erstmal per HTerm anzeigen).

Dazu führe ich eingangs eine Init durch und ändere anschließend für 
jeden Einlesevorgang das "Mux-Register" entsprechend dem gewünschten AD- 
Eingang.

Quasi:

MUX = 1;
wert1 = ADC;
MUX = 2;
wert2 = ADC;
anzeigen();

Es kommt aber stets der gleiche Wert für beide Variablen dabei heraus!!
Woran könnte das liegen?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Programmiersprache?

An welcher Stelle startest du den ADC und wartest auf das Ergebnis?

MfG Spess

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a: c

b: ADSC (start convert) setze ich im Init, das Ergebnis hole ich mir 
später in der Schleife.

Ich habe im Tutorial gelesen, dass ADSC vor dem ersten Muxen gesetzt 
werden soll, dennoch funktioniert es ja quasi auch so (ein bisschen).

Ich kann mir vorstellen, dass ich vor jedem MUX- Wechsel bzw nach jedem 
Auslesen auch an den Status-Bits rumoperieren muss?!

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur:

Ich habe im Tutorial gelesen, dass ADSC > NACH < dem ersten Muxen 
gesetzt
werden soll, dennoch funktioniert es ja quasi auch so (ein bisschen).

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Leider kann ich keinen Code posten,...

Wieso nicht? Sollen jetzt alle ihre Kristallkugeln putzen?

MfG Spess

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann ja nie schaden!

Der Programmierrechner hängt nicht am Internet. Aber ich werds daheim 
versuchen..

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach dem Ummuxen direkt eine Messung zu starten, geht meist daneben, da 
der MUX eine gewisse Zeit zum Umschalten braucht, im Bereich einiger 
hundert ns. Es kann nicht schaden, entweder nach dem Umschalten zu 
warten, oder aber den MUX direkt VOR dem Einlesen der vorherigen Messung 
umzuschalten. Das Einlesen geschieht entweder durch Interrupt oder per 
Polling des ADSC oder ADIF. Also nach Bestätigung des gültigen 
Ergebnisses wird erst umgemuxt, dann ADCL und ADCH eingelesen und 
weggespeichert und dann eine neue Messung gestartet. Das Einlesen 
verbraucht dann die Zeit, die der MUX zum Schalten benötigt. Alternativ 
kann man die Messungen auch immer mit einem festen Timerinterval 
starten, dann hat der MUX ewig genug Zeit.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R. schrieb:
> Es kommt aber stets der gleiche Wert für beide Variablen dabei heraus!!
> Woran könnte das liegen?

Was hängt an den AD-Eingängen?

Autor: Ralli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wer lesen kann und diese Gabe nutzt, ist manchmal im Vorteil.
Hier wieder ein Beweis.

Datenblatt ATmega8:
-------------------
However, the simplest method is to wait for the first conversion
to complete, and then change the channel selection. Since the next
conversion has already started automatically, the next result will
reflect the previous channel selection. Subsequent conversions will
reflect the new channel selection.

Der ATmega8 macht also genau das, was im Datenblatt steht.
- Das gefällt mir an den Dingern!

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wird und wird nicht besser.. Ich frage mich, ob das START-CONVERT- 
Bit Einfluss auf die Messung hat. (Ich habe die INIT- Routine hier mit 
eingebaut.)


int get_ad (int ch)
{
 ADCSRA |= (1 <<  ADEN);  // AD-Wandler enabled
 ADCSRA |= (0 <<  ADFR);  // Free Running Mode aus
 ADMUX  |= (1 << REFS0);  // AVcc als Referenzspannung
 ADMUX  |= (0 << REFS1);  //
 ADMUX  |= (0 << ADLAR);  // Die 8 bit kommen in das Low-Register
 ADCSRA |= (1 << ADPS1);  // Vorteiler
 ADCSRA |= (1 << ADPS0);  // auf /8
 ADCSRA |= (1 <<  ADSC);  // convert an

  switch (ch)
  {
    case 0:   ADMUX  |= (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2); 
break;
    case 1:   ADMUX  |= (1 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2); 
break;
    case 2:   ADMUX  |= (0 <<  MUX0) | (1 <<  MUX1) | (0 <<  MUX2); 
break;
   }
return ADC;
}

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo löscht du die mux-bits ausm ADMUX Register?

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Löschen? Ich setzt doch bei jedem Switch eine neue Maske?!





(nicht gut?)

Autor: Edi R. (edi_r)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
|= ist was anderes als =

Du meintest:
    case 0:   ADMUX  = (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2);
usw.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edi R. schrieb:
> |= ist was anderes als =
>
> Du meintest:    case 0:   ADMUX  = (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2);
> usw.

REfs dabei nicht vergessen. :-)

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R. schrieb:
> Löschen? Ich setzt doch bei jedem Switch eine neue Maske?!

Nö. Mit "|=" werden Bits nur gesetzt.

Gruß,
Magnetus

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oha! Ein graues Wölkchen zieht auf!

Heisst das,

|= (0 <<  MUX0)

rücksetzt das Bit nicht auf 0??

Autor: AVR-Frickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Stephan,

du machst in deinem Code 2 Fehler:

1. Du startest erst den ADC und setzt dann den Mux. Setzte deinen 
Switch-Block vor dem Initialisierungsblock.

2. Du wartest überhauüt nicht bis der ADC fertig ist. Sieh dazu die 
Anmerkungen von Travel Rec. weiter oben, oder schau mal ins 
AVR-GCC-Tutorial auf dieser Seite.

Ein kleiner Tipp es reicht aus wenn du die ersten 7 Zeilen deines 
Initialisierungsblocks nur ein einziges Mal ausführst. Also einfach nur 
einmal vor deiner Hauptschleife in main().

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es läääääuft!! Es läuftesläuftesläuft!!!!!
Init abgetrennt, Mux nach vorn geschoben, dem ganzen nen kleines 
Päuschen eingebaut und alles in Butter!

Habt Dank!

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R. schrieb:
> Heisst das,
> |= (0 <<  MUX0)
> rücksetzt das Bit nicht auf 0??

Richtig. Zum gezielten zurücksetzen schreibt man z.B.:

ADMUX &= ~((1<<MUX0)|(1<<MUX1));

Gruß,
Magnetus

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder man schreibt fürs obere Programm einfach:

ADMUX = (1<<REFS0)|(ch);
:-)

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Denn ist dieser Code

case 0:   ADMUX  = (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2);


wirkungslos??

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö. Immerhin beschreibt er das Register mit dem Wert "0".

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R. schrieb:
> case 0:   ADMUX  = (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2);

Er überschreibt dir halt deine gewünschte REFS einstellung, da diese 
auch im ADMUX register sind, mit 0.

Autor: Stephan R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan R. schrieb:
> Heisst das,
>
> |= (0 <<  MUX0)
>
> rücksetzt das Bit nicht auf 0??

Magnus Müller schrieb:
> Richtig. Zum gezielten zurücksetzen schreibt man z.B.:
>
> ADMUX &= ~((1<<MUX0)|(1<<MUX1));

Stephan R. schrieb:
> Denn ist dieser Code
>
> case 0:   ADMUX  = (0 <<  MUX0) | (0 <<  MUX1) | (0 <<  MUX2);
>
>
> wirkungslos??

Magnus Müller schrieb:
> Nö. Immerhin beschreibt er das Register mit dem Wert "0".



Graue Wolke angekommen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>dem ganzen nen kleines Päuschen eingebaut und alles in Butter!

Das Päuschen macht man mit:

 while (ADCSRA & (1<<ADSC)

MfG Spess

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.