www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Watch Dog Interrupt Attiny 13A


Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
was mache ich falsch?
Ich versuche alle 8s in die Interrupt Routine zu springen.
Eine LED soll hierbei alle 8s ein und ausschalten.
Allerdings passiert gar nichts.

Wie muss ich den Watchdog Interrupt initialisieren?

Danke Pascal

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


void wdt_init(void)
{
cli();
MCUSR = ~(1<<WDRF);
WDTCR =  (1<<WDCE) | (1<<WDE);
WDTCR = ((1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0)); // Interrupt
mode & Prescaler auf 8Sek. setzen

MCUSR = ~(1<<WDRF);
WDTCR = ~(1<<WDE);
sei();
}

ISR(WDT_vect)
{
   PORTB ^= (1 << PB0);
}

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>WDTCR =  (1<<WDCE) | (1<<WDE);
>WDTCR = ((1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0)); // Interrupt
>WDTCR = ~(1<<WDE);

Und welchen Wert soll WDTCR nun haben?

MfG Spess

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss es denn so aussehen?

WDTCR |= (1<<WDCE) | (1<<WDE); /* Startet timer sequence */

WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); Set Prescaler 8S

Sorry, ist mein erstes ATEML Projekt.

Gruss Pascal

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Muss es denn so aussehen?

>WDTCR |= (1<<WDCE) | (1<<WDE); /* Startet timer sequence */

>WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); Set Prescaler 8S

>Sorry, ist mein erstes ATEML Projekt.

Und ich kann kein C. Wenn du die Zuweisung in meheren Zeilen machst, 
dann so:

WDTCR = ....
WDTCR |= ...
WDTCR |= ...

Mit einem '=' überschreibst du alle vorherigen Zuweisungen.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pascal schrieb:
> Muss es denn so aussehen?
>
> WDTCR |= (1<<WDCE) | (1<<WDE); /* Startet timer sequence */
>
> WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); Set Prescaler 8S
>


Wenn du eine Abfolge von Zuweisungen machst

  i = 5;
  i = 8;
  i = 3;

welchen Wert hat dann i zu guter letzt?

Inwiefern verändert sich das, wenn du eine der Zuweisungen davor 
veränderst?

  i = 9;
  i = 3;

welches ist jetzt der Wert von i nach der letzten Zuweisung?

  i = 8 + 9;
  i = 3;

Und jetzt?

> Sorry, ist mein erstes ATEML Projekt.

Das ist egal. Denn ein grundlegendes Prinzip der Programmiersprachen aus 
der Familie zu der C gehört lautet nun mal: Anweisungen werden in der 
Reihenfolge ihrer Niederschrift abgearbeitet.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
i=3; soweit alles klar.

Den Code habe ich aus dem DB vom Attiny 13A.

Gruss Pascal

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Den Code habe ich aus dem DB vom Attiny 13A.

Der geht aber davon aus, das der WD schon initialisiert ist.

MfG Spess

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pascal schrieb:
> Muss es denn so aussehen?
>
>
>
> WDTCR |= (1<<WDCE) | (1<<WDE); /* Startet timer sequence */
>
>
>
> WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); Set Prescaler 8S

Das ist schon fast richtig.
Es fehlt noch das MCUSR-Register.
Um das WDE-Bit zu löschen, MUSS ZUERST das WDRF-Bit im MCUSR gelöscht, 
dann wird das WDCE-Bit(Change Enable) gesetzt und mit dem NÄCHSTEN 
Befehl können dann das WDE gelöscht und weitere Änderungen gemacht 
werden werden.

Das muß aber alles in diesem einen letzten Befehl geschehen.
Sieht ein bisschen unlogisch aus, aber beim Watchdog müssen klar 
definierte Timings eingehalten werden.

Das ist so, damit der Watchdog nicht einfach bei einem Programmfehler 
durch nicht beabsichtigtes Schreiben ins WDTCR-Register deaktiviert 
werden kann.

Beim Atmega 644 mache ich das so:
(Beim Tiny 13 sind das die gleichen Register)

//Watchdog Interval Timer
WDTCSR |= (1<<WDCE) | (1<<WDE);  //Enable Reset
MCUSR &= ~(1<<WDRF);  //Clear WDRF in MCUSR
WDTCSR |= (1<<WDCE);  //Watchdog ChangeEnable
WDTCSR = 0x49;  //Enable Interrupt, Disable Reset, Set Prescaler 8s
DDRB |= (1 << 4);          //Test
//---
sei();


ISR(WDT_vect)
{
  PORTB ^= (1 << 4);
}

Und dann toggelt PB4 ungefähr alle 8s.
Warum ungefähr? Weil die Timing-Angaben für 5 V gelten und bei anderen 
Spannungen andere Werte herauskommen können. Also ausprobieren.

mfg.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Thomas
super danke, werde es mir heute Abend einmal anschauen.

Danke Pascal

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.