Gast
#2036873
hallo zusammen, mein wdt löst keinen ionterrupt aus, jemand ne ahnung warum??? µC ist der tiny2313. hier mal der zugehörige code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
|
Anzeige
|
Watchdog timer löst keinen interrupt aus
Gast
#2036873
hallo zusammen, mein wdt löst keinen ionterrupt aus, jemand ne ahnung warum??? µC ist der tiny2313. hier mal der zugehörige code:
Gast
#2036874
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] Weil "WDE" den System Reset einschaltet, würde ich sagen, lass dieses Bit mal 0.
Gast
#2036909
klar ist mir bewusst aber vor dem system reset sollte ja der interrupt einmal ausgeführt werden! Hmm ja stimmt, sorry hatte ich vergessen. Allerdings musst du danach wieder WDIE setzen, sondern ist der nächste Timeout ein Reset, ist dir das auch klar? 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
> 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");
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
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 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
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)
Gast
#2037085
und der icp vector wird ja erst ausgelöst wenn ein flankenwechsel kommt, und das ist im simulator ja nicht der fall.-. Tja, also mit der momentanen Informationslage kann Dir dann aber hier kaum jemand helfen. Mein Vorschlag wäre, dass Du dein Programm auf der Kernproblem reduzierst. Dann kann man weiter sehen. Ansonsten viel mir jetzt noch Stack zu klein ein?
Gast
#2037190
hm wie prüfe ich den stack...?
Gast
#2037191
werd ich aber wie gesagt erst heut abend da ich noch beim arbeiten bin... micha s. schrieb: > hm wie prüfe ich den stack...? Überprüfen ob der Stackpointer in einen SRAM Bereich läuft in dem schon was liegt.
Gast
#2037211
das ist ja eig assembler ebene, sollte mich ja nicht unbedingt interessieren oder? okay, wie komme ich an die größe des stacks? adresse müsste ja im db stehen. 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
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 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
#2037225
super dank euch dreien :)
Gast
#2037237
so, sollte jetzt so stimmen oder: - timer an, prescaler lt. define, interrupt an, systemreset deaktivert. code:
richtig?
Gast
#2037247
Hi
>richtig?
Sieh dir das Assemblerlisting an. Das ganze braucht ein bestimmtes
Timing. Möglicherweise versaut dir C das. Das Codebeispiel aus dem
Datenblatt kennst du?
MfG Spess
micha s. schrieb: > reset_WDT(); Ist an dieser Stelle überflüssig, da der WDT noch gar nicht initialisiert ist. Schadet aber wohl auch nicht. mfg.
Gast
#2037275
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?
Gast
#2037276
übrigens der wd startet immer mit und ist immer aktiv ausser man schaltet ihn ab, also sollte man einen reset durchführen!
Gast
#2037282
Hi
>soll ich alles in assembler schreiben?
Nein. Aber sich mal ansehen, was der Compiler daraus macht.
MfG Spess
Gast
#2037298
mach ich und zum vgl nehm ich mal dein code omg...das macht mir der compiler aus der init funktion...!!! kann der dads nicht schlauer anstellen??? hilfe...back to the asm roots :)
Jaholla... Ja, lieber mit inline Assembler von Hand bauen. Ist ja jetzt auch nicht so schlimm oder? jup das denke ich mir auch... ich mein mal im ernst, optimieren geht anders... werd in zukunft glaub echt lieber die hex oder binär zahlen ins register schreiben (wenns auch unübersichtlicher ist) aber besser als 3 befehle wenn ich ein besch...bit setzen will!
Gast
#2037716
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 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 :)
Gast
#2037782
Hi MCUSR gehört aber nicht zum Watchdog! Das brauchst du nur für WDTCSR. MfG Spess Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|