AD Wandler auf dem ATmega48

Gast #4015763
Lesenswert?

Hi ich habe ein Problem mit meinem ADWandler mit meinem ATmega48. Ich 
möchte 2 Kanäle auslesen und zwar 0 und 1 diese habe ich probehalber 
einmal mit VCC und den anderen mit GND beschaltet. Doch egal was ich 
mache ich bekomme für beide Werte immer die selbe Ausgabe, wenn ich mir 
den Wert über die Serielle Schnittstelle ausgeben lasse.

Ich hoffe ihr habt eine Idee wo mein Problem liegt. Ich bin total 
überfragt.

Hier habt ihr meine Register Konfiguration und die entsprechenden 
Funktionen und ein paar Eckdaten.

VCC = 5V
F_CPU = 1MHz interner Takt
1
void adcInit(){
2

3
  ADMUX = 0;
4
  
5
  DIDR0 |= (1 << ADC0D) | (1 << ADC1D);
6
  
7
  //ADC ist freigeschaltet, automatisch getriggert, interrupt ist enabled und prescaler ist bei 8 also 125kHz -> 104µs pro Wandlung
8
  ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS1) | (1 << ADPS0);
9
  ADCSRB = 0;
10
  
11
}
12

13
void adcChannel(uint8_t c){
14
  if(channel >= 0 && channel <= 7){
15
    //wähle den Channel aus aber lasse linksbündige einstellung drin 64 setzt ADLAR und die channel Variable die MUX Bits
16
    ADMUX = channel;
17
  }
18
}
19

20
ISR(ADC_vect){  
21
  uint8_t valueHigh = ADCH;
22
  uint8_t valueLow = ADCL;
23
  uint16_t value = valueLow + (valueHigh << 8);
24
  
25
  
26
  uartPutS("Channel ");
27
  uartPutC(channel + 48);
28
  uartPutS(" = ");
29
  uartPutC(value/1000 + 48);  //1000er Stelle
30
  uartPutC(value%1000/100 + 48);  //100er Stelle
31
  uartPutC(value%100/10 + 48);  //10er Stelle
32
  uartPutC(value%10 + 48);  //1er Stelle
33
  uartPutC('\n');
34
  //*/
35
  
36
  if(channel == 1){
37
    channel = 0;
38
  }else{
39
    channel = 1;        
40
  }
41
  
42
  adcChannel(channel);
43
  
44
  ADCSRA |= (1 << ADSC);
45
}

Die Ausgabe im Terminal:

Channel 1 = 0450<\n>
Channel 0 = 0450<\n>

Ich hoffe ihr könnt mir weiterhelfen :) Danke für eure Aufmerksamkeit.

charly
#4015876
Lesenswert?

charly schrieb:
> Also wenn ich den Kanal wechsel dann, bleibt es bei einem Wert um die
> 400 +- 10
>
> VCC und AVcc sind beide direkt an 5V angeschlossen.

das ist erst mal egal. Denn weder Vcc noch AVcc werden benutzt. So wie 
du ADMUX eingestellt hast, wird die SPannung an AREF als 
Referenzspannung benutzt und nichts anderes.

> Keine Kondensatoren.

Kein Kommentar (zumindest jetzt noch nicht)

> Und ich habe noch einen 1k Widerstand zwischen Klemme und dem mega48 das
> hätte ich noch erwähnen sollen.

Zwischen welcher Klemme und welchem Anschluss des Mega48?
Gast #4015917
Lesenswert?

Karl Heinz schrieb:
>> Und ich habe noch einen 1k Widerstand zwischen Klemme und dem mega48 das
>> hätte ich noch erwähnen sollen.
>
> Zwischen welcher Klemme und welchem Anschluss des Mega48?

zwischen dem Anschlusspin des Controllers und der Klemme an der später 
das Poti dran ist, welches zwischen VCC und GND geschaltet ist.

Karl Heinz schrieb:
> das ist erst mal egal. Denn weder Vcc noch AVcc werden benutzt. So wie
> du ADMUX eingestellt hast, wird die SPannung an AREF als
> Referenzspannung benutzt und nichts anderes.

AREF ist ebenfalls auf 5V geschaltet.
#4016028
Lesenswert?

charly schrieb:
> uint8_t valueHigh = ADCH;
>   uint8_t valueLow = ADCL;
>   uint16_t value = valueLow + (valueHigh << 8);

ADCL muss vor ADCH ausgelesen werden!

Also überlass das dem Compiler, anstatt dir selbst etwas falsches 
zusammen zu basteln:

1
uint16_t value = ADC;

Die UART-Ausgaben in der ISR zu kommentieren, erspare ich mir jetzt.

mfg.
#4016655
Lesenswert?

Können wir uns darauf einigen, mal ein ganz simples Testprogramm ohne 
Interrupt und sonstigen Schnickschnack, nur mit den Tutorial Routinen zu 
schreiben?
1
...
2
hier die Routinen aus dem Tutorial, wobei du die Referenzspannung so einstellst, wie du das brauchst.
3
...
4

5
int main()
6
{
7
  uint16_t adcval;
8

9
  ADC_Init();
10

11
... was immer du noch für die UART benötigst
12
...
13
 
14
  while( 1 ) {
15

16
    adcval = ADC_Read(0);  // Kanal 0
17

18
    sprintf( uart_buff, "ADC 0: %u\n", adcval );
19
    uartPutS( uart_buff );
20
  }
21
}

Dann variierst du mal die Spannung am ADC Eingang 0 (mit Voltmeter 
kontrollieren) und siehst nach, was die ausgegebenen Werte machen.

Wenn sich die wie erwartet verhalten, dann kommt das nächste 
Testprogramm
1
...
2
  while( 1 ) {
3

4
    adcval = ADC_Read(0);
5

6
    sprintf( uart_buff, "ADC 0: %u\n", adcval );
7
    uartPutS( uart_buff );
8

9
    adcval = ADC_Read(1);
10

11
    sprintf( uart_buff, "ADC 1: %u\n", adcval );
12
    uartPutS( uart_buff );
13
  }
Gast #4017325
Lesenswert?

charly schrieb:
> Karl Heinz schrieb:
>>> Und ich habe noch einen 1k Widerstand zwischen Klemme und dem mega48 das
>>> hätte ich noch erwähnen sollen.
>>
>> Zwischen welcher Klemme und welchem Anschluss des Mega48?
>
> zwischen dem Anschlusspin des Controllers und der Klemme an der später
> das Poti dran ist, welches zwischen VCC und GND geschaltet ist.

Jetzt ist Zeit für einen Schaltplan.

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