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
AFAIK musst du den Watchdog VOR dem Einschalten erstmal zurücksetzen. MFG Falk
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?
>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.
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.
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 ....
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
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" \ )
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.