mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik uc hängt nach watchdog isr


Autor: seb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

ums kurz zu machen: Ich habe ein batteriebetriebenes gerät welches sich 
automatisch ausschalten soll sobald längere Zeit kein Taster mehr 
gedrückt wurde. Dazu benutze ich den auf 1s programmierten watchdog. In 
der ISR des WD habe ich eine Funktion implementiert welche mir das gerät 
ausschaltet. Dies funktioniert einwandfrei.
Da das jedoch erst nach 20s passieren soll wird jedes mal wenn er 
aufwacht eine variable inkrementiert. Hat sie den Wert 20 (sekunden) 
erreicht soll sich das gerät ausschalten.
Problem: Nachdem das Ende der ISR erreicht wurde hängt sich der 
controller auf. Zumindest reagiert das Gerät auf keinerlei Tastendruck 
mehr (Das Display zeigt den jeweiligen letzten wert an)

Hat jemand evtl. sowas ähnliches programmiert und kennt sich aus ??
Danke schonmal !

// global.h

uint8_t wdto_ctr;
#define WDT_timeout 20;

// system.c

ISR(WDT_vect)
{  
  wdto_ctr++;
  if (wdto_ctr >=  WDT_timeout)  // Timeout nach 20s
  {
    wdt_disable(); // Damit der Ausschaltvorgang nicht unterbrochen wird
    PWR_off();   // Schaltet das Gerät aus
  }

}

ISR(PCINT0_vect)  // wird nach tastendruck ausgeführt  
{
wdt_reset();
wdto_ctr=0;
}

// main.c

main
{
wdt_enable(WDTO_1S);  // Enable WDT
WDTCSR |=(1<<WDIE);  // Enable Interrupt on WD Timeout
wdto_ctr=0;             // Init Timeout counter

while(1)
{
// [..] ändere xyz in abhängigkeit von der tasteneingabe und zeige wert an
}
}


Autor: Gregor B. (gregor54321)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deiner PWR_off() steht sowas wie
    SleepMode(Power_Down);
Dann geht wecken nur noch mit über einen INT-Eingang.
Schau mal ins Datenblatt unter SleepModes. Gibts immer ne hübsche 
Tabelle am Ende des Kapitels.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der PinChange Interrupt sollte funktionieren, wenn er ordnungsgemäß 
eingerichtet ist.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Watchdog Interrupt muss das WDIE bit wieder gesetzt werden, ansonsten 
wird danach dieser Interrupt nicht mehr angesprungen.
Also noch die Zeile
WDTCSR |= (1<<WDIE);
einfügen.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotzdem sollten die Tasten funktionieren.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir so spontan auffällt: Wo wird denn beim Watchdog-Interupt der 
Watchdog resetet/abgeschaltet wenns nicht in die If-Schleife rein geht?

Autor: Edi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> uint8_t wdto_ctr;

Globale Variablen, die sowohl in der ISR als auch in der main() 
verwendet werden, sollten mit volatile deklariert werden:

volatile uint8_t wdto_ctr;

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
seb schrieb:
> Hat jemand evtl. sowas ähnliches programmiert und kennt sich aus ??

Ja.
Allerdings nicht über den Umweg Watchdoginterrupt, sondern direkt über 
den allgemeinen  Timerinterrupt, den wohl jede Applikation hat und der 
auch das Tastenentprellen macht.

Funktioniert super:

http://www.avrfreaks.net/index.php?module=Freaks%2...


Da das Main im Idle-Mode ist (10ms je Loop), zähle ich dort auch das 
Timeout.
Aber wenn man noch andere Interrupts benutzt, sollte man es direkt im 
Timerinterrupt zählen.


Peter

Autor: seb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits,

erstmal danke für die vielen Antworten.

An Mehmet Kendi: Vielen Dank für den Tipp mit dem enabeln des 
Interrupts, jetzt funktionierts einwandfrei.

An Edi: Warum sollten globale variablen mit volatile deklariert werden ?

Autor: Edi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> An Edi: Warum sollten globale variablen mit volatile deklariert werden ?

Wenn eine Variable mit "volatile" deklariert worden ist, dann optimiert 
der Compiler die Variable nicht als Register, sondern verwendet eine 
"echte" RAM-Speicherstelle dafür.

Das bedeutet: Bei einer volatile-Variable rechnet der Compiler immer 
damit, dass der Inhalt der Variablen irgendwo anders (also z. B. in 
einer ISR) verändert werden kann.

Autor: Edi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleiner Nachtrag: Das hab ich mir natürlich nicht aus den Fingern 
gesaugt, sondern von hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.