ADC-Werte falsch nur im Watchdog-Interrupt

Gast #1057820
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.