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


von Gernot (Gast)


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:
1
float AD_start (char Kanal)
2
{
3
  float ADWert= 0;
4
  int erfassterWert;
5
6
  ADMUX = (3<<REFS0); //2.56V intern
7
  ADMUX |= Kanal;
8
  ADCSRA = (1<<ADEN) | (6<<ADPS0); //64 prescaler
9
10
  ADCSRA |= (1<<ADSC); //dummy messung
11
  while (! (ADCSRA & (1<<ADIF)) ) {
12
      ;
13
  }
14
  ADCSRA |= (1<<ADIF);
15
16
  erfassterWert = ADCH;
17
  erfassterWert = erfassterWert << 8;
18
  erfassterWert = ADCL | erfassterWert;
19
20
  ADCSRA |= (1<<ADSC); // richtige messung
21
  while (! (ADCSRA & (1<<ADIF)) ) {
22
      ;
23
  }
24
25
  erfassterWert = ADCH;
26
  erfassterWert = erfassterWert << 8;
27
  erfassterWert = ADCL | erfassterWert;
28
29
  ADWert = (2.56 * erfassterWert ) / 1024;
30
  
31
  
32
  ADCSRA |= (1<<ADIF);
33
  ADCSRA &= ~(1<<ADEN);
34
35
  return ADWert;  
36
}

von Johannes M. (johnny-m)


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...

von Gernot (Gast)


Lesenswert?

Danke für die Antwort.
Damit funktioniert es.

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.