Atmega64 Sleep mit Watchdog nach Zeit wecken

Gast #4985799
Lesenswert?

Hallo,

ich Programmiere gerade mit Arduino und möchte einen Atmega64L im 
Sleepmode mit dem Watchdog nach einer festgelegten Zeit zurückholen.

In Sleep geht er aber er kommt nicht mehr zurück.

Der Befehl ruft die goToSleep auf, in der SLEEP_TIME steht die Zahl 7
irgendwie funktioniert der Watchdog nicht und ich werd nicht so recht 
schlau aus dem Datenblatt. Nach 4 Std vergeblichem rumprobieren brauch 
ich jetzt hilfe, vielleicht hat das schon jemand gemacht.

Hier der Arduino Code mit der Sleep Funktion



goToSleep (0b100001, SLEEP_TIME);



void goToSleep(const byte interval, int time) {
 for (int i=0; i<time; i++) {

MCUSR = 0;
WDTCR |= (1<<WDCE) | (1<<WDE);
WDTCR =  0b01000000 | interval;        //hier muss der Fehler sein
 set_sleep_mode (SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 sleep_cpu();

 }
}
ISR(WDT_vect)
 {

 WDTCR = 0x00;  //für Watchdog disablen laut Datenblatt Atmega64
 }
Gast #4985840
Lesenswert?

beim Power Down Mode sollte laut datenblatt der Watchdog funktionieren

Mit dem WDTCR Befehl komm ich irgendwie nicht richtig klar.
Verstehe nicht genau wie sich das zusammenhängt und wie man hier eine 
Zeit einstellen kann bis der Watchdog ausgeführt wird.

Komischerweise hat das ganze bei einem Atmega16 funktioniert...

Hier das Datenblatt dazu
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2490-8-bit-AVR-Microcontroller-ATmega64-L_datasheet.pdf
Angehängte Dateien:
#4986240
Lesenswert?

Thomas schrieb:
> WDTCR |= (1<<WDCE) | (1<<WDE);
> WDTCR =  0b01000000 | interval;        //hier muss der Fehler sein

Das Schreiben auf das WDTCR muß in einer Timed Sequence erfolgen. Dafür 
hast du 4 Takte Zeit, in denen das erledigt sein muß. Dauert es länger, 
passiert gar nichts.


1
unsigned char temp = 0b01000000 | interval;
2
WDTCR |= (1 << WDCE) | (1 << WDE);
3
WDTCR = temp;
Gast #4986341
Lesenswert?

Hab das mal ausprobiert aber leider gleiches verhalten.
Die 4 Takte schafft er nicht würd ich sagen.

Die Frage ist auch was bedeutet das 0b0100000 ?
Es ist das Timer Control Register WDTCR aber was macht hier das 0b ????
Ist das die Adresse und ist diese evtl falsch?

Das Bild zeigt den WDTCR beim Atmega64
Angehängte Dateien:
Gast #4986410
Lesenswert?

Thomas schrieb:
> Hab das mal ausprobiert aber leider gleiches verhalten.
> Die 4 Takte schafft er nicht würd ich sagen.
>
> Die Frage ist auch was bedeutet das 0b0100000 ?
> Es ist das Timer Control Register WDTCR aber was macht hier das 0b ????
> Ist das die Adresse und ist diese evtl falsch?
>
> Das Bild zeigt den WDTCR beim Atmega64


So hab mal geschafft das der Watchdog läuft
jedoch macht er nach ca 0,5 Sekunden einen Reset und fängt das komplette 
Programm von vorne an. hier sollte er eigentlich zurück kommen die for 
schleife durcharbeiten und sehen das i noch nicht 4 ist und dann wieder 
in den sleep gehen.
Woher weis er das er keinen Reset machen soll durch watchdog?
wie befüllt man die Intervall richtig?

ich checks nicht. :-(



interval = 0b00011111, time = 4

---------------------------------------


void goToSleep(const char interval, int time) {


 for (int i=0; i<time; i++) {


 WDTCR =  0b00011000 | interval;
 set_sleep_mode (SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 sleep_cpu();
 wdt_reset();
 }
}
ISR(WDT_vect)
 {

 WDTCR = 0x00;  // Watchdog ausschalten
 }
#4986468
Lesenswert?

Hi

Laut
http://www.atmel.com/Images/Atmel-2490-8-bit-AVR-Microcontroller-ATmega64-L_datasheet.pdf
Seite 51 löst beim ATmega64(L) der Watchdog immer einen Reset aus.
Finde in dem PDF aber die möglichen ISR-Quellen nicht :/
Beim ATtiny kann man den WD nur einen Interrupt auslösen lassen, scheint 
es hier nicht zu geben.

Du kannst am Programm-Anfang da aber drauf reagieren, indem Du das WDRF 
(WatchDogResetFlag) auswertest und bei gesetztem Flag
- dieses auf Null setzt
- an die Programmstelle springen, wo Du nach dem WD weiter machen willst

Ohne dieses gesetzte Flag am Programmanfang 'ganz normal' 
Register/Ports/Variabeln setzen.


MfG
#4986489
Lesenswert?

Patrick J. schrieb:
> Ohne dieses gesetzte Flag am Programmanfang 'ganz normal'
> Register/Ports/Variabeln setzen.

Ein WD-Reset ist kein jump 0, sondern ein richtiger Reset mit allen 
Konsequenzen. Ohne sich den Status nach dem Aufruf des Sleep Mode im 
EEPROM zu sichern, wird das nichts. Da nützt allein die Kenntnis , daß 
es der WD war, der den Reset ausgelöst hat, wenig.

Nun ist allerdings ein WD-Reset die denkbar schlechteste Möglichkeit, 
den Sleep selbsttätig zu beenden.

Entweder lässt man einen beliebigen Timer im Sleep Idle laufen oder den 
Timer2 im Asynchron Mode mit Uhrenquarz im Sleep Power Safe . Oder man 
nimmt einen pinkompatiblen Atmega644 oder einen einen seiner Brüder. Der 
kann das mit WD als Timer von Haus aus.
Gast #4986491
Lesenswert?

Hi

>Du kannst am Programm-Anfang da aber drauf reagieren, indem Du das WDRF
>(WatchDogResetFlag) auswertest und bei gesetztem Flag
>- dieses auf Null setzt
>- an die Programmstelle springen, wo Du nach dem WD weiter machen willst

Und nach dem WD-RESET ist auch die ganze Initialisierung weg.

MfG spess
Gast #4986558
Lesenswert?

Danke Jungs.

Dann lass ich das mit dem Watchdog...

Ich werde dann einen Timer nehmen der im Sleep Idle weiterläuft und ihn 
danach automatisch wecken lassen. Mal schauen ob ich das so einfach 
hinbekomme.

Es geht hierbei um einen Batteriebetriebenes Gerät das mit möglichst 
wenig Strom auskommen soll. Die Spannung bekommt er von einer LIPO 
Zelle, somit zwischen 3 V und 4 Volt und deswegen auch der Atmega64L.
Das Teil soll alle 5min aufwachen was abarbeiten und wieder in den Sleep 
gehen. Die Zeitvariable soll über eine Taste und Display einstellbar 
sein, somit variabel.

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