Forum: Mikrocontroller und Digitale Elektronik ADC liefert Maximalwert - warum?


von Mischi (Gast)


Lesenswert?

Hallo,

ich versuche gerade eine Spannung mit einem ATMEGA32 an PA0 mit dem ADC 
einzulesen.
Die Spannung variiert zwischen 0V und 5V.
AGND ist auf GND; AVCC auf VCC (5V); AREF mit 100nF gegen GND.

Im Debugger steht das ADC Data Register als auch die Variable bla immer 
am Maximum, trotz dass die Spannung an PA0 nachgemessen bei <1V ist.

Was mach ich falsch?

Beispielcode:
1
double bla;
2
int main()
3
{
4
  DDRA = 0x00;
5
  PORTA = 0x00;
6
  ADMUX = (1 << REFS0);
7
  ADCSRA = (1 << ADEN);
8
9
10
  while(1)
11
  {
12
    bla = ADC_conversion((1 << REFS0),10);
13
    _delay_ms(10);
14
  }
15
}
16
17
double ADC_conversion(unsigned char mux, unsigned char MW)  // Spannung messen (single ended)
18
{
19
ADMUX = mux;      // Multiplexer-Modus einstellen
20
_delay_us(40);      // Pause bis Multiplexer eingestellt ist
21
double Messwert = 0;
22
unsigned int ADC_temp;
23
unsigned char i = 1;
24
25
do
26
{
27
  ADCSRA |= (1<<ADSC);       // 'single conversion' einleiten
28
  while(!(ADCSRA & 0x10));   // auf ende der Wandlung warten, ADIF Flag '1'
29
  ADC_temp = ADCL;           // ADCL Register lesen
30
  ADC_temp += (ADCH << 8);   // ADCH Register lesen
31
  Messwert += ADC_temp;      // Ergebnisse der Messungen addieren
32
  i++;           // Schleifenzähler erhöhen
33
}
34
while (i <= MW);         // MW Messungen für bessere Genauigkeit
35
Messwert = Messwert/MW;       // Mittelwert der globalen Variable zuweisen
36
37
return (Messwert);
38
}

von Thomas E. (thomase)


Lesenswert?

Mischi schrieb:
> ADMUX = mux;      // Multiplexer-Modus einstellen
Autsch!
Damit überschreibst du diese Einstellung:
> ADMUX = (1 << REFS0);

ADMUX &= 0xF0;
ADMUX |= mux;

mfg.

von Mischi (Gast)


Lesenswert?

Hallo Thomas,

mein Aufruf in der main sieht so aus:
bla = ADC_conversion((1 << REFS0),10);

das Argument mux ist also (1 << REFS0), sollte also i.O. sein.
Beim Debuggen sieht man auch dass REFS0 gesetzt ist.

von Stefan E. (sternst)


Lesenswert?

ADIF wird gepollt, aber nicht zurückgesetzt.
Du pollst besser ADSC.

von Mischi (Gast)


Lesenswert?

Okay, ist umgestellt.

  while(ADCSRA & (1<<ADSC));   // auf ende der Wandlung warten

Leider immer noch Maximalwert im ADC Daten Register.
Alternativ hab ich auch andere Eingänge PA1, PA2, ... getestet, und auf 
GND gelegt. Wird trotzdem 0x3FF ins ADC Daten Register geschrieben.

Komisch, oder?

von Mischi (Gast)


Angehängte Dateien:

Lesenswert?

Anbei ein Screenshot der Register nach dem Wandeln.

von Mischi (Gast)


Lesenswert?

Problem gefunden, die Prescaler waren nicht hoch genug für den ext. 
Takt. Kleinerer Takt am ADC und schon gehts...

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.