Probleme mit AD Wandler am AT90CAN128

Gast #1512925
Lesenswert?

Morgen Forumsgemeinde,

ich habe ein Problem mit dem AD-Wandler an meinem AT90CAN128. Ich habe 
den Quellcode aus dem AVR-GCC Tutorial genommen und anversich nicht 
verändert, bis auf eine Abfrage welche Reversenzspannung genommen werden 
soll.

Hier kurz den Quellcode:
1
uint16_t ReadChannel(uint8_t mux, uint8_t referenz)
2
{
3
  uint8_t i;
4
  uint16_t result;
5

6
  ADMUX = mux;                      // Kanal waehlen
7

8
  if(referenz == 0)
9
    ADMUX |= (0<<REFS1) | (1<<REFS0) | (0 << ADLAR); //externe Referenzspannung(5V) nutzen
10
  if(referenz == 1)
11
    ADMUX |= (1<<REFS1) | (1<<REFS0) | (0<<ADLAR);  //interene Referenzspannung (2,56V) nutzen
12

13
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler
14
                               // setzen auf 128 (1) und ADC aktivieren (1)
15

16
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
17
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
18
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung
19
  while ( ADCSRA & (1<<ADSC) ) {
20
     ;     // auf Abschluss der Konvertierung warten
21
  }
22
  result = ADCW;  // ADCW muss einmal gelesen werden,
23
                  // sonst wird Ergebnis der nächsten Wandlung
24
                  // nicht übernommen.
25

26
  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
27
  result = 0;
28
  for( i=0; i<4; i++ )
29
  {
30
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
31
    while ( ADCSRA & (1<<ADSC) ) {
32
      ;   // auf Abschluss der Konvertierung warten
33
    }
34
    result += ADCW;        // Wandlungsergebnisse aufaddieren
35
  }
36
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
37

38
  result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
39

40
  return result;
41
}

Wie ihr seht frage ich vor dem beschreiben des ADMUX-Registers die 
Variable "referenz" ab um die gewünschte Referenzspannung in das 
Register zu programmieren.
In meiner while-Schleife in meiner Main-Funktion rufe ich direkt 3 mal 
hintereinander die "ReadChannel"-Funktion auf, um die Channel 0 bis 2 
wandeln zu lassen.
1
while(1)
2
{
3
     .
4
     .
5
     .
6

7
     ergebnis1 = ReadChannel(0, ad_wandler1[1]);
8
     ergebnis2 = ReadChannel(1, ad_wandler2[1]);
9
     ergebnis3 = ReadChannel(2, ad_wandler3[1]);
10
     
11
     .
12
     .
13
     .
14
}
Das funktioniert auch soweit nur wenn ich z.B. dem Channel 0 die 2,56 
Volt  interneReferenzspannung zuweise und den Channeln 1 und 2 die 5 
Volt externe Referenzspannung zuweise bekomme ich kein vernünfiges 
Ergebnis für die einzelnen Wandlungen.
Variable "result" vom Channel 0 hat bei einer Spannung von 1 Volt bei 
der intern Referenzspannung einen Wert von 265 sollte aber rechnerisch 
bei 400 liegen.
Variable "result" der Channel 1 und 2 hat einen Wert von 222 bei einer 
realen Referenzspannung von 4,6 Volt.

Wenn ich allen 3 Channeln die gleicher Referenzspannung zuweise, egal 
welche, passen alle 3 Ergebnise.

Hat jemand von euch eine Idee wo ich den Fehler habe? Kann vieleich der 
AD-Wandler nicht schnell genug seine Referenzspannung umschalten?

Ich dank euch allen wie immer für eure Hilfe.

Gruß
Stephan
Gast #1512931
Lesenswert?

Das Datenblatt sagt:

21.5 Changing Channel or Reference Selection
...
Note that the conversion starts on the following rising ADC clock edge 
after
ADSC is written. The user is thus advised not to write new channel or 
reference selection values
to ADMUX until one ADC clock cycle after ADSC is written.

Vielleicht solltest du nach dem Umschalten ein bisschen warten oder den 
ersten ausgelesenen Wert verwerfen...
#1513107
Lesenswert?

Ich vermute das ist ein elektrisches, kein Softwarepoblem.

Du schaltest zwischen interne Ref und AVCC als Ref um.
Beide Referenzspannungen werden mit dem Kondensator an AREF gepuffert.
-> Du musst warten, bis der Kondensator umgeladen wurde.
(21.5.2 im Datenblatt)

-> Kondensator kleiner machen oder Wartezeit nach dem Referenzwechsel 
erhöhen.

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