Forum: Mikrocontroller und Digitale Elektronik Attiny13 Watchdog interrupt


von Eumel (Gast)


Lesenswert?

1
.include "tn13def.inc"
2
.org 0x000
3
         rjmp main 
4
.org WDTaddr
5
    rjmp WATCHDOG
6
7
8
9
 main:
10
 
11
ldi r16, low(RAMEND)
12
out SPL, r16
13
ldi r16, 0b00000011
14
out DDRB, r16
15
ldi r16, (1<<WDCE) 
16
out WDTCR, r16
17
ldi r16, (1<<WDTIE)| (1<<WDP3) 
18
out WDTCR, r16
19
sei
20
21
ende: rjmp ende
22
23
24
WATCHDOG:
25
ldi r16, 0b00000011
26
out PORTB, r16
27
reti

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 :)

von spess53 (Gast)


Lesenswert?

Hi

Wie sieht deine WDTON-Fuse aus?

MfG Spess

von Eumel (Gast)


Lesenswert?

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.

von Thomas E. (thomase)


Lesenswert?

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.

von (Gast) (Gast)


Lesenswert?

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.

von Eumel (Gast)


Lesenswert?

1
 .include "tn13def.inc"
2
.org 0x000
3
         rjmp main 
4
.org WDTaddr
5
    rjmp WATCHDOG
6
7
8
9
 main:
10
 
11
ldi r16, low(RAMEND)
12
out SPL, r16
13
ldi r16, 0b00000011
14
out DDRB, r16
15
ldi r16, (1<<WDRF)
16
out MCUSR, r16
17
ldi r16, (1<<WDCE) | (1<<WDE)
18
out WDTCR, r16
19
ldi r16,  (0<<WDE)| (1<<WDTIE) 
20
out WDTCR, r16
21
sei
22
23
ende: rjmp ende
24
25
26
WATCHDOG:
27
ldi r16, 0b00000011
28
out PORTB, r16
29
reti

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

von Thomas E. (thomase)


Lesenswert?

Eumel schrieb:
> Funktioniert leider in der Simulation wie in
>
> der Realität nicht.

Der Compiler macht es so:

MCUSR &= ~(1<<WDRF);  //Clear WDRF in MCUSR
     47c:  84 b7         in  r24, 0x34  ; 52
     47e:  87 7f         andi  r24, 0xF7  ; 247
     480:  84 bf         out  0x34, r24  ; 52
WDTCSR = (1<<WDCE) | (1<<WDE);  //Watchdog Change Enable, Enable 
Watchdog
     482:  88 e1         ldi  r24, 0x18  ; 24
     484:  80 93 60 00   sts  0x0060, r24
WDTCSR = 0x46;  //Enable Interrupt, Disable Reset, Set Prescaler 1s
     488:  86 e4         ldi  r24, 0x46  ; 70
     48a:  80 93 60 00   sts  0x0060, r24

Ist allerdings ein Atmega 644. Aber die Register sind die gleichen.

WDTON-Fuse muss abgeschaltet sein.

mfg.

von Eumel (Gast)


Lesenswert?

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)

von Thomas E. (thomase)


Lesenswert?

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.

von (Gast) (Gast)


Lesenswert?

WDTON hast Du mittlerweile abgeschaltet?

von Eumel (Gast)


Lesenswert?

Ja, ist abgeschaltet.

von (Gast) (Gast)


Lesenswert?

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 :)

von Eumel (Gast)


Lesenswert?

Stand der Dinge: geht nicht.

Gute nacht und Danke für die Hilfe :) morgen ist ja auch noch ein Tag!

von MWS (Gast)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.