Hi, wir wollen den 644p in den Sleepmode "Power-Down" schicken und mit dem WDT (geht laut Datenblatt) wieder aufwecken. Unsere Idee ist es keinen Reset machen zu lassen sondern in der ISR(WDT_vect) die sleepinstr. zu deaktivieren. Unsere Problems sind zum einen, das mit wdt_enable() es zwar kein Problem ist den WDT einzuschalten, er jedoch immer bei Ablauf einen Reset macht und nicht in die ISR springt. Was muessen wir tun um den Reset zu deaktivieren und die ISR zu aktivieren? Zum anderen wissen wir nicht, ob wir aus dem Power-Down direkt in die ISR von WDT springen koenen. Hat da jemand schon Erfahrung??
Ralle wrote: > Unsere Problems sind zum einen, das mit wdt_enable() es > zwar kein Problem ist den WDT einzuschalten, er jedoch immer bei Ablauf > einen Reset macht und nicht in die ISR springt. Das ist korrekt, dazu ist die Blackbox wdt_enable() gemacht. > Was muessen wir tun um > den Reset zu deaktivieren und die ISR zu aktivieren? Das Datenblatt lesen und dann die nötigen Bits selber setzen. > Hat da jemand schon Erfahrung?? Ich nicht (ich benutze keinen Batteriebetrieb, meine Geräte laufen alle am Stromnetz). Peter
> Unsere Problems sind zum einen, das mit wdt_enable() es > zwar kein Problem ist den WDT einzuschalten, er jedoch immer bei Ablauf > einen Reset macht und nicht in die ISR springt. wdt_enable() setzt nicht nur die Prescaler-Bits, sondern auch WDE, wodurch ein Reset ausgelöst wird. > Was muessen wir tun um den Reset zu deaktivieren und die ISR zu aktivieren? Manuell die Prescaler-Bits sowie WDIE setzen, um den Watchdoginterrupt zu aktivieren. > Zum anderen wissen wir nicht, ob wir aus dem Power-Down direkt in die ISR > von WDT springen koenen. Ja.
Also wir machen es so: cli(); MCUSR &= ~(1<<WDRF); WDTCSR |= (1<<WDCE); WDTCSR |= ((1<<WDIE) | (1<<WDP2)|(1<<WDP1)| (1<<WDP0)); MCUSR &= ~(1<<WDRF); WDTCSR &= ~(1<<WDE); sei(); Also WDIE fuer Interrupt und WDE=0 fuer "kein Reset". Prescaler wird eingestellt. Funzt aber nicht. Macht ISR + Reset und ist sau schnell. Nicht wie in Prescaler eingestellt.
Schmeiß mal die ganzen &=, |= raus. Du mußt direkt zuweisen (=), damit die Timings (<4Takte) eingehalten werden. Peter
OK, schon besser. cli(); MCUSR = ~(1<<WDRF); WDTCSR = (1<<WDCE) | (1<<WDE); WDTCSR = ((1<<WDIE) | (1<<WDP2)|(1<<WDP1)| (1<<WDP0)); MCUSR = ~(1<<WDRF); WDTCSR = ~(1<<WDE); sei(); So gehts! Alle 2 Sec. wird ISR(WDT_vect) ausgefuehrt ohne anschliessenden Reset. Nur Interrupt.
Du kannst auch einen avr-libc-Bugreport schreiben, damit diese Funktionalität mal in <avr/wdt.h> mit aufgenommen wird.
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.