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 }
Power Down macht verdammt viele Taktgeber aus. Schau Dir mal an ob da überhaupt noch was läuft was den WDT antreiben kann.
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
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; |
:
Bearbeitet durch User
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
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 }
Thomas schrieb: > was macht hier das 0b ???? Kennst du den Präfix 0x für Hexzahlen? Das 0b ist dementsprechend der Präfix für Binärzahlen...
:
Bearbeitet durch Moderator
Thomas schrieb: > ich checks nicht. Schon mal einen Blick ins Datenblatt riskiert? Der Code, den du irgendwo abgeschrieben hast, funktioniert auf dem Atmega64 nicht, da der die dafür notwendige Funktion, nämlich den WD als Timer zu nutzen, nicht hat.
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
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.
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
Thomas E. schrieb: > Oder man > nimmt einen pinkompatiblen Atmega644 oder einen einen seiner Brüder. Der > kann das mit WD als Timer von Haus aus. Ach Sch... vergiss es. Ich war beim 16/32er. Aber 640/1280/2560 könnte was sein. Den 2560 gibt es auch als Arduino.
:
Bearbeitet durch User
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.
Bei den alten ATmegas kannst Du einen 32kHz Quarz an den asynchronen Timer anschließen und Dich damit aus Power-Save wecken lassen.
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.