ADC-Werte falsch nur im Watchdog-Interrupt

Gast #1057820
Lesenswert?

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
Gast #1057836
Lesenswert?

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.
Gast #1057845
Lesenswert?

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
}
Gast #1057852
Lesenswert?

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.

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