Probleme mit ADC bei atmega 32

Gast #693402
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
}
#693410
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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren