Hallo, Um mehrere Interrupts beim PIC 16F628 nutzen zu können, muss ja eine Auswahl geschehen, welches Ereignis den INT ausgelöst hat, da ja nur ein einziger INT-Vektor existiert. Hier sollen z.B. Timer0, Timer1, RB0 und die RS232 Schnittstelle benützt werden. Wie ist das beste Vorgehen? Ich dachte mir sowas ind er Art: org 0 goto start org 4 ;** Interruptbehandlungsroutinen (Timer, etc.) ** btfsc PIR1, TMR1IF ; Int von Timer1? GOTO intEnde ;Programmcode GOTO intEnde btfsc PIR1, RCIF ; Int von RCIF (RS232 RX)? GOTO intEnde ;Programmcode GOTO intEnde btfsc PIR1, TXIF ; Int von TXIF (RS232 TX)? GOTO intEnde ;Programmcode GOTO intEnde btfsc INTCON, INTF ; Int von RB0? GOTO intEnde ;Programmcode GOTO intEnde btfss INTCON, T0IF ; Int von Timer0? GOTO intEnde ; wenn nicht, intEnde movwf temp_w ;save w & status swapf status,w bcf status,rp0 movwf temp_status ;Programmcode ;----------------------------------------------------- intEnde swapf temp_status,w movwf status swapf temp_w swapf temp_w,w retfie
Gast
#409308
PIC ist nicht so mein Ding, aber normalerweise läuft das so ab: - Register sichern. - Quelle abfragen und entsprechende Routine aufrufen. - Register wiederherstellen und Return. Bei dir sieht das irgendwie andersrum aus.
OK. Richtig.
Der Block
movwf temp_w ;save w & status
swapf status,w
bcf status,rp0
movwf temp_status
muss an den Anfang der Interruptbehandlungsroutine. Mir ging's jetzt
mehr um die Unterscheidung wo der INT herkam, da ja beim PIC nur ein
einzige INT-Vektor (an hex 4) existiert.
Thomas
Hallo nochmal, Nun ist mir grad klar geworden, dass das so nicht gehen kann. Was ich brauche, ist eine Auswahl in der Art von CASE .. OF. Wie geht das in Assembler? Thomas
Gast
#409311
Register sichern. btfsc PIR1, TMR1IF ; Int von Timer1? call timer_interrupt btfsc PIR1, RCIF ; Int von RCIF (RS232 RX)? call rcif_interrupt [...] Register wiederherstellen und Ende. Es sollte allerdings Foren geben, in denen PICs verbreiteter sind als grad hier.
Gast
#409312
Es müssen alle Quellen nacheinander abgefragt werden, nicht gleich nach
intEnde verzweigen wenns nicht der erste schon war.
Beispiel
btfsc PIR1, TMR1IF ; Int von Timer1?
GOTO testRX
;Programmcode
GOTO intEnde
testRX
btfsc PIR1, RCIF ; Int von RCIF (RS232 RX)?
GOTO testTX
;Programmcode
GOTO intEnde
testTX
btfsc PIR1, TXIF ; Int von TXIF (RS232 TX)?
GOTO intEnde
;Programmcode
intEnde
OK. Vielen Dank. Kleine Frage am Rande: Müssten die BTFSC nicht durch BTFSS ersetzt werden? Gruß, Thomas
Ja, <Register sichern> Int0 btfss Int0Flag Goto Int0E <Code> bcf Int0Flag (wird i.d.R. benötigt, siehe jeweiliges Manual) Int0E Int1 btfss Int1Flag Goto Int1E <Code> bcf Int1Flag (wird i.d.R. benötigt, siehe jeweiliges Manual) Int1E <Register herstellen> RETFI Einfach der Reihe nach alle Int-Quellen abklappern. Geht recht schnell !
Gast
#409315
Man kann den Interrups auch noch verschiedene Prioritäten geben:
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 | |
27 | |
28 | |
29 | |
30 | |
Also: INT1 hat die höchste Priorität, INT2 die zweite, und INTn die niedrigste. Das funktioniert weil der PIC den Interruptvektor gleich wieder anspringt wenn noch ein Interruptflag gesetzt ist. Feadi