Atmega644p + WDT + Sleepmode

Gast #659179
Lesenswert?

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??
#659224
Lesenswert?

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
Gast #659233
Lesenswert?

> 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.
Gast #659316
Lesenswert?

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.
Gast #659369
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren