Kannst du nicht einfach in der Isr_Int0 die Timer ISR aufrufen:
Isr_int0:
Waitms 10
gosub Isr_Timer0
Return
Gruß
Rolf
Ich habe noch ein Problem:
Ich muss einen Timer-Interrupt unter bestimmten Umständen zwischendurch "erzwingen", d.h. zwischen zwei Überläufen. Der Grundrhythmus darf sich dabei aber nicht verschieben. Im Datenblatt habe ich gelesen, dass man dazu nur das Overflow-Flag setzen muss, und schon soll der Interrupt ausgeführt werden (vorausgesetzt, der spezielle und die Interrupts im allgemeinen sind freigegeben).
Um das zu probieren, habe ich mal folgenden Code geschrieben: Timer1 toggelt eine LED alle ca. 1,5 Sekunden. Ein Taster löst INT0 aus, in dessen ISR das Overflow-Flag von Timer1 (TIFR.2) gesetzt wird.
Die LED blinkt zwar stabil im 1,5-Sekundentakt - auf Tastendruck passiert aber gar nichts Die INT0-ISR wird dabei korrekt angesprungen (ich habe in der ISR versuchsweise mal eine andere LED toggeln lassen - das geschieht bei jedem Tastendruck einwandfrei).Code:$regfile = "m8def.dat" $crystal = 1000000 $hwstack = 128 $swstack = 128 $framesize = 160 Ddrb.0 = 1 'LED-Ausgang Portd.2 = 1 'PullUp Config Timer1 = Timer , Prescale = 1024 Timer1 = 64000 'Überlauf alle ca. 1,5 Sek. On Timer1 Isr_timer1 Enable Timer1 Config Int0 = Falling 'Taste gegen Masse On Int0 Isr_int0 Enable Int0 Enable Interrupts Do Loop Isr_timer1: Toggle Portb.0 Timer1 = 64000 Return Isr_int0: 'Tastendruck: Waitms 10 'Prellen abwarten (ich weiß - schlechter Stil...) Tifr.2 = 0 'Timer1-Overflow-Flag setzen Return
Was mach´ ich falsch???
Kannst du nicht einfach in der Isr_Int0 die Timer ISR aufrufen:
Isr_int0:
Waitms 10
gosub Isr_Timer0
Return
Gruß
Rolf
Hmmm.. da hatte ich auch schon drüber nachgedacht. In der "richtigen" Anwendung (wo nicht nur ´ne LED blinkt) hatte ich etwas Bedenken, eine ISR aus einer anderen ISR anzuspringen.
Zugegebenermaßen funktioniert´s im Blink-Code einwandfrei. Die Geschichte mit dem Flag schien mir zwar elegant, aber wenn´s auch anders funktioniert... Werde es morgen einfach mal in der eigentlichen Anwendung testen.
Danke für den Tip - aber wenn doch noch jemand wissen sollte, wie man mit dem TOV1-Flag korrekt umgeht, bin ich weiterhin interessiert!
Gruß,
Daniel
ups .. was lese ich denn da ?
INTERRUPTS ERZWINGEN ?
das hat mich nachdenklich gemacht, ob man diese ints denn erzwingen kann, obwohl sie ja schon erzwungen sind.
evt. istv die fragestellung falsch!
Interuupts sind ja erzwungene unterbrechungen des hauptprogrammes mit höherer priorität als das hauptprogramm.
im datenblatt gibt es doch eine liste der prioritäten der einzelnen ints.
wenn höherwertige disabled sind, würde doch dein timer der höherwetigste sein.
oder nicht ?
gruss klaus
Guter Einwand, guter Einwand... zumal das Gegenteil von "erzwungen" ja so etwas wie "freiwillig" ist - und schon wären wir bei der Frage, ob ein ATMega8 einen freien Willen haben kann...das hat mich nachdenklich gemacht, ob man diese ints denn erzwingen kann, obwohl sie ja schon erzwungen sind.
evt. istv die fragestellung falsch!
Deshalb hier nochmal der komprimierte, auf den Punkt gebrachte Kern meiner (vielleicht etwas wirr formulierten) Frage:
Wie kann ich die Timer-Overflow-ISR ausführen lasssen, ohne dass der Timer überläuft?
Oder die INT0-ISR ohne die dafür nötige Pegeländerung?
Oder die ADC-Complete-ISR ohne eine vollendete AD-Wandlung?
(to be continued)
Die einzelnen Interrupts kommen sich dabei nicht in die Quere, so dass deren Priorität in diesem ganz speziellen Fall eine eher untergeordnete Rolle spielt.
Technisch gesehen kannst du hemmungslos die ISR-Routine mit GOSUB aufrufen. Dem eigentlichen Timer-Counter is das im Grunde egal.
Nur wird ja deine ISR-Routine wohl den Timer-Preload setzen, und das is natürlich weniger gut.
Ausserdem ist die PUSH /POP Orgie einer ISR auch eher unnötig, also überleg' dir, ob das in dieser Form wirklich notwendig ist.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Okay, ich sehe schon, dass die Gosub-Lösung wohl wirklich die beste ist. Dass das den Timer als solchen stört war auch nicht meine Sorge, sondern eher eine "Aufhänge"-Problematik von wegen verschachtelten Sprüngen. Aber das scheint bei ausreichendem Stack ja kein Problem zu sein.
Und den Timer-Preset kann man ja auch relativ einfach von einem gesetzten bzw. geclearten Flag-Bit abhängig machen.
Trotzdem wundert es mich, weshalb das Setzen des TOV1-Flags keinen Interrupt bewirkt...
in C hätt ich einfach das FOC bit im TCCR gesetzt (habs aber bei mir auch so gelöst, dass ich einfach ne methode aufrufe, die cih bei bedarf direkt aus der hauptroutine aufrufe)
PS: das steht aber auch im datenblatt, dass das setzen des flags nicht geht, sondern explizit FOC benutz werden muss, denn treffender weise heisst das flag Force Output Compare (erzwinge output compare) ^^
Auch in Bascom könnte man ja ohne weiteres das FOC-Bit setzen - so weit so gut. Aber ich brauche einen außerplanmäßigen Timer-Overflow-Interrupt, und nicht den Output-Compare-Interrupt. Und das sind ja nun mal zwei Paar Schuhe.
Zum TOV1-Flag habe ich nur folgendes gefunden:
TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location.
Und so dachte ich mir halt, dass sich das Flag auch manuell setzen lassen müsste, wenn man es schon manuell löschen kann.
An welcher Stelle hast Du denn den Hinweis gefunden, dass man dieses Flag nicht einfach so setzten kann?
(Blöd, aber solche Dinge lassen mir einfach keine Ruhe, auch wenn das eigentliche Problem schon längst gelöst ist...)
oh dass du den overflow meinst, ist mir glatt entgangen >_<
das problem ist, dass dieses bit mit dem schreiber einer 1 in sein register gelöscht wird, beim schreiben einer 0 wird der wert nicht verändert!
also wenn das bit den wert x hat und du einen 0 reinschreibst, hat es immernoch den wert x, schreibst du eine 1 rein, hat das bit anschliessend den wert 0!
das dient dazu, dass du das bit verändern kannst(schreiben einer 1), dich aber nciht um seinen ursprünglichen zustand kümmern musst, sondern einfach das bit auf 0 lässt wenn du andere bits des registers bearbeitest... das wird bei einigen anderen registern auch so gehandhabt, da stand auch irgendwo ne kurzerklärung zu
Lesezeichen