Forum: Mikrocontroller und Digitale Elektronik AVR: Watchdog löst keinen Interrupt aus


von StefanK (stefanka)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich glaube, mein Watchdog muss mal in die Hundeschule und ein bisschen 
nachsitzen. Er löst keinen Interrupt aus, obwohl (1<<WDIE) und sei().

Ich versuche meinem Arduino Uno R3 mit ATmega328P beizubringen, die LED 
nur dann ein- oder auszuschalten, wenn eine gewisse Anzahl WD-Timeouts 
erreicht ist. Zwischen den WD-Timeouts soll der uC im Power-down-Modus 
schlafen (macht er) und beim WD-Timeout wieder aufwachen. Wacht er aber 
nicht. Die Hauptschleife wird genau einmal durchlaufen. Danach liegt der 
uC im Koma.

Warum bellt der faule Hund nicht? Hat jemand einen Tipp?

von S. L. (sldt)


Lesenswert?

Auf die Schnelle (und ohne Garantie, ist schon länger her): bei mir lief 
(in Assembler)
1
 puti  WDTCSR,(1<<WDE)+(1<<WDCE)
2
 puti  WDTCSR,(0<<WDE)+(1<<WDIE)+(1<<WDP3)  ; 4 s, Interrupt-Mode

von Rolf (rolf22)


Lesenswert?

StefanK schrieb:
> Warum bellt der faule Hund nicht? Hat jemand einen Tipp?

Zeig den Code.

von StefanK (stefanka)


Lesenswert?

Sieht bei mir so aus. Eigentlich dasselbe, nur, dass ich noch WDIE 
setze, in der Hoffnung, dass der WD-Timeout auch einen Interrupt 
auslöst. Nur warum nicht?
WDTCSR |=  (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDIE) | (1<<WDCE) | (0<<WDE) | (1<<WDP2) | (1<<WDP1);

von StefanK (stefanka)


Lesenswert?

Rolf schrieb:
> Zeig den Code.
Habe ihn oben angehängt.

von S. L. (sldt)


Lesenswert?

> Eigentlich dasselbe

Und wenn Sie, dauert ja nur 30", meine Version einfach ausprobieren?

von StefanK (stefanka)


Lesenswert?

StefanK schrieb:
> WDTCSR |=  (1<<WDCE) | (1<<WDE);
> WDTCSR = (1<<WDIE) | (1<<WDCE) | (0<<WDE) | (1<<WDP2) | (1<<WDP1);

Korrektur:
...nur, dass ich noch WDCE  setze...

Beitrag #7999432 wurde vom Autor gelöscht.
von StefanK (stefanka)


Lesenswert?

S. L. schrieb:
> Und wenn Sie, dauert ja nur 30", meine Version einfach ausprobieren?

Mache ich, bin nur gerade nicht am richtigen PC.

von Oliver S. (oliverso)


Lesenswert?

Da wird wohl das erforderliche Timing nicht eingehalten werden. Dafür 
gibts passende Macros in der avrlibc, die das sicherstellen.

https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

Oliver

von Rolf (rolf22)


Lesenswert?

Was auf jeden Fall nicht ok ist:
-- wdt_ticks muss volatile sein

-- Es ist nicht gut, in der Hauptschleife wdt_ticks als Zählerstand 
abzufragen.
Besser: In der ISR einen bool setzen, wenn es soweit ist, und den in der 
Hauptschleife abfragen. Der Vergleich ==0 kann auch mal schief gehen.

Ansonsten: Die seriellen while-Sachen vorübergehend rauswerfen, um 
sicher zu sein, dass es da keine Endlosschleifen gibt.
Und: Die LED in die ISR einbauen, damit man sicher sehen kann, ob die 
ISR durchlaufen wird.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

StefanK schrieb:
> Warum bellt der faule Hund nicht?

Deine wdt ticks sollten atomar abgehandelt werden.
Auch eine Memory Barrier kann wunder bewirken..

Tipp:
Verwende die Atomic Makros aus atomic.h
https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html
Die regeln das für dich.

von Mario M. (thelonging)


Lesenswert?

Aber selbst wenn wdt_ticks komplett weg optimiert würde, muss wenigstens 
der Text seriell ausgegeben werden.

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.