Hallo, der Watchdog-Timer des ATMega644 läßt sich nur mittels der Headerdatei wdt.h konfigurieren - aber nicht durch Manipulation der zugehörigen Register. Letzeres muß ich aber tun, weil der WD nur einen Interrupt und keinen Reset auslösen soll. Mit der Headerdatei wdt.h läßt sich das nicht konfigurieren. Bei meinen allerersten Exercietien mit dem ATMega644 ist mir allerdings aufgefallen, daß schon beim Konfigurieren eines normalen Resets Seltsames geschieht, wenn man die Register direkt beschreibt. Ich füge eine kurze Programmsequenz an, wo der Watchdog zunächst ein Delay überdauern muß und schließlich in eine Endlosschleife gerät, die er abbrechen soll: #include <avr/io.h> #include <util/delay.h> #include <avr/wdt.h> #include <avr/interrupt.h> void wd_start(void) { // wdt_reset(); // aus wdt.h MCUSR &= ~(1<<WDRF); // sicherheitshalber, für WDE-Manipulation WDTCSR |= (1<<WDCE) | (1<<WDE); // muß zur Manipulation an WDE //gesetzt sein WDTCSR |= (1<<WDE) | (1<<WDP3) | (1<<WDP0); // Watchdog-mode u. //timeout setzen; hier: return; // Totalreset u. 8,0 s } int main(void) { wd_start(); // Mit wd_start() (= Registermanipulation) bleibt // das Programm in der Schleife hängen, mit dem // Headerbefehl wdt_enable(7) funktioniert es, // wie sein soll; das Delayglied darf 2000ms sein. // wdt_enable(7); _delay_ms(10); // delay bei wd_start nicht über 10ms! (Soll 8,0 s!) MCUSR &= ~(1<<WDRF);// als wdt-reset zu gebrauchen, Manual (S52) unklar // wdt_reset(); // alternativ aus Headerdatei DDRA = 3; while (1) // ewige Schleife, sollte durch den WDT verlassen // werden { PORTA = 3; _delay_ms(35); PORTA = 0; _delay_ms(35); } return 0; } Also, mit wdt_enable(x) läuft es bestens, mit den Registern direkt (=wd_start) bleibt es in der Endlosschleife hängen. Kann jemand beurteilen, ob meine Manual-Interpretation falsch ist und wie man den ATMega644 zu einem Watchdog-Interrupt bringen kann, wenn nicht mal der Reset richtig zu funktionieren scheint. Oder muß man einen anderen Prozessor nehmen (welchen)? Viele Grüße Egon
> MCUSR &= ~(1<<WDRF); // sicherheitshalber, für WDE-Manipulation
macht was völlig anderes, als wd_reset().
Warum schaust du dir nicht einfach die Doku der avr-libc und dazu den
Source-Code in wdt.h an? Das hätte dir sofort gezeigt, was wd_reset()
tatsächlich macht. Und selbst, wenn da nicht direkt die Unterstützung
für den Interrupt_mode drin steckt, als Ausgangsbasis für eigenen Code
ist das allemal besser, als völlig neu von vorne anzufangen.
Oliver
steht das so im 644 manual ? hmm es gab AVRs da klappte das mit der wdt.h der LIB nicht richtig ich bastel mit einem 2561 .. da muss man auch manuell ausschalten sonst crasht er wieder beim start ich würde dazu das datenblatt nochma durchackern im datenblatt selber stehen bsp codes für C drin die man nehmen kann
Oliver schrieb: >> MCUSR &= ~(1<<WDRF); // sicherheitshalber, für WDE-Manipulation > > macht was völlig anderes, als wd_reset(). > > Warum schaust du dir nicht einfach die Doku der avr-libc und dazu den > Source-Code in wdt.h an? Habe ich gleich zu anfang, bin aber leider nicht so recht schlau daraus geworden, deshalb habe ich gem. Manual: ...WDRF The bit is reset by ..... or by writing a logic zero to the flag. Die habe ich als reset interpretiert, deshalb die Manipulation am MCUSR. Bin mir aber nicht sicher. > ...snip..... als Ausgangsbasis für eigenen Code > ist das allemal besser, als völlig neu von vorne anzufangen. > > Oliver Ist kein eigener Code, ist wortwörtlich aus dem Manual abgeschrieben (S. 50ff). Gruß Egon
gast schrieb: > steht das so im 644 manual ? > > ich würde dazu das datenblatt nochma durchackern > Kenne ich nun fast auswendig > im datenblatt selber stehen bsp codes für C drin die man nehmen kann Leider nicht ausfühlich genug, z.B. steht nichts für Reset, die empfehlen selbst den __watchdog_reset() aus irgendeiner spezifischen Headerdatei. Hier bei WinAVR-gcc heißt der Befehl wdt_reset() (funktioniert einwandfrei). Dann noch der Hinweis, daß man WDRF in MCUSR löschen könne. Ich werde mal allüberall die WDT-Initialisierungsroutine hinschreiben, denn wenn der WD anspricht, dann verstellt er wohl die Zeitkonstante (auf den kürzestmöglichen Wert 16ms). Übrigens gibt es bei Atmel ein App-Notiz (App 132???) - mit schönen Diagrammen, aber keinen C-Code, den man anpassen und übernehmen könnte. Viele Grüße Egon
>...WDRF The bit is reset by ..... or by writing a logic zero to the >flag. >Die habe ich als reset interpretiert, deshalb die Manipulation am MCUSR. >Bin mir aber nicht sicher. WDRF ist das Bit im MCUSR-Register, das anzeigt, daß ein WD-Reset stattgefunden hat. Das Bit kann man durch schreiben einer logischen eins löschen. wd_reset() setzt den Zählerstand des watchdog-timers zurück auf 0 (das ist ja nichts anderes als ein Timer/Counter). Dazu gibt es den (Assembler-)Befehl WDR. Der Sinn liegt wohl darin, zu verhindern, daß der watchdog zufällig innerhalb der folgenden Befehle zuschlägt, in denen er neu konfiguriert werden soll. Oliver
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.