Watchdog timer löst keinen interrupt aus

Gast #2036873
Lesenswert?

hallo zusammen, mein wdt löst keinen ionterrupt aus, jemand ne ahnung 
warum??? µC ist der tiny2313.

hier mal der zugehörige code:
1
#define WD_PRESCALER  WDT_32MS
2

3
(...)
4

5
ISR(WDT_OVERFLOW_vect)
6
{
7
   WD_cnt++;
8
}
9

10
(...)
11

12
// Init watchdog timer as normal timer with interrupt
13
void init_WDT_IRQ(void)
14
{
15
   disable_IRQ();
16

17
   // Start timed Sequence
18
   WDTCSR |= (1<<WDCE) | (1<<WDE);
19

20
   // Set new prescaler(time-out) value
21
   WDTCSR  = (1<<WDIE) | (1<<WDE) | | (WD_PRESCALER);
22

23
   WD_cnt  = 0;
24

25
   enable_IRQ();
26
}
Gast #2036874
Lesenswert?

ups jetzt hab ich ein fehler in die zeile getippt:
[c]
   // Set new prescaler(time-out) value
   WDTCSR  = (1<<WDIE) | (1<<WDE) | | (WD_PRESCALER);
[\c]
muss natürlich so heissen:
[c]
   // Set new prescaler(time-out) value
   WDTCSR  = (1<<WDIE) | (1<<WDE) | (WD_PRESCALER);
[\c]
#2036932
Lesenswert?

Ansonsten besteht noch die Möglichkeit, das dir der Compiler etwas 
wegoptimiert, "WD_cnt++;" in dem Fall.

Wie sieht die Definition dafür aus?
Mal ins Listing geschaut was rauskommt?

Ich stochere bei GCC ein wenig im Dunkeln, ich nutze den nicht weil ich 
ihm nicht traue. ;-)
Gast #2036944
Lesenswert?

> weil ich ihm nicht traue. ;-)

das kommt mir irgenwie seltsam bekannt vor ;)
WD_cnt ist ne globale volatile mit 8bit, soll später mal in EEPROM 
geschrieben werden.
ja ist mir klar aber die init wird ja nach jedem systemneustart (was 
nicht vorkommen sollte) neu aufgerufen und somit auch das Ir flag.

und nach dem watchdog_reset(); bleibt das flag ja normalerweise erhalten 
oder? hinter watchdog_reset(); steckt asm("WDR");
#2036958
Lesenswert?

micha s. schrieb:
> und nach dem watchdog_reset(); bleibt das flag ja normalerweise erhalten
> oder? hinter watchdog_reset(); steckt asm("WDR");

Ja das fasst das Flag nicht an.

Hast du das Ganze mal durch den AVR Simulator gejagt?

Mir fehlt so ein wenig die Information, wie Du das Ganze denn testest, 
zwischen Interrupt und dem kompletten Reset liegen schließlich nur 
wenige Millisekunden.

Also führe mal ein bisschen detailierter auf wie du testest, reduziere 
dein Programm auf den Tesfall und stelle das hier >komplett< ein.
Gast #2037008
Lesenswert?

testen eben im avr simulator.
hm das ganze programm (selbst nur den test hier rein zu stellen) wird 
viel zu viel, sind 5 files + enstspr. header...
wie gesagt der test ist im avr simulator, mit breakpoint beim IRQ von 
wdt ovr. kommt aber nie soweit obwohl ich den wdt nie zurücksetze.
aber ich werde sehen was ich machen kann, allerdings erst wenn ich 
wieder daheim bin, habs nicht dabei.
eventuell könnte es noch sein da ich recht viele interrupts habe das es 
nie soweit kommt weil er am interruot abarbeiten ist.
aber in der simulation funktioniert es soweit bis auf den wd
#2037036
Lesenswert?

micha s. schrieb:
> eventuell könnte es noch sein da ich recht viele interrupts habe das es
> nie soweit kommt weil er am interruot abarbeiten ist.
> aber in der simulation funktioniert es soweit bis auf den wd

Das wäre denkbar, der WDT Interrupt hat den Vektor 0x0012, also am A. 
der Welt und somit niedrigste Priorität. ;-)
Allerdings würde ich mir dann grundlegend Gedanken machen ob das Design 
sinnvoll ist, wenn das Programm so dermassen viele und lange Interrupts 
abarbeitet.
Gast #2037083
Lesenswert?

lang sind sie nicht, eher im geegnteil sie sind so kurz wie möglich.

es gibt den input capture, T1 ovr, pwm im modus 1 bzw 5 (phase correct), 
dazu noch den T0 overflow (und eventuell noch den ocr0a)
#2037214
Lesenswert?

So geht das:

//Watchdog Interval Timer
  WDTCSR |= (1<<WDCE) | (1<<WDE); //Enable Watchdog(Reset)
  MCUSR &= ~(1<<WDRF);     //Clear WDRF in MCUSR
  WDTCSR |= (1<<WDCE);  //Watchdog Change Enable
  WDTCSR = 0x46;     //Enable Interrupt, Disable Reset, Set Prescaler 1s

Beim Ändern es Watchdogs muß zum Schutz gegen unbeabsichtigtes 
Überschreiben ein bestimmter Ablauf in einer definierten Zeit 
eingehalten werden.

mfg.
Gast #2037219
Lesenswert?

Hi

Also mit dieser Initialisierung, allerdings Assembler:

   ldi r16,(1<<WDCE) | (1<<WDE) ; Start timed sequence
   sts WDTCSR, r16
   ldi r16, 1<<WDE|1<<WDIE|7<<WDP0
   sts WDTCSR, r16
   sei

bekomme ich auf einem ATMega48 genau dein gewünschtes Verhalten: 
Interrupt und danach Reset. Debugt mit AVR Dragon. Den Simulator kannst 
du vergessen. Funktioniert nicht -> Known Issues.

MfG Spess
#2037222
Lesenswert?

micha s. schrieb:
> okay, wie komme ich an die größe des stacks? adresse müsste ja im db
> stehen.

SPH und SPL sind die Stackpointer "Register", diese werden idR auf die 
letzte SRAM Adresse gesetzt, das erledigt der Startup Code der mit 
verlinkt wird. Der SP zählt dann abwärts.

Und doch, das hat dich sehr wohl zu interessiern, wenn dein Stack zu 
groß wird, z.B. durch viele Subroutinen Aufrufe, dann überschreibst du 
damit evtl. Werte im SRAM.

Lies dir mal die Beschreibung des AVR Core durch, ist im DS des 
ATtiny2313 drinne. Dann wirds evtl. bissel klarer.
Gast #2037237
Lesenswert?

so, sollte jetzt so stimmen oder:
- timer an, prescaler lt. define, interrupt an, systemreset deaktivert.

code:
1
// Init watchdog timer as normal timer with interrupt
2
void init_WDT_IRQ(void)
3
{
4
   disable_IRQ();
5
   reset_WDT();
6

7
   WDTCSR |=  (1<<WDCE) | (1<<WDE); // Start timed Sequence
8
   MCUSR  &= ~(1<<WDRF);            // Clear WDRF in MCUSR
9
   WDTCSR |=  (1<<WDCE);            // Watchdog Change Enable
10
   WDTCSR  =  (1<<WDIE)             // Enable Interrupt, Disable Reset 
11
           |  (WD_PRESCALER);       // Set Prescaler
12

13
   enable_IRQ();
14
   WD_cnt  = 0;
15
}

richtig?
Gast #2037275
Lesenswert?

ja das codebeispiel war mal die grundlage zu der init funktion...
soll ich alles in assembler schreiben?
blöde frage wie packe ich mehrere asm befehle in eine funktion?

asm("befehl1",
    "befehl2");
usw oder?
#2037620
Lesenswert?

omg...das macht mir der compiler aus der init funktion...!!!
kann der dads nicht schlauer anstellen??? hilfe...back to the asm roots 
:)
1
71:       {
2
+00000304:   95A8        WDR                      Watchdog reset
3
74:          WDTCSR |=  (1<<WDCE) | (1<<WDE); // Start timed Sequence
4
+00000305:   B581        IN      R24,0x21         In from I/O location
5
+00000306:   6188        ORI     R24,0x18         Logical OR with immediate
6
+00000307:   BD81        OUT     0x21,R24         Out to I/O location
7
75:          MCUSR  &= ~(1<<WDRF);            // Clear WDRF in MCUSR
8
+00000308:   B784        IN      R24,0x34         In from I/O location
9
+00000309:   7F87        ANDI    R24,0xF7         Logical AND with immediate
10
+0000030A:   BF84        OUT     0x34,R24         Out to I/O location
11
76:          WDTCSR |=  (1<<WDCE);            // Watchdog Change Enable
12
+0000030B:   B581        IN      R24,0x21         In from I/O location
13
+0000030C:   6180        ORI     R24,0x10         Logical OR with immediate
14
+0000030D:   BD81        OUT     0x21,R24         Out to I/O location
15
77:          WDTCSR  =  (1<<WDIE)             // Enable Interrupt, Disable Reset
16
+0000030E:   E481        LDI     R24,0x41         Load immediate
17
+0000030F:   BD81        OUT     0x21,R24         Out to I/O location
18
80:          WD_cnt  = 0;
19
+00000310:   921000AF    STS     0x00AF,R1        Store direct to data space
20
81:       }
21
+00000312:   9508        RET                      Subroutine return
Gast #2037716
Lesenswert?

HI

So richtig verstehe ich deine Reihenfolge nicht. Erst WDTCSR ohne 
richtige Aktion, Dann MCUSR. WDRF ist nach Reset gelöscht. Dann wieder 
WDTCSR.

Mach doch einfach mal

   MCUSR  &= ~(1<<WDRF);
   WDTCSR  =  (1<<WDCE) | (1<<WDE);
   WDTCSR  =  (1<<WDE) | (1<<WDIE) | (WD_PRESCALER);

Das Assemblerlisting passt schon. Kürzer kann es C nicht.

MfG Spess
#2037771
Lesenswert?

doch kann es,
register = 0xneuer wert;

WDTCSR  =  (1<<WDCE) | (1<<WDE);
wdce brauchst du wenn du am wd irgendwas ändern willst (lt db)

und wde um den watchdog in der timing sequenz zu starten (auch db)

stimmt den rest von wdtcsr hätte ich in eine zeile schreiben können :)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren