Ich möchte einfach durch den Watchdog timer nach einer gewissen Zeit,
über einen Interupt, zwei LEDs anschalten. Leider klappt das ganze
nicht, und ich habe absolut keinen Dunst wieso. Wäre nett wenn mir
jemand einen kleinen Hinweis geben könnte :)
WDTON Fuse ist an.
Wenn ich das richtig verstehe, ist der Watchdog ein Timer der unabhängig
vom CPU Takt mit ca 128 kHZ läuft. Bei jedem überlauf des Timers kann
eine, je nach Einstellung, anderte Aktion sattfinden. Bei mir soll es
ein Interrupt sein, der dann zwei LEDs anschaltet. Hab mir die
Einstellungen im Datenblatt zusammengesucht und die Registetr so
gesetzt, dass die LEDs nach ca 4 Sekunden angehen sollten. Tun sie nur
leider nicht.
Das ganze Programm hat erstmal keinen größeren Sinn. Das ganze dient mir
nur zum verstehen. Danach will ich halt ein Programm schreiben, dass
alle paar Sekunden eine ADC Messung vornimmt. Zwischen den Messungen
soll sich der mc zum Stromsparen schlafen legen. Der Watchdog ist
eigentlich nur zum Aufwecken da.
Erstmal die WDTON-Fuse abschalten!
Damit der Watchdog nicht versehentlich oder durch Programmfehler ein-
oder ausgeschaltet wird, muß ein bestimmtes Timing beim Setzen der
Register eingehalten werden.
1. WDRF-Flag in MCUSR setzen.
2. Watchdog einschalten: WDCE und WDE in WDTCSR setzen
3. Watchdog ändern: WDCE und WDIE setzen, WDE zurücksetzen,
Prescaler-Bits setzen. Und zwar alles gleichzeitig.
Wichtig ist bei einer Änderung immer das WDCE (Watchdog Change Enable),
zum Ein- ,Ausschalten und Resetten das WDRF in MCUSR.
In C sieht das so aus:
MCUSR &= ~(1<<WDRF); //Clear WDRF in MCUSR
WDTCSR = (1<<WDCE) | (1<<WDE);//Watchdog Change Enable, Enable Watchdog
WDTCSR = 0x46; //Enable Interrupt, Disable Reset, Set Prescaler 1s
mfg.
Interessanterweise braucht man die 'timed sequence' beim ATiny13
[i]nicht[/i], ebensowenig WDCE - sofern der WDT-Reset nicht aktiviert
ist.
Probier Deinen Code einfach mal mit deaktiviertem WDTON aus, den WDTON
forciert einen RESET.
Das ist die Aktuelle Version, hab mich dabei an die Vorschläge von
Thomas Eckmann gehalten. Funktioniert leider in der Simulation wie in
der Realität nicht. WDTIF wird einfach nicht gesetzt, mach ich das in
der Simulation manuell, dann funktioniert das restliche Programm wie
gedacht.
der Eumel
Danke für deine Mühe, aber was der c comoiler da veranstaltet ist mir
schleierhaft. Warum wird hier was im Ram gespeichert? Und wozu ist das
"ANDI" gut? ( Was es macht weiß ich...nur wieso nicht)
Eumel schrieb:> Warum wird hier was im Ram gespeichert?
Das wird nicht im RAM gespeichert. Das ist vom Atmega 644. Da fängt das
RAM erst bei 0x100 an.
Das ist beim Tiny 13 natürlich eine andere Adresse.
Mit sts schreibt man in den Dataspace. Der geht von 0x0000 bis RAMEND.
Also Register, I/O Memory und SRAM.
Eumel schrieb:> Und wozu ist das "ANDI" gut?
MCUSR wird in r24 geladen, mit "andi r24, 0xF7 " wird Bit3 in r24
gelöscht und dann wieder zurück geschrieben.
Anstatt alles zu überschreiben.
mfg.
Seltsam.
Also ich schreib (in C) einfach nur WDTIE und den prescaler direkt in
WDTCR, dann noch das 'sei', und das geht dann einfach so...
WDTCR=0b01000011; SEI;
(SEI ist ein Makro für 'sei' halt :)
Das hier dürfte Dein Fehler sein:
ldi r16, (1<<WDRF)
Das WDRF wird durch Schreiben einer 0 gelöscht, Du schreibst eine 1.
Und das AVR-Studio simuliert so etwas nicht gescheit, das muss am
lebenden Baustein ausprobiert werden.
Und schreib' noch ein WDR zu Beginn rein. Im ATiny-DB gibt's ein paar
Beispiele wie's richtig gemacht wird.