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