www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit ADC bei atmega 32


Autor: Gernot (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grüße,

Ich möchte über einen Bewegungsmelder eine Lampe einschalten. Dabei bin 
ich jetzt aber auf Probleme mit dem AD Wandler gestossen.
Mom schaut es so aus, das wenn ich das programm in den Flash speichere 
der µC nur den ersten erfassten Wert (nach der Dummy auswertung) richtig 
nimmt. Jeder Messwert danach ist in ungefähr gleich groß wie der erste.
Wenn ich aber irgendwo einen breakpoint reinnehme funktioniert die 
nächste Wandlung wieder richtig. Hat jemand eine Ahnung was der Grund 
für dieses seltsame Verhalten sein könnte?

Hier der code:
float AD_start (char Kanal)
{
  float ADWert= 0;
  int erfassterWert;

  ADMUX = (3<<REFS0); //2.56V intern
  ADMUX |= Kanal;
  ADCSRA = (1<<ADEN) | (6<<ADPS0); //64 prescaler

  ADCSRA |= (1<<ADSC); //dummy messung
  while (! (ADCSRA & (1<<ADIF)) ) {
      ;
  }
  ADCSRA |= (1<<ADIF);

  erfassterWert = ADCH;
  erfassterWert = erfassterWert << 8;
  erfassterWert = ADCL | erfassterWert;

  ADCSRA |= (1<<ADSC); // richtige messung
  while (! (ADCSRA & (1<<ADIF)) ) {
      ;
  }

  erfassterWert = ADCH;
  erfassterWert = erfassterWert << 8;
  erfassterWert = ADCL | erfassterWert;

  ADWert = (2.56 * erfassterWert ) / 1024;
  
  
  ADCSRA |= (1<<ADIF);
  ADCSRA &= ~(1<<ADEN);

  return ADWert;  
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> erfassterWert = ADCH;
> erfassterWert = erfassterWert << 8;
> erfassterWert = ADCL | erfassterWert;
Das ist beim Umgang mit dem ADC der Standard-Anfängerfehler. Es muss 
beim Auslesen der ADC-Datenregister unbedingt die Reihenfolge beachtet 
werden. Erst ADCL, dann ADCH. Beim Lesezugriff auf ADCL werden beide 
Register für einen Zugriff des ADC gesperrt, und zwar so lange, bis ADCH 
gelesen wurde. Da Du nach dem Lesen von ADCL das ADCH erst im nächsten 
Durchlauf wieder liest, der ADC aber in der Zwischenzeit keinen neuen 
Wert reinschreiben kann, kommt immer das selbe raus.

Allerdings ist es in C unsinnig, die beiden Register getrennt 
auszulesen. Jeder mir bekannte C-Compiler für AVRs bietet ein 
16-Bit-Register ADC oder ADCW an und nimmt Dir beim Zugriff die Sache 
mit der richtigen Reihenfolge ab, so dass Du Dir da keine Gedanken 
drüber machen musst.

Abgesehen davon solltest Du überlegen, ob Du wirklich Gleitkommazahlen 
brauchst, oder ob Festkommaarithmetik nicht besser ist...

Autor: Gernot (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort.
Damit funktioniert es.

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.