Forum: Mikrocontroller und Digitale Elektronik ADC am ATMeha644p geht nicht


von Ralf (Gast)


Lesenswert?

Ich bekomme den ADC an meinem ATMega644p nicht zum laufen. Hier mein 
Code:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include "uart.h"      
4
5
#define F_CPU 16000000L
6
7
void main(void)
8
{
9
//init UART
10
  uinit();
11
  //ADC aktiv, ADC starten, Freerunning mode, Prescaler = 128
12
  //ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (1<<ADPS0 ) | (1<<ADPS1) | (1<<ADPS2); 
13
  ADCSRA=(1<<ADSC)|(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
14
  //ADC auf Pin 1
15
  ADMUX = 0x01;
16
  //interne 2.56 Volt Ref., 
17
  ADMUX = (1<<REFS1) | (1<<REFS1);
18
    uint16_t x;
19
  char text[4];
20
    while(1)
21
    {
22
    x = ADCL;
23
    x += (ADCH<<8);
24
    itoa(x, text, 10);
25
    uputs(text);
26
    uputs("\n\r");
27
    }
28
}

Ich verwenden ein STK500. An den Pin PA1 habe ich ein Poti als 
Spannungsteiler geschaltet. Egal was ich dort einstelle, über die 
serielle Schnittstelle wird immer nur 1023 ausgegeben.

von Hubert G. (hubertg)


Lesenswert?

Mit dem ADMUX = (1<<REFS1) | (1<<REFS1);
stellt du den ADC wieder auf 0.

von Εrnst B. (ernst)


Lesenswert?

Nach dem Start der Conversion (ADSC-Bit) musst du warten, bis die 
Wandlung fertig ist.
Ausserdem:
Natürlich ZUERST den Mux-Input+Referenz auswählen, DANN den Wandler 
starten.

von Ralf (Gast)


Lesenswert?

Danke. Bei dieser Reihenfolge ändert sich leider auch nichts.
1
  //ADC auf Pin 1
2
  ADMUX = 0x01;
3
  //interne 2.56 Volt Ref., 
4
  ADMUX = (1<<REFS1) | (1<<REFS1);
5
  //ADC aktiv, ADC starten, Freerunning mode, Prescaler = 128
6
  //ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (1<<ADPS0 ) | (1<<ADPS1) | (1<<ADPS2); 
7
  ADCSRA=(1<<ADSC)|(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);

@Hubert:
> Mit dem ADMUX = (1<<REFS1) | (1<<REFS1);
> stellt du den ADC wieder auf 0.

Aber so stelle ich doch auf interne Ref.spannung um, oder?

@Ernst:
wenn es "nur" am warten liegt, sollten doch nur die ersten Werte falsch 
sein. Es wird aber dauern 1023 ausgegeben.

von Justus S. (jussa)


Lesenswert?

Ralf wrote:

>
> Aber so stelle ich doch auf interne Ref.spannung um, oder?
>

und den Kanal auf 0

von Ralf (Gast)


Lesenswert?

Meinst Du so:
1
  //interne 2.56 Volt Ref., 
2
  ADMUX = (1<<REFS1) | (1<<REFS1);
3
  //ADC auf Pin 1
4
  ADMUX = (1<<MUX0);
5
  //ADC aktiv, ADC starten, Freerunning mode, Prescaler = 128
6
  ADCSRA=(1<<ADSC)|(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
kommt aber noch immer 1023 raus...:-(

von Justus S. (jussa)


Lesenswert?

Ralf wrote:
> Meinst Du so:

nein...

jetzt stellst du wieder auf ext. Referenz um UND wählst Kanal0 (MUX0) 
um...

von Johannes M. (johnny-m)


Lesenswert?

Klartext: Mit der zweiten Zuweisung an ADMUX überschreibst Du den Wert 
von der ersten Zuweisung! Ist das so schwer zu verstehen?

Schau Dir mal den Artikel Bitmanipulation genauer an...

von Ralf (Gast)


Lesenswert?

das wäre dann so, oder?:
{c]
  //interne 2.56 Volt Ref., ADC auf Pin 1
  ADMUX = (1<<REFS1) | (1<<REFS1) | (1<<MUX0);
  //ADC aktiv, ADC starten, Freerunning mode, Prescaler = 128
  ADCSRA=(1<<ADSC)|(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
[/c]
immer noch 1023...

von Johannes M. (johnny-m)


Lesenswert?

Vielleicht mal dran denken, dass man erstmal warten sollte, bis der ADC 
mit seiner Wandlung fertig ist, bevor man das Ergebnis ausliest. Steht 
alles im AVR-GCC-Tutorial inkl. Codebeispielen...

von Hubert G. (hubertg)


Lesenswert?

Entweder du schreibst  ADMUX = (1<<REFS1) | (1<<REFS1) | (1<<MUX1);
oder ADMUX |= (1<<MUX1);
ADC erst abfragen wenn ADIF gesetzt ist, ansonst ist der Wert 
undefiniert oder alt.

von Ralf (Gast)


Lesenswert?

> du schreibst  ADMUX = (1<<REFS1) | (1<<REFS1) | (1<<MUX1);
Sollte das nicht MUX0 am Ende sein wenn ich Pin1 abfragen will?
Egal, es bringt beides nur 1023.

> ADC erst abfragen wenn ADIF gesetzt ist, ansonst ist der Wert
undefiniert oder alt.

Ich wollte den Code auf ein absolutes Minimum beschränken um den Fehler 
zu finden / zu verstehen.

Wenn der Wert alt oder undef. ist, müste ja mal was anderes als 1923 
rauskommen. Darum denke ich, dass ich noch was anderes falsch mache.

von Justus S. (jussa)


Lesenswert?

Ralf wrote:
>> du schreibst  ADMUX = (1<<REFS1) | (1<<REFS1) | (1<<MUX1);
> Sollte das nicht MUX0 am Ende sein wenn ich Pin1 abfragen will?

was den nun, Pin 1 oder A1

hast du denn überhaupt mal nachgemessen, was an dem Pin anliegt?

von Hubert G. (hubertg)


Lesenswert?

Du hast in deinem ersten Beitrag geschrieben PA1, das ist MUX1.

von Ralf (Gast)


Lesenswert?

> was den nun, Pin 1 oder A1
PA1, nach Datenblatt ist das ADC1.


> hast du denn überhaupt mal nachgemessen,
> was an dem Pin anliegt?

Ja, habe ich. Eine Spannung die ich mit einem Poti von 0V bis 4,9V 
verändere ohne dass sich mein "gemessener" Wert ändert.

Sorry für die vielleicht dummen Fragen und danke für die Gedult ;-)

von Ralf (Gast)


Lesenswert?

> Du hast in deinem ersten Beitrag
> geschrieben PA1, das ist MUX1.

ist das nicht so:

MUX2 MUX1 MUX0
0    0    0    = PA0
0    0    1    = PA1
0    1    0    = PA2
usw.?

von Hubert G. (hubertg)


Lesenswert?

Ja, richtig, war mein Fehler.

von Ralf (Gast)


Lesenswert?

Auf dem STK500 steckte der Jumper AREF noch. Wenn ich ihn entferne geht 
es. Ich dachte mit dem Umschalten auf interne Referenzspannung:
1
ADMUX = (1<<REFS1) | (1<<REFS1)

wäre der Jumper bedutungslos.

Danke an alle und sorry, dass ich das mit dem Jumper nicht eher abgklärt 
habe.

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.