Hallo, folgende Situation habe ich. 1. Ich versetze meinen ATMEGA168 in den Standby-Mode. 2. Der MCU wacht durch den Watchdog-Interrupt auf. 3. In der ISR(WDT_vect) rufe ich eine Funktion read_adc() zur Spannungsmessung. Und die Werte der Messung stimmen nicht. Mit der gleichen Funktion read_adc() bekomme ich aber im Programm außerhalb der WDT-ISR richtige Messwerte. Kann jemand mir bitte helfen? Danke für Eure Antworten Lee
Der erste Wert ist fast immer falsch. Ansonstens wie geschrieben, alle Werte in der ISR stimmen nicht, eher zu niedrig. Denn ich will mit der Messung Spannungen auswerten. Wenn sie unter 11,7V liegen, sollen es piepsen. Aber im Interrupt piepst es immer noch bei Spannungen unter 11,95 V.
Der erste Wert ist immer falsch, da hier der ADC initialisiert wird. Warte den ersten Wert ab, verwirf ihn und lass den ADC noch einmal messen.
So sieht die Funktion read_adc aus:
1 | uint16_t read_adc(uint8_t adc_source) |
2 | {
|
3 | uint16_t adc_result; |
4 | uint8_t count; |
5 | cli(); // stoppe alle ISR |
6 | |
7 | |
8 | ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (0 << ADPS0); // 1MHz sysclk -> ADC-clk = 125 kHz |
9 | |
10 | // Referenzspannung
|
11 | ADMUX |= ADC_VREF_TYPE; // Internal 1.1V Voltage Reference with external capacitor at AREF pin |
12 | |
13 | // Quelle
|
14 | ADMUX |= adc_source; |
15 | |
16 | // ADC aktivieren
|
17 | ADCSRA |= (1 << ADEN); |
18 | |
19 | // AD-Umwandlung starten
|
20 | // dummy readout 5 mal!
|
21 | |
22 | for( count = 0; count < 5; count++ ) |
23 | {
|
24 | |
25 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
26 | |
27 | while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten |
28 | |
29 | adc_result = ADCW; |
30 | }
|
31 | |
32 | ADMUX = adc_source | ADC_VREF_TYPE; |
33 | |
34 | // Jetzt startet die eigentliche Messung
|
35 | adc_result = 0; |
36 | for( count = 0; count < 8; count++ ) |
37 | {
|
38 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
39 | while ( ADCSRA & (1<<ADSC) ) ; // auf Abschluss der Konvertierung warten |
40 | adc_result += ADCW; // Wandlungsergebnisse aufaddieren |
41 | }
|
42 | ADCSRA &= ~(1<<ADEN); // ADC deaktivieren |
43 | |
44 | adc_result = adc_result >> 3; |
45 | |
46 | sei(); // setzte alle ISR fort |
47 | return adc_result; |
48 | }
|
Ich habe
1 | ADMUX = adc_source | ADC_VREF_TYPE; |
einmal zu viel. Habe die Zeile gelöscht aber es ändert sich nicht an den Ergebnissen.
1 | ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (0 << ADPS0); // 1MHz sysclk -> ADC-clk = 125 kHz |
wird auf
1 | ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 1MHz sysclk -> ADC-clk = 125 kHz |
korrigiert, also Frequenzteilerfaktor = 8. Sorry, war mein Fehler beim Kopieren.
Ja, aber ich will es für mich ein bisschen deutlicher machen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.