www.mikrocontroller.net

Forum: GCC Watchdog First Time


Autor: Alex (Gast)
Datum:

Hallo zusammen

Ich hab vorhin einen Tipp bekommen, dass ich das Aufwecken meine
ATmega88 auch gut mit einem Watchdog lösen kann.

Ich hab mich jetzt mal ein bissl eingelesen und benutze jetzt die wdt.h!

Mein Programm-Code soll eigentlich nur den Watchdocg überprüfen.

Dieser wird auf 8s Prescaler eingestellt und soll wenn er in die ISR
springt eine Variable setzen, die anschließend im Hauptprogramm eine LED
für eine Sekunde leuchten lassen soll.

Davor soll der IC in den Power Down Mode gesetzt werden. Der Watchdog
sollte diesen ja eigentlich aufwecken.

Nun hier mal mein Programm-Code... das Problem ist, die LED leuchtet
nicht :(

// Hauptprogramm===================================================================================


int main(void)

{
  //initLDR();              // LDR initialiseren
  
  //ACSR = 0x80;            // AD ausschalten
  
  wdt_enable(WDTO_8S);

  sei();                // Interrupts aktivieren
    
  while(1)
  
  {  
        wdt_reset();
    
    OCR2B = 0;                       // Dummyzugriff
        while((ASSR & (1<< OCR2BUB)));   // Warte auf das Ende des Zugriffs
 
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_mode();                   // in den Schlafmodus wechseln

    if (GO==1)
    
    {            
      SET_BIT(DDRB, DDB2);            
      CLR_BIT(PORTB, PB2);    // LED einschalten, falls an

      _delay_ms(1000);
    }
  }      
}


//================================================================================================

//Watchdog Interrupt==============================================================================

ISR (WDT_vect)      // Interrupt Service Rountine Timer Overflow 2

{
  GO = 1;
  SET_BIT(DDRB, DDB2);
  SET_BIT(PORTB, PB2);    // LED ausschalten, falls an
}



Danke euch schonmal!
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Geht der AVR überhaupt in den Sleep Modus (Hinweis: Stromaufnahme
messen)?

Wenn nein, dann nachsehen, wie kommt das Programm über diese Stelle?
> while((ASSR & (1<< OCR2BUB)));   // Warte auf das Ende des Zugriffs

Und nachsehen, wie GO definiert ist (volatile?).
Autor: Alex (Gast)
Datum:

Ja GO hab ich als volatile definiert... richtig so oder?

aber stimmt ASSR hat gar keinen Bezug mehr... ist noch n Fragment eines
anderen Codes. Den Dummyzugriff und so habe ich aus dem AVR-GCC Tutorial
übernommen.

Also Stromverbrauch ist konstant bei 12mA... tut sich gar nichts. Hab
jetzt einfach mal die zwei zeilen OCR2B und ASSR rausgelöscht
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Für den Atmega8 habe ich gerade ein kleines Beispiel dazu geschrieben.
http://www.mikrocontroller.net/articles/Pollin_Fun...

Das ist auch für den Atmega89 übersetzbar und kann dir vielleicht die
Erleuchtung bringen. Ich selbst kann es aber nicht für den Atmega88
testen, weil ich keinen Atmega88 zur Hand habe.

Die Anzeige per LED habe ich auf PD5 gemacht. Die LED ist an PD5 so
angeschlossen:

PD5 o--------###-------->|--------o GND
        Vorwiderstand  LED
Autor: Alex (Gast)
Datum:

Wow echt super Sache was du da aufbaust ;)

Aber wo ist denn deine ISR?

Brauch man die nicht beim Watchdog? Die ISR (WDT_vect)?

Wo springt denn das Programm hin, wenn es aufgeweckt wird?
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Schau ich nach. Ich habe wohl noch einen Bug drin!
Autor: Alex (Gast)
Datum:

okay... für was braucht man aber dann die ISR (WDT_vect)?
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Alex schrieb:
> okay... für was braucht man aber dann die ISR (WDT_vect)?

Mit einer Watchdog-Interrupt ISR spart man sich den RESET.

Den Atmega8 habe ich schlecht gewählt, denn der hat keinen
Interruptvektor für den Watchdog, den ich auf eine eigene ISR umlenken
kann. Beim Atmega8 wird durch den Watchdog ein RESET ausgelöst. Man kann
die Resetursache dann abfragen (um andere Resetursachen
auszuschliessen). Das ändert aber nix daran, dass das Programm von vorne
neu gestartet wird und man in seinen Variablen und Programmabläufen
darauf Rücksicht nehmen muss. Diesen Neustart habe ich jetzt im Artikel
dokumentiert.

Ich muss mal suchen, ob ich einen AVR mit Watchdog-Interrupt habe und
den Artikel ergänzen kann. Vielleicht der Attiny2313?
Autor: Alex (Gast)
Datum:

Okay du meinst also, wenn der Watchdog auslöst, resettet das ganze
Programm oder wie? Und wenn man davor immer den Watchdog_Reset reinhaut,
tut er das nicht!

Ich hab gelesen, dass wenn der WD auslöst, dieser dann nach dem Sleep
Befehl einfach weiter macht... und wenn die while-Schleife durchgelaufen
ist, der sleep-befehlt ja wieder kommt und er schlafen geht.

und iwo hab ich noch gelesen, dass wenn der WD zuschlägt, ein Interrupt
ausgelöst wird und dieser interrupt dann so lange zeit hat abgearbeitet
zu werden, bis theoretisch ein neuer WD auslöst und diesmal entgültig
das system resettet ode rbist einfach der WD_Reset gesetzt wurde.

stimmt das in etwa?
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Ja, mit dem Attiny2313 kann man den Watchdog Interrupt so aufsetzen,
dass kein System Reset ausgeführt wird. Der Artikel ist entsprechend
ergänzt.
Und nicht wundern: Was beim Atmega88 WDT_vect heisst, heisst beim
Attiny2313 WDT_OVERFLOW_vect.
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Alex schrieb:
> Okay du meinst also, wenn der Watchdog auslöst, resettet das ganze
> Programm oder wie? Und wenn man davor immer den Watchdog_Reset reinhaut,
> tut er das nicht!

Ja bei dem Dino Atmega8 ist das so. Den Watchdog Reset hat man im
Sleep Modsu nicht zur Verfügung bzw. verlässt man sich ja gerade darauf,
dass der Watchdog auslöst.

Kein Reset ist beim Attiny2313 und beim Atmega88 (und anderen)
einstellbar, wenn die entsprechend konfiguriert werden.

> Ich hab gelesen, dass wenn der WD auslöst, dieser dann nach dem Sleep
> Befehl einfach weiter macht... und wenn die while-Schleife durchgelaufen
> ist, der sleep-befehlt ja wieder kommt und er schlafen geht.

Bei obigen "modernen" AVRs ist das möglich!

> und iwo hab ich noch gelesen, dass wenn der WD zuschlägt, ein Interrupt
> ausgelöst wird und dieser interrupt dann so lange zeit hat abgearbeitet
> zu werden, bis theoretisch ein neuer WD auslöst und diesmal entgültig
> das system resettet ode rbist einfach der WD_Reset gesetzt wurde.

Ja das ist in etwas richtig, wenn WDTCSR für den Interrupt and System
Reset Mode konfiguriert wurde, d.h. WDIE und WDE gesetzt sind.

Der erste anspringende Watchdog ruft die ISR auf und löscht das WDIE Bit
und der nächste führt zu einem System Reset, wenn zwischendurch vom
Programm das WDIE Bit nicht nochmal gesetzt wurde.

Diesen Fall habe ich noch nicht betrachtet; es könnte meine
Schlußbemerkung zum Umkonfigurieren im Artikel obsolet machen bzw. die
Umkonfiguration wesentlich erleichtern.
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Erledigt, Artikel ist umgeschrieben für den Modus Interrupt+System
Reset.
Autor: Alex (Gast)
Datum:

Hi :)

Kannst du vllt mal kurz drüberschauen, wenn du Zeit hast? Ist nun eine
etwas umgeschriebene Funktion, aber LED leuchtet immer noch nicht und er
scheint auch nicht schlafen zu gehen ;(

Vllt weißt du wo der Fehler liegt...
int main(void)

{
  WDTCSR |= 0x48;      // setzt WDIE und WDE für Interrupt and System Reset Mode

  wdt_enable(WDTO_4S);  // Watchdog auf 4Sekunden bis zum Auslösen

  sei();          // Interrupts aktivieren
    
  while(1)
  
  {  
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_mode();       // in den Schlafmodus wechseln

    WDTCSR |= (1<<WDIE);// WDT Interrupt Flag erneut setzen, damit kein Reset erfolgt

    if (GO==1)
    
    {            
      SET_BIT(DDRB, DDB2);            
      CLR_BIT(PORTB, PB2);    // LED einschalten

      _delay_ms(1000);

      GO=0;
    }
  }      
}


//================================================================================================

//Watchdog Interrupt==============================================================================

ISR (WDT_vect)      // Interrupt Service Rountine Timer Overflow 2

{
  GO=1;
  SET_BIT(DDRB, DDB2);
  SET_BIT(PORTB, PB2);    // LED ausschalten, falls an
}

Danke euch schonmal :)
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net