Hallo zusammen
Ich hab vorhin einen Tipp bekommen, dass ich das Aufwecken meine
ATmega88 auch gut mit einem Watchdog lösen kann.
Ich hab mich jetzt mal ein bissl eingelesen und benutze jetzt die wdt.h!
Mein Programm-Code soll eigentlich nur den Watchdocg überprüfen.
Dieser wird auf 8s Prescaler eingestellt und soll wenn er in die ISR
springt eine Variable setzen, die anschließend im Hauptprogramm eine LED
für eine Sekunde leuchten lassen soll.
Davor soll der IC in den Power Down Mode gesetzt werden. Der Watchdog
sollte diesen ja eigentlich aufwecken.
Nun hier mal mein Programm-Code... das Problem ist, die LED leuchtet
nicht :(
Geht der AVR überhaupt in den Sleep Modus (Hinweis: Stromaufnahme
messen)?
Wenn nein, dann nachsehen, wie kommt das Programm über diese Stelle?
> while((ASSR & (1<< OCR2BUB))); // Warte auf das Ende des Zugriffs
Und nachsehen, wie GO definiert ist (volatile?).
Ja GO hab ich als volatile definiert... richtig so oder?
aber stimmt ASSR hat gar keinen Bezug mehr... ist noch n Fragment eines
anderen Codes. Den Dummyzugriff und so habe ich aus dem AVR-GCC Tutorial
übernommen.
Also Stromverbrauch ist konstant bei 12mA... tut sich gar nichts. Hab
jetzt einfach mal die zwei zeilen OCR2B und ASSR rausgelöscht
Für den Atmega8 habe ich gerade ein kleines Beispiel dazu geschrieben.
http://www.mikrocontroller.net/articles/Pollin_Funk-AVR-Evaluationsboard#Pennen_bis_der_Hund_bellt
Das ist auch für den Atmega89 übersetzbar und kann dir vielleicht die
Erleuchtung bringen. Ich selbst kann es aber nicht für den Atmega88
testen, weil ich keinen Atmega88 zur Hand habe.
Die Anzeige per LED habe ich auf PD5 gemacht. Die LED ist an PD5 so
angeschlossen:
PD5 o--------###-------->|--------o GND
Vorwiderstand LED
Wow echt super Sache was du da aufbaust ;)
Aber wo ist denn deine ISR?
Brauch man die nicht beim Watchdog? Die ISR (WDT_vect)?
Wo springt denn das Programm hin, wenn es aufgeweckt wird?
Alex schrieb:> okay... für was braucht man aber dann die ISR (WDT_vect)?
Mit einer Watchdog-Interrupt ISR spart man sich den RESET.
Den Atmega8 habe ich schlecht gewählt, denn der hat keinen
Interruptvektor für den Watchdog, den ich auf eine eigene ISR umlenken
kann. Beim Atmega8 wird durch den Watchdog ein RESET ausgelöst. Man kann
die Resetursache dann abfragen (um andere Resetursachen
auszuschliessen). Das ändert aber nix daran, dass das Programm von vorne
neu gestartet wird und man in seinen Variablen und Programmabläufen
darauf Rücksicht nehmen muss. Diesen Neustart habe ich jetzt im Artikel
dokumentiert.
Ich muss mal suchen, ob ich einen AVR mit Watchdog-Interrupt habe und
den Artikel ergänzen kann. Vielleicht der Attiny2313?
Okay du meinst also, wenn der Watchdog auslöst, resettet das ganze
Programm oder wie? Und wenn man davor immer den Watchdog_Reset reinhaut,
tut er das nicht!
Ich hab gelesen, dass wenn der WD auslöst, dieser dann nach dem Sleep
Befehl einfach weiter macht... und wenn die while-Schleife durchgelaufen
ist, der sleep-befehlt ja wieder kommt und er schlafen geht.
und iwo hab ich noch gelesen, dass wenn der WD zuschlägt, ein Interrupt
ausgelöst wird und dieser interrupt dann so lange zeit hat abgearbeitet
zu werden, bis theoretisch ein neuer WD auslöst und diesmal entgültig
das system resettet ode rbist einfach der WD_Reset gesetzt wurde.
stimmt das in etwa?
Ja, mit dem Attiny2313 kann man den Watchdog Interrupt so aufsetzen,
dass kein System Reset ausgeführt wird. Der Artikel ist entsprechend
ergänzt.
Und nicht wundern: Was beim Atmega88 WDT_vect heisst, heisst beim
Attiny2313 WDT_OVERFLOW_vect.
Alex schrieb:> Okay du meinst also, wenn der Watchdog auslöst, resettet das ganze> Programm oder wie? Und wenn man davor immer den Watchdog_Reset reinhaut,> tut er das nicht!
Ja bei dem Dino Atmega8 ist das so. Den Watchdog Reset hat man im
Sleep Modsu nicht zur Verfügung bzw. verlässt man sich ja gerade darauf,
dass der Watchdog auslöst.
Kein Reset ist beim Attiny2313 und beim Atmega88 (und anderen)
einstellbar, wenn die entsprechend konfiguriert werden.
> Ich hab gelesen, dass wenn der WD auslöst, dieser dann nach dem Sleep> Befehl einfach weiter macht... und wenn die while-Schleife durchgelaufen> ist, der sleep-befehlt ja wieder kommt und er schlafen geht.
Bei obigen "modernen" AVRs ist das möglich!
> und iwo hab ich noch gelesen, dass wenn der WD zuschlägt, ein Interrupt> ausgelöst wird und dieser interrupt dann so lange zeit hat abgearbeitet> zu werden, bis theoretisch ein neuer WD auslöst und diesmal entgültig> das system resettet ode rbist einfach der WD_Reset gesetzt wurde.
Ja das ist in etwas richtig, wenn WDTCSR für den Interrupt and System
Reset Mode konfiguriert wurde, d.h. WDIE und WDE gesetzt sind.
Der erste anspringende Watchdog ruft die ISR auf und löscht das WDIE Bit
und der nächste führt zu einem System Reset, wenn zwischendurch vom
Programm das WDIE Bit nicht nochmal gesetzt wurde.
Diesen Fall habe ich noch nicht betrachtet; es könnte meine
Schlußbemerkung zum Umkonfigurieren im Artikel obsolet machen bzw. die
Umkonfiguration wesentlich erleichtern.
Hi :)
Kannst du vllt mal kurz drüberschauen, wenn du Zeit hast? Ist nun eine
etwas umgeschriebene Funktion, aber LED leuchtet immer noch nicht und er
scheint auch nicht schlafen zu gehen ;(
Vllt weißt du wo der Fehler liegt...
1
intmain(void)
2
3
{
4
WDTCSR|=0x48;// setzt WDIE und WDE für Interrupt and System Reset Mode
5
6
wdt_enable(WDTO_4S);// Watchdog auf 4Sekunden bis zum Auslösen
7
8
sei();// Interrupts aktivieren
9
10
while(1)
11
12
{
13
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
14
sleep_mode();// in den Schlafmodus wechseln
15
16
WDTCSR|=(1<<WDIE);// WDT Interrupt Flag erneut setzen, damit kein Reset erfolgt