Hallo,
ich versuche gerade, den Watchdog auf dem AtMega2560 zu benutzen. Dafür
habe ich mir ein paar Routinen geschrieben. _enableWatchdog und
_disableWatchdog verändern die Prescalerbits nicht.
1
; void _setTimeout(unsigned char r24);
2
_setTimeout:
3
wdr
4
push r16
5
push r17
6
lds r16, 0x60 ; read WDT register
7
andi r16, 0xD8 ; clear WDP bits
8
or r16, r24 ; set timeout from parameter, leave old bits
9
ldi r17, 0x10 | 0x08 ; load WDE and WDCE
10
sts 0x60, r17 ; start WDT manipulation
11
sts 0x60, r16 ; write new WDT content
12
pop r17
13
pop r16
14
ret
15
16
_enableWatchdog:
17
push r16
18
lds r16, 0x60 ; load content of WDTCSR
19
ori r16, 0x08 ; enable WDE and WDCE
20
sts 0x60, r16 ; write back to WDTCSR
21
pop r16
22
ret
23
24
_disableWatchdog:
25
wdr ; reset WDT
26
push r16
27
push r17
28
lds r16, 0x60 ; load WDTCSR content
29
mov r17, r16 ; one copy is also needed
30
ori r16, 0x10 | 0x18 ; set WDCE and WDE, but leave WDP bits
31
andi r17, ~(0x10 | 0x08); clear WDCE and WDE bit, but leave WDP bits
32
sts 0x60, r16 ; write to WDTCSR to begin watch dog manipulation
33
sts 0x60, r17 ; disable watchdog
34
pop r17
35
pop r16
36
ret
Das klappt auch so weit innerhalb des Programms. Ich kann den Prescaler
setzen und den Watchdog beliebig oft aktivieren und deaktivieren. Wenn
er allerdings zuschlägt und der Controller neu startet, dann
funktioniert _disableWatchdog nicht mehr und der Watchdog schlägt sofort
wieder zu, obwohl das eigentlich hiermit abgestellt werden sollte:
Die Routine wird auch zum richtigen Zeitpunkt angesprungen, denn wenn
ich in initWatchdog einen Aufruf zu _setTimeout mit einem beliebigen
Prescalerwert einfüge, dann wird der Watchdog nach einem Watchdog-Reset
auch abgestellt.
Hat jemand eine Idee, warum ich nach einem Watchdog-Reset unbedingt die
Prescalerbits setzen muss?
Danke
Richard
Hallo Peter,
das Löschen des MCUSR-Registers hat scheinbar keinen Einfluss. Ich muss
explizit irgendein Prescalerbit beschreiben.
Warum nicht die wdt.h? Mein Watchdogtreiber soll sich in ein bestehendes
Framework integrieren, welches keinerlei Abhängigkeit zu den
AVR-Bibliotheken aufweist. Ich hab's jetzt in Hochsprache gebracht, da
muss ich nur noch eine einzige Zeile Assembler schreiben. So ungefähr
siehts aus:
Sapperlot!
Tatsächlich muss ich das MCUSR-Register zurücksetzen, ich habs nur
anscheinend nicht richtig gemacht.
So ungefähr funktioniert's jetzt ganz prima und ohne dass ich mich mit
Assembler abquälen muss ;-) Vielen Dank für die Hilfe.