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