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); }
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
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
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
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.
i=3; soweit alles klar. Den Code habe ich aus dem DB vom Attiny 13A. Gruss Pascal
Hi
>Den Code habe ich aus dem DB vom Attiny 13A.
Der geht aber davon aus, das der WD schon initialisiert ist.
MfG Spess
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.
@Thomas super danke, werde es mir heute Abend einmal anschauen. Danke Pascal
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.