mikrocontroller.net

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


Autor: Thomas Miehling (tm112)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Miehling (tm112)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas Miehling (tm112)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dieter Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas Miehling (tm112)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK. Vielen Dank.

Kleine Frage am Rande:

Müssten die BTFSC nicht durch BTFSS ersetzt werden?

Gruß,
Thomas

Autor: Bernd Rüter (Firma: Promaxx.net) (bigwumpus)
Datum:

Bewertung
0 lesenswert
nicht 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
!

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann den Interrups auch noch verschiedene Prioritäten geben:

org 4

(register sichern)

btfsc INT1FLAG
goto doINT1

btfsc INT2FLAG
goto doINT2

btfsc INTnFLAG
goto doINTn


exitINT:
(register wiederherstellen)
retfie


doINT1:
(ISR)
goto exitINT

doINT2:
(ISR)
goto exitINT

doINTn:
(ISR)
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.