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]
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. ;-)
> 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.
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.
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)
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?
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.
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.
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
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?
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!
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 :)