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
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
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.
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 !
Man kann den Interrups auch noch verschiedene Prioritäten geben:
1 | org 4 |
2 | |
3 | (register sichern) |
4 | |
5 | btfsc INT1FLAG |
6 | goto doINT1 |
7 | |
8 | btfsc INT2FLAG |
9 | goto doINT2 |
10 | |
11 | btfsc INTnFLAG |
12 | goto doINTn |
13 | |
14 | |
15 | exitINT: |
16 | (register wiederherstellen) |
17 | retfie |
18 | |
19 | |
20 | doINT1: |
21 | (ISR) |
22 | goto exitINT |
23 | |
24 | doINT2: |
25 | (ISR) |
26 | goto exitINT |
27 | |
28 | doINTn: |
29 | (ISR) |
30 | goto exitINT |
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.