Forum: Mikrocontroller und Digitale Elektronik ATMega1284 - ADC bringt falsche Werte


von Tim W. (timw)


Lesenswert?

Hallo zusammen!
Ich benutze einen ATMega1284, welcher auf einem fertigen Board sitzt 
(kommt von der Uni, daher denke ich, dass Aufbaufehler ausgeschlossen 
sind. Diese Boards sind nämlich schon seit Jahren im Betrieb).

Meine Schaltung ist folgendermaßen: Es handelt sich um eine 1/2-Aktive 
Brückenschaltung mit zwei Pt-1000 Widerständen (unten links; oben 
rechts) sowie zwei 1k Widerständen (oben links; unten rechts).

Mit meinem Programm messe ich zunächst die Spannung im linken 
Brückenzweig zwischen den Widerständen und dann im rechten Brückenzweig 
zwischen den Widerständen.

Mit dem Multimeter messe ich links 2,66V und rechts 2,37V (immer gegen 
Masse). Soweit so gut.

Ich verwende weitestgehende die ADC-Routine aus dem Tutorial:
1
void adc_Init(void)
2
{  
3
  ADMUX |= (1<<REFS0);                  //Referenz auf AVCC - jeweiligen Kanal später "vor Ort", also in der jeweiligen Funktion auswählen!!!
4
  ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);            // Frequenzvorteiler
5
  
6
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
7
 
8
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
9
    also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
10
 
11
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
12
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung warten
13
  }
14
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
15
    Wandlung nicht übernommen. */
16
  (void) ADCW;
17
}
Habe hier nur den Prescaler auf 128 gesetzt, weil der Controller mit 
16MHz läuft.

1
uint16_t adc_read(uint8_t channel)
2
{
3
  // Kanal waehlen, ohne andere Bits zu beeinflussen
4
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
5
  ADCSRA |= (1<<ADSC);                  //neuen ADC-Wert lesen
6
  while (!(ADCSRA & (1<<ADSC)))
7
  {
8
  }
9
  //fertige ADC-Werte stehen nun in ADCL und ADCH. daran denken, dass immer zuerst ADCL und dann ADCH gelesen wird!
10
  return ADCW;                    // ADC auslesen und zurückgeben
11
}
1
uint16_t bruecke_links()
2
{
3
  uint16_t intern_adc_wert_l;
4
  intern_adc_wert_l = adc_read(0);
5
  UART_PutChar('c');
6
  UART_PutChar(intern_adc_wert_l >> 8);    //highbyte
7
  UART_PutChar(intern_adc_wert_l);      //lowbyte
8
  return intern_adc_wert_l;
9
}
10
11
uint16_t bruecke_rechts()
12
{
13
  uint16_t intern_adc_wert_r;
14
  intern_adc_wert_r = adc_read(1);
15
  UART_PutChar('d');
16
  UART_PutChar(intern_adc_wert_r >> 8);    //highbyte  
17
  UART_PutChar(intern_adc_wert_r);      //lowbyte
18
  return intern_adc_wert_r;
19
}

Mit diesen beiden Funktionen schaue ich mir dann nacheinander die 
ADC-Werte an und gebe sie über den UART raus. (Ich rufe die in einer ISR 
alle 5 Sekunden auf, damit ich nicht komplett zugespammt werde ;-) )
Im HTerm kommen dann für beide Seiten die gleichen Werte raus, was ja 
schonmal nicht sein kann (Werte: 554).

Das nächste Ding ist: Wenn ich einen der beiden ADC-Eingänge in die Luft 
hänge oder z.B. auf Plus oder Minus lege ändert sich der Wert nicht. Ist 
für mich auch ziemlich unverständlich.


Kann mir eventuell jemand sagen, was ich falsch mache?

Vielen Dank schonmal im Voraus!

MfG
Tim

von Tim W. (timw)


Lesenswert?

Problem selbst gelöst:
1
uint16_t adc_read(uint8_t channel)
2
{
3
  // Kanal waehlen, ohne andere Bits zu beeinflussen
4
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
5
  ADCSRA |= (1<<ADSC);                  //neuen ADC-Wert lesen
6
  while (!(ADCSRA & (1<<ADSC)))
7
  {
8
  }
9
  //fertige ADC-Werte stehen nun in ADCL und ADCH. daran denken, dass immer zuerst ADCL und dann ADCH gelesen wird!
10
  return ADCW;                    // ADC auslesen und zurückgeben
11
}

Das Ausrufezeichen in der while-Schleife muss natürlich weg.

Danke trotzdem an die, die den Beitrag gelesen haben

MfG
Tim

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.