PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pin-Change-Int.. ISR soll trotzdem unterbrechbar sein! Wie?



0tes_Gesetz
26.09.2005, 13:57
Hi.

Die Frage ist wahrscheinlich in einem Satz beantwortet..

Ich hab einen Pin-Change-Interrupt und möchte daraufhin gerne bestimmten Code ablaufen lassen (Werte auslesen, berechnen, Daten senden). Dieser Code soll aber jederzeit von einem Timer-Interrupt zwecks genauer Zählung des Overflows unterbrochen werden können..

Nehm ich da so eine "Sub-Prozedur" (mit Call Sub usw..)?

Wie ruf ich die mit meinem Pin-Change-Interrupt auf, ohne diese Sub-Prozedur UN-unterbrechbar für den Timer-Interrupt zu machen?

Gruß und Dank
Nico

PicNick
26.09.2005, 15:07
Ich mach das immer so, daß der Pinchange-Interrupt eigentlich nur einen Schalter setzt, daß er da war. In der Hauptschleife wird zyklisch der Schalter abgefragt, wenn gesetzt, wird er gelöscht und es läuft eben alles Mögliche ab. Dadurch können alle Interrupts normal unterbrechen, ohne wem anderen auf die Zehen zu treten.
(Überhaupt, wenn diese Sub's auch daten senden, was ja dauert, kann ich die das Verfahren nur empfehlen)

0tes_Gesetz
26.09.2005, 21:38
Ja, das klingt gut..
Werd ich versuchen zu machen.

Danke und Gruß
Nico

Werner_Just
27.09.2005, 10:07
Hallo Nico,

> Wie ruf ich die mit meinem Pin-Change-Interrupt auf, ohne diese
> Sub-Prozedur UN-unterbrechbar für den Timer-Interrupt zu machen?

eine Möglichkeit ist, Du schaltest im Pin-Change-Interrupt einfach Global-Interrupt-enable wieder frei.

Zu beachten dabei ist, dass BASCOM standardmäßig fast alle Register beim Interruptaufruf sichert. Du mußt die Stackgrößen also drastisch vergrößern oder alle anderen Interrupts mit "Nosave" declarieren und Dich von Hand um das sichern der Register kümmern.

Ciao,
Werner

0tes_Gesetz
27.09.2005, 14:12
Ich habs so gemacht wie PcNick das vorgeschlagen hat..

Hier mal der kommentierte Code:


Dim Iwashere As Bit
Iwashere = 0

On PCINT Unterbrecher 'ATtiny2313 PinChangeInt (µC spezifisch!!!)
Enable Interrupts

Unterbrecher: 'Interrupt-Routine "Unterbrecher"
Speed = Timer0 'Wert von Timer0 wird ausgelesen
Toggle Iwashere 'Schalter wird gesetzt für
'Hauptprogrammabfrage
Return

Do 'Start Hauptprogramm
If Iwashere = 1 Then 'Abfrage ob Interrupt "Unterbrecher"
'stattgefunden hat..

'...Das Hauptprogramm läuft hier..

Toggle Iwashere 'Schalter zurückstellen mit dem wir
'hergekommen sind
End If
Loop

Denke, dass das so geht..

Das Toggle hab ich gemacht, weil ich mir einbilde (Aussage ohne Gewähr!), dass es wohl schneller (vom Programmablauf) ist, als wenn ich jeweils Var = 1 bzw. Var =0 schreibe..
Kann da nochmal jemand was zu schreiben bitte?

Danke trotzdem für die Idee mit dem Register - kann man sich ja merken für später ;-)

Gruß
Nico

PicNick
27.09.2005, 14:23
AN sich ok.
Zwei Dinge:
Die Routine "unterbrecher" mußt du HINTEN anhängen, sonst wird sie vor Do..Loop durchlaufen (is nicht wie bei C)
Das Hantieren mit Bits ist bei Bascom nicht gar so super gelöst. Das Schnellste ist tatsächlich das Byte setzen/abfragen.

Variante mit "ISR enable": Wenn es ausser den beiden keinen Interrupt gibt, ist das auch ok. Ansonsten hast du ja gelesen, was du alles berücksichtigen mußt, und bei komplexeren Programmen ist das so'n Ding. Je tricky, desto anfälliger

0tes_Gesetz
27.09.2005, 14:57
...Rountinen nach hinten? Ok, hab ich gemacht. Danke

...Var=1/0 setzen anstatt toggle? Ok, auch umgeeselt. Danke.

...Variante "ISR enable" lass ich mal besser weg, da da doch noch ein bisschen mehr abläuft und ich wie man wohl merkt noch kein Freak bin, der sich "auskennt". ;-)

Also besten Dank nochmal für die Hinweise.

Gruß
Nico