Forum: Compiler & IDEs Watchdog Reset Problem -- sofort, ohne entspr. Delay


von Jens-Erwin (Gast)


Angehängte Dateien:

Lesenswert?

Der Watchdog (ATMega8) funktioniert nicht richtig. Ich habe diesen auf 
2s eingestellt. Aber er geht sofort auf Reset.
Ich benutze einen Interrupt beim Timer.
Habe ein Testprogramm in C und Assembler geschrieben -- Assembler geht 
... C nicht

Bitte um Hilfe

von Falk B. (falk)


Lesenswert?

AFAIK musst du den Watchdog VOR dem Einschalten erstmal zurücksetzen.

MFG
Falk

von Jens-Erwin (Gast)


Lesenswert?

ja kann ich machen

etwa so:

asm ("wdr")
WDTCR |= (1<<WDE) |(1<<WDCE);
WDTCR = 0;

trotzdem, die 2,1s werden nicht gemacht, sondern es geht sofort in den 
Reset, es ist so, als würde ich nur ein paar Zeilen Zeit haben, um dann 
wieder ein wdr setzen zu müssen.

Ich habe auch keinen Beispielcode in C hier gefunden. Gibt es da einen?

von Jojo S. (Gast)


Lesenswert?

>Ich habe auch keinen Beispielcode in C hier gefunden. Gibt es da einen?

ja, es gibt einen header in den avr includes für die Watchdog 
Funktionen. Es dürfte besser sein die zu benutzen weil für mehrere Typen 
portabel.
1
#include <avr/wdt.h>
2
3
wdt_enable(WDTO_2S);
4
5
...
6
7
wdt_reset();

aber vielleicht liegt das Problem auch woanders und es wird ein anderer 
Interrupt ausgelöst der keine ISR hat oder ist ein falsches Device 
eingestellt und die ISR an der falschen Stelle? Dann würde ja der 
default Reset ausgelöst.

von Andreas K. (a-k)


Lesenswert?

Im Programm nach dem Start das MCUCSR/MCUSR auslesen, irgendwie 
anzeigen, dann löschen. Damit erfährt man, was den Reset tatsächlich 
ausgelöst hat.

Man kann bei AVRs den Watchdog per Fuse einschalten. Das kann auch 
solche Effekte haben. Vor allem wenn man erst einmal 3s wartet.

von Jens-Erwin (Gast)


Lesenswert?

Danke an alle,

ich habe es ja mit Assembler ausprobiert, geht alles --- aber nicht mit 
C-Code

Es funktioniert mit der wdt.h und den entsprechenden Befehlen ... wie 
Johannes geschrieben hat .. klasse!!

Scheinbar ist der C-Code zu langsam -- hängt vielleicht mit den 4 
Taktzyklen zusammen

Der Assmbler-Code in der wdr.h ist einleuchtend ....

von Peter D. (peda)


Lesenswert?

Jens-Erwin wrote:
1
WDTCR = (1<<WDE) |(1<<WDCE);  //Watchdog enabled
2
WDTCR |= (1<<WDP0) | (1<<WDP1) | (1<<WDP2) ;            //Dauer
> Scheinbar ist der C-Code zu langsam -- hängt vielleicht mit den 4
> Taktzyklen zusammen

Nö, er ist schlichtweg falsch!

WDCE muß im 2.Zugriff 0 sein, das geht nicht mit nem |=.

Mach 2 Zuweisungen mit den richtigen Werten, dann  klappts auch in C.


Peter

von Jens-Erwin (Gast)


Lesenswert?

wenn ich den Inline-Assembler in der wdr.h in C "übersetze", 
funktioniert es trotzdem nicht  --- komisch ??? Der Reset wird 
ausgelöst, aber die Zeit lässt sich nicht eingeben ...



asm ("cli");
asm ("wdr");

WDTCR = (1<<WDE) |(1<<WDCE);  //Watchdog enabled

asm ("sei");                        //  I-Flag in SREG, wenn gesetzt

WDTCR = (1<<WDE) | 7 ;


//FUNKTIONIERT NICHT !!






#define _wdt_write(value)   \
    _asm__ __volatile_ (  \
        "in _tmp_reg_,__SREG__" "\n\t"    \
        "cli" "\n\t"    \
        "wdr" "\n\t"    \
        "out %0,%1" "\n\t"  \
        "out _SREG_,__tmp_reg__" "\n\t"   \
        "out %0,%2" \
        : /* no outputs */  \
        : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
        "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)),   \
        "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
            _BV(WDE) | (value & 0x07)) ) \
        : "r0"  \
    )

von Peter D. (peda)


Lesenswert?

Optimierung einschalten -Os


Peter

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.