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


von seb (Gast)


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 !
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
}

von Gregor B. (gregor54321)


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.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der PinChange Interrupt sollte funktionieren, wenn er ordnungsgemäß 
eingerichtet ist.

von Mehmet K. (mkmk)


Lesenswert?

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

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Trotzdem sollten die Tasten funktionieren.

von Michael (Gast)


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?

von Edi (Gast)


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;

von Peter D. (peda)


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%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

von seb (Gast)


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 ?

von Edi (Gast)


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.

von Edi (Gast)


Lesenswert?

Kleiner Nachtrag: Das hab ich mir natürlich nicht aus den Fingern 
gesaugt, sondern von hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.