ADC beim atmega32 liefert 0

OP #781671
Lesenswert?

Hallo zusammen,

leider habe ich ein Problem beim Auslesen des ADC mit meinem mega32:
Der returnwert von read_sensor ist immer null, egal, was am Port 
anliegt.

- Spannung direkt am Pin überprüft, liegt was an
- unterschiedliche Spannungen ausprobiert
- porta0 - porta7 durchprobiert
- Nur lesen von ADCH ausprobiert
- Takt 10 MHz

Code habe ich angehängt:
1
extern void init_sensor()
2
{  
3

4
  // adc freischalten
5
  ADCSRA = (1 << ADEN);
6

7

8
  // Frequenzteilerverhältnis auf 1/128
9
  ADCSRA |= (1 << ADPS2) | (1 << ADPS1) |  (1 << ADPS0);
10

11

12
  /* Kanal einstellen */
13
  ADMUX = SENSOR;             // SENSOR == 7
14

15
  
16
  /* Interne Referenzspannung 2.56 V */
17
  ADMUX |= (1 << REFS1) | (1 << REFS0);
18

19

20
}
21

22

23
extern uint16_t read_sensor()
24
{  
25
  uint16_t  result;
26

27

28

29
  
30
  init_sensor();
31

32
  // Messung anstoßen  
33
  ADCSRA = (1 << ADSC);
34

35

36
  // warten, bis Messung komplett
37
  while (ADCSRA & (1 << ADSC)) ;
38

39

40
  result = ADCL;
41
  result += (ADCH << 8);
42

43

44
  return result;
45

46
}

Tja, ich hoffe, jemanden von Euch ist das Problem bekannt, ich
weiss langsam wirklich nichte mehr weiter ... (adc kaputt??)
OP #781716
Lesenswert?

Ahhhh! Himmel! Stimmt, danke.

Bloss die schlechte Nachricht, es geht immer noch nicht.
Ich habs auch schonmal im freilaufenden Betrieb probiert, das war dann 
das gleiche ...

Inzwischen hab ich mir auch noch einen zweiten µC (baugleich) 
ausgeliehen, bei dem gehts auch nicht, also wird der ADC wohl nicht 
defekt sein ...
#781724
Lesenswert?

> result = ADCL;
> result += (ADCH << 8);
Mach das nicht von Hand. Der Compiler kennt dafür ein 16-Bit-Register 
(ADC oder ADCW), das Du ohne großes Trara direkt in die entsprechende 
Variable übernehmen kannst, ohne dass Du Dich auch noch um die 
Zugriffsreihenfolge kümmern musst (die hier aber zufällig stimmt)...
OP #781728
Lesenswert?

OK, danke für den Tipp, mag auch schönen Code :)

Ich hab jetzt bloss grad die lezten 2 Stunden zwischen Datenblatt, den 
zwei Tutorials und anderen Codefetzen hin&hergewurschtelt und so war ich 
mir sicher, dass in der Variablen wenigstens IRGENDWAS steht, wenns 
funktioniert ...
#781729
Lesenswert?

Das hier:
1
result += (ADCH << 8);
... klappt zwar in diesem Fall, weil Du Glück hast, dass es die Integer 
Promotion gibt. Aber grundsätzlich sollte man einen Wert, bevor man ihn 
über seinen eigenen Wertebereich hinaus verschiebt, auf den Zieldatentyp 
erweitern. Würde der Compiler nämlich nicht automatisch das auf der 
rechten Seite vom "=" nach int erweitern, käme immer 0 raus. Also besser 
auf Nummer sicher und
1
result += ((uint16_t) ADCH) << 8;
(abgesehen von oben gesagtem, nur als zusätzlicher Tipp).

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