www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit ADC beim AVR


Autor: zalk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Ich versuche gerade eine Spannung über einem LDR über den ADC 
auszulesen. Leider funktioniert das immer nur am Anfang (kurz nach dem 
Anlegen der Betrebsspannung) nach ein paar Messungen kommen plötzlich 
nur noch Werte die keinen Sinn ergeben.
Die Messung ist nicht zeitkritisch, Messung erfolgt nur alle paar 
Sekunden und läuft mit langsamster Geschwindigkeit. Ob Single Modus oder 
Free Running macht keinen Unterschied.

Controller: ATMega32
Referenzspannung: intern 2,56 V, Aref mit 100n auf Masse
sonstige Bertiebsspannungen über Kondensator und Spule entkoppelt

Ich hoffe da hat jmd noch eine Idee...


Danke

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal auf einen Softwarefehler tippen...

Autor: ecslowhand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du auch mal die Spannung am ADC-Eingang gemessen ?

Autor: zalk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Spannung am Pin ist so, wie sie sein sollte. Das heißt der Fehler 
liegt im Mikrocontroller.
Ich werde dann morgen mal etwas Code posten...

Autor: zalk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, wie versprochen der Code:

while(1)
{
  //ADC Messung
  sbi(ADCSRA, ADSC);   //Messung starten
  while (ADCSRA & 0x40) {}

  hold_ADCL = ADCL;         //Messwerte abspeichern
  hold_ADCH = ADCH;

  while ( !( UCSRA & (1<<UDRE)) ) {} //Messergebnis an PC senden
  UART_send(hold_ADCH, hold_ADCL);

  //hier irgendwas tun

  //und nochmal messen
  //ADC Messung
  sbi(ADCSRA, ADSC);   //Messung starten
  while (ADCSRA & 0x40) {}

  hold_ADCL = ADCL;         //Messwerte abspeichern
  hold_ADCH = ADCH;

  while ( !( UCSRA & (1<<UDRE)) ) {} //Messergebnis an PC senden
  UART_send(hold_ADCH, hold_ADCL);

  //hier irgendwas anderes tun
}


Wie gesagt, die Spannung am Eingang ist korrekt, nur die AD-Wandlung im 
µC funktioniert nicht richtig. Manchmal(!) klappt es wenn man 2 mal 
direkt hintereinander wandelt. Dann ist der 2. Wert korrekt.

Die Initialisierung des ADC:

sbi(ADCSRA, ADEN);    //ADC einschalten
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);

sbi(ADMUX, REFS1);    //A1 als Eingang, zu Vref intern 2,56 V
sbi(ADMUX, REFS0);

und evtl noch:
//free running mode
sbi(ADCSRA, ADATE);
sbi(ADCSRA, ADSC);

aber ob free-running oder single conversion macht keinen Unterschied.

Gruß

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuche mal die Wandlung so zu starten:
ADCSRA |= (1<<ADSC);       // 'single conversion' einleiten
while(!(ADCSRA & 0x10));   // auf ende der Wandlung warten, ADIF flag '1'
und erst danach ADCL und dann ADCH einzulesen.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, immer daran denken mindestens 40µs nach Umschalten des MUX und 
120µs nach Umschschalten der Betriebsart (single-ended <=> 
differentiell) abzuwarten.

Autor: zalk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich hab das jetzt nochmal im Single Modus getestet mit den 2 Zeilen 
Code von Sonic:

ADCSRA |= (1<<ADSC);       // 'single conversion' einleiten
while(!(ADCSRA & 0x10));   // auf ende der Wandlung warten, ADIF flag 
'1'

Aber das hilft auch nicht.
Deshalb erläutere ich mal die Anwendung genauer:
Am ADC-Pin können 2 verschiedene Spannungen angelegt werden. Der 
Ablaufplan in der Endlosschleife sieht so aus:

1) Spannung 1 anlegen
2) Diese Spannung mit dem ADC messen
3) Spannung 2 anlegen
4) Diese Spannung mit dem ADC messen

Das heißt am Ende sollte ich abwechselnd den Wert der Spannung 1 und der 
Spannung 2 erhalten. In Wirklichkeit klappt das ganze nur im ersten 
Durchgang, ab dann gibt der ADC IMMER nur noch einen der beiden Werte 
zurück.

Und nochmal: Das ganze ist völlig zeitunkritisch. Zwischen dem Anlegen 
und dem Samplen sind mehrere Sekunden Pause.

Gruß

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Woran merkst du, dass es nicht geht?

Wie schnell läuft der µC?
 - der ADC-takt soll zwischen 50kHz und 200kHz liegen, bei 10Bit 
Auflösung, du hast 128 als Prescaler gewählt (ADCPS0:2 alle gesetzt), 
d.h. dein µC "muss" mindestens 6.4MHz schnell sein damit der ADC richtig 
funktioniert.

Autor: zalk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Er läuft mit 11,xxx MHz.

Dass es nicht funktioniert, merke ich daran, dass der ADC immer den 
gleichen Wert liefert, obwohl die Spannung an seinem Pin sich ändert!?

Lässt man ihn einen Spannungswert 2x samplen, dann stimmt der 2. der 
beiden Werte.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> sbi(ADMUX, REFS1);    //A1 als Eingang, zu Vref intern 2,56 V
> sbi(ADMUX, REFS0);
Wenn "A1" "PORTA.1" sein soll, dann stimmt die Multiplexer-Konfiguration 
nicht. So wie es hier eingestellt ist, ist PORTA.0 als Eingang 
konfiguriert. Check mal, ob wirklich der korrekte Pin angeschlossen ist.

Und ob Du das Ende der Wandlung durch Abfrage von ADIF oder von ADSC 
ermittelst, sollte gehopst wie gesprungen sein.

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- stimmt jedes Mal nur die zweite Messung, oder stimmt nur die _erste 
überhaupt_ nicht ?
- liegt das Prob. vl. woanders ?(s. johnny.m)
- wie sieht eigentlich die funktion "UART_send()" aus? sendet die 
korrekt zwei chars nach einander?
also ungefähr vom Typ: "void UART_send(char erstes, char zweites)"
geht

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.