uc hängt nach watchdog isr

Gast #1472518
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 !
1
// global.h
2

3
uint8_t wdto_ctr;
4
#define WDT_timeout 20;
5

6
// system.c
7

8
ISR(WDT_vect)
9
{  
10
  wdto_ctr++;
11
  if (wdto_ctr >=  WDT_timeout)  // Timeout nach 20s
12
  {
13
    wdt_disable(); // Damit der Ausschaltvorgang nicht unterbrochen wird
14
    PWR_off();   // Schaltet das Gerät aus
15
  }
16

17
}
18

19
ISR(PCINT0_vect)  // wird nach tastendruck ausgeführt  
20
{
21
wdt_reset();
22
wdto_ctr=0;
23
}
24

25
// main.c
26

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

33
while(1)
34
{
35
// [..] ändere xyz in abhängigkeit von der tasteneingabe und zeige wert an
36
}
37
}
Gast #1472592
> 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;
#1472724
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%20Academy&func=viewItem&item_type=project&item_id=2265


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
Gast #1473232
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 ?
Gast #1473466
> 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.

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.