Hallo Leute, eine kurze frage: Wie setz ich den Watchdog im Programm zurück? Ich programmiere in C. Reicht ein: WDR = 0; ..oder benötige ich da auch irgend einen genau spezifizierten Programmablauf? Grüße Tom
Hallo nochmal, So in der Art sollte das Einstellen des Watchdogs doch funktionieren oder? Übergabewerte: - watchdog_presc -> Wertebereich 0x0 - 0x9 -> entspricht 2k-1024k clock cycles - watchdog_mode -> Wertebereich 0x0 - 0x3: 0x0 = stopped, 0x1 = isr, 0x2 = System reset, 0x3 = isr & system reset void watchdog_config(unsigned char watchdog_presc, unsigned char watchdog_mode) { switch(watchdog_mode) { case 0x0: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = 0x0; break; case 0x1: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = (watchdog_presc&0x7) | \ ((watchdog_presc&0x8)<<2) | (1<<WDIE); break; case 0x2: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = (watchdog_presc&0x7) |\ ((watchdog_presc&0x8)<<2) | (1<<WDE); break; case 0x3: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = (watchdog_presc&0x7) |\ ((watchdog_presc&0x8)<<2) | (1<<WDIE) | \ (1<<WDE); break; default: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = 0x0; } } nur wie läuft das mit dem Rücksetzen ab?!? Einfach "WDR = 0;"?
> "WDR = 0;" Was soll das sein? 'wdr' ist ein Assembler-Befehl. Dem kann man keinen Wert zuweisen. Entweder, Du fügst den wdr-Befehl per Inline-Assembler ein (da Du nicht erzählst, welchen C-Compiler Du benutzt, kann ich natürlich nicht konkret sagen, wie es in Deinem Fall auszusehen hat) oder Du benutzt eine Bibliotheksfunktion bzw. -Makro. In AVR-GCC-C läuft das entweder direkt über asm volatile ("wdr"); //Inline-Assembler oder mit #include<avr/wdt.h> //... wdt_reset(); wobei das Makro wdt_reset() auch nix anderes macht, als den Assembler-Befehl wdr inline einzusetzen. In CodeVision gehts z.B. mit #asm("wdr")
Hallo Jonny, danke für deine Antwort! Ich benutze AVR-GCC-C. Genau das war es was mir gefehlt hat. Kenn mich mit assembler leider net wirkl aus :). Eine Frage hätte ich noch dazu: Ich habe schon einen inline-Assembler Sleep-Befehl. Bei dem sind zwei "::" am Ende. Kannst du mir erklären, was das bedeutet? asm volatile ("sleep"::); //:: am ende == ?? Grüße
Lt. AVR-libc-Doku (http://www.nongnu.org/avr-libc/user-manual/inline_asm.html) muss bei Inline-Assembler immer die Parameter-Liste, deren erforderliche Teile (Input- und Output-Parameter) durch Doppelpunkte getrennt werden, angegeben werden, auch wenn sie leer ist. Die angesprochene Doku scheint sich allerdings auf eine ältere Version zu beziehen. Aktuell kann man bei parameterlosen Befehlen wie sleep, wdr, nop usw. die Doppelpunkte weglassen. Wenn man sie trotzdem macht ist auch nicht schlimm... Vielleicht ist ja einer der WINAVR-Experten grade irgendwo hier in der Gegend (Hallo Jörg Wunsch, kannst Du uns hören?) und kann das kommentieren (ab welcher Version, warum usw..) Gruß Johnny
Danke für die Info! Der funktionierende Code lautet: (net dass des oben wer rauskopiert u es funzt net ;) void watchdog_config(unsigned char watchdog_presc, unsigned char watchdog_mode) { cli(); unsigned char temp = 0x0; temp = (watchdog_presc & 0x7)| ((watchdog_presc&0x8)<<2); switch(watchdog_mode) { case 0x0: asm volatile ("wdr"::); //Watchdog reset MCUSR &= ~(1<<WDRF); //Flag zurücksetzen WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE); WD_CONTROL = 0; break; case 0x1: asm volatile ("wdr"::); //Watchdog reset WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE); WD_CONTROL = temp | (1<<WD_ISR); break; case 0x2: asm volatile ("wdr"::); //Watchdog reset WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE); WD_CONTROL = temp | (1<<WD_ENABLE); break; case 0x3: asm volatile ("wdr"::); //Watchdog reset WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE); WD_CONTROL = temp | (1<<WD_ISR) | (1<<WD_ENABLE); break; default: asm volatile ("wdr"::); //Watchdog reset WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE); WD_CONTROL = 0x0; } sei(); }
Schau mal in die avr/wdt.h. Da gibts mehrere Funktionen, die im Prinzip genau das machen, was Du da programmiert hast. Gruß Johnny (bitte mit 'h')
Ja ich weiss...ich programmiere es nur immer gern selber, anstatt fremde libraries einzufügen :). Trägt wenigstens ein bissl zum Verständnis bei.:) Grüße
"Schau mal in die avr/wdt.h. Da gibts mehrere Funktionen, die im Prinzip genau das machen, was Du da programmiert hast." aber nicht ganz, z.B. den Watchdog als interrupt einstellen gibts da nicht
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.