Forum: Mikrocontroller und Digitale Elektronik ATMega32 ADC hängt


von Robert S. (socketa)


Lesenswert?

Hallo,
Beim Umstieg vom Easy-Mode Arduino auf avr-gcc bin ich auf ein Problem 
beim ADC lesen gestossen. Es scheint als wueder der ADC haengen bleiben.

Die erste Wandlung nach einem Reset ist korrekt, aber alle weiteren 
geben immer den selben Wert zurück wenn man den Eingang verändert.
Nach einem Reset wird wieder einmal richtig gewandelt, und dann hängts.

Ist auf einem ATMEGA32 der mit 16MHz betrieben wird. AVCC ist auf VCC 
(+5V), Kondensator von AREF auf GND. Um AVCC als Referenz zu nutzen muss 
laut Datenblatt REFS0 auf 1 sein und REFS1 auf 0.

Mein ADC Code sieht wie folgt aus:
1
void main(){
2
    ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADEN); //prescaler 128 
3
    ADMUX = (1<<REFS0); //AVCC, channel 0
4
    _delay_ms(10);      //nicht notwendig 
5
    while(1){
6
      ADCSRA |= (1<<ADSC); 
7
      while(!(ADCSRA & (1<<ADIF)));
8
      UARTSend(ADCH);
9
      UARTSend(ADCL);
10
      ADCSRA |= (1<<ADIF); //Interruptflag loeschen
11
      _delay_ms(500);      
12
   }
13
}

Soweit ich das richtig verstanden habe wird ADIF gesetzt wenn die 
Wandlung abgeschlossen ist bzw. neue Daten in ADCH/L sind. Man loescht 
es wieder indem man es auf 1 setzt. Der ADC sollte dann wieder eine neue 
Wandlung nach dem Setzen von ADSC durchfuehren koennen.

Ich nehme an dass ich etwas grundsaetzlich falsch verstanden habe und 
bin sehr dankbar ueber jeden Hinweis dazu was das wohl sein koennte.

von Spess53 (Gast)


Lesenswert?

Hi

Vergiss ADIF und teste, ob ADSC wieder zurückgesetzt wird. Dann ist der 
ADC fertig.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

>       UARTSend(ADCH);
>      UARTSend(ADCL);

Beim Auslesen von 16-Bit Pseudo-Register:
Erst das Low-Register, dann das High-Register. Die Reihenfolge ist NICHT 
egal.

von Spess53 (Gast)


Lesenswert?

Hi

Nachtrag: Beim Lesen erst Das L-Register und danach das H-Register.

MfG Spess

von Cyblord -. (cyblord)


Lesenswert?

> When ADCL is read, the ADC Data Register is not updated until ADCH is
> read. Consequently, if
> the result is left adjusted and no more than 8-bit precision is required,
> it is sufficient to read
> ADCH. Otherwise, ADCL must be read first, then ADCH.

Also erst ADCL lesen!

Oder gleich:
1
uint16_t x=ADC;
Damit liest du direkt in eine 16 Bit Variable und musst dich nicht mehr 
drum kümmern.

von Robert S. (socketa)


Lesenswert?

MEINE GUETE, wie peinlich.
Vielen Dank, die falsche Reihenfolge beim Registerlesen wars.
"When ADCL is read the ADC register is not updated until ADCH is read" - 
Laut Doku.

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.