Forum: Mikrocontroller und Digitale Elektronik Grundsätzliche Frage zur Interruptbehandlung beim PIC


von Thomas M. (tm112)


Lesenswert?

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

von A.K. (Gast)


Lesenswert?

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.

von Thomas M. (tm112)


Lesenswert?

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

von Thomas M. (tm112)


Lesenswert?

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

von A.K. (Gast)


Lesenswert?

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.

von Dieter Werner (Gast)


Lesenswert?

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

von Thomas M. (tm112)


Lesenswert?

OK. Vielen Dank.

Kleine Frage am Rande:

Müssten die BTFSC nicht durch BTFSS ersetzt werden?

Gruß,
Thomas

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

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
!

von Feadi (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.