Problem mit Interrupt an PIC

Gast #747371
Lesenswert?

Hallo!

Mein Problem ist, dass nach einmaligem Durchlauf des Interrupts dieser 
mit RETFIE irgendwie immer an die falsche Stelle im Programm 
zurückspringt. Eigendlich sollte doch wieder die endlosschleife 
gestartet werden. Bin irgendwie am verzweifeln. Sitze schon fast 3 
Stunden dabei. Ich hoffe ihr könnt mir einen Tipp geben! Vielen Dank 
schonmal im Voraus!
greetz,

Sebi


Hier mein Programm:
list p=16f627

; Taktquelle: 4 MHz
;
;**************************************************************
; Includedatei für den 16F627 einbinden
 #include <P16f627.INC>

; Configuration festlegen
; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator

        __CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC

;**************************************************************
; Variablennamen vergeben

w_copy  Equ    0x30               ; Backup für Akkuregister
s_copy  Equ    0x31               ; Backup für Statusregister
loops   Equ     0x22            ; Zähler für Warteschleife
loops2  Equ     0x23            ; Zähler für Warteschleife
kontrolle   Equ     0x24            ; Kontrollbit

;**************************************************************
; los gehts mit dem Programm

        org    0
        goto   Init               ; Sprung zum Hauptprogramm

;**************************************************************
; die Interruptserviceroutine

        org  4
intvec
    movwf   w_copy
    swapf   STATUS,w
    bcf     STATUS, RP0       ; status_temp in Bank 0
    movwf   s_copy

  call pruefung


Int_end
  bcf    INTCON, INTF       ; RB0-Interrupt-Flag löschen
    swapf   s_copy,w
    movwf   STATUS
    swapf   w_copy,f
    swapf   w_copy,w
    RETFIE

;**************************************************************



pruefung
    BTFSC  kontrolle, 0    ;Prüfen, ob das Gerät läuft
    call  ausschalten    ;wenn es läuft, dann ausschalten
        call  anschalten





anschalten
    BSF    PORTA, 0           ; Gerät schalten
    call  Wait250
    BCF    PORTA, 0
    BSF    kontrolle, 0        ;Kontrollbit setzen
    goto  Int_end


ausschalten
    BSF    PORTA, 0           ; Gerät schalten
    call  Wait250
    BCF    PORTA, 0
    BCF    kontrolle, 0        ;Kontrollbit entfernen
    goto  loop


; Warteschleife 250 ms
Wait250
        movlw   D'1'          ; 250 ms Pause
        movwf   loops
Wai
        movlw   .110           ; Zeitkonstante für 1ms
        movwf   loops2
Wai2    nop
        nop
        nop
        nop
        nop
        nop
        decfsz  loops2, F      ; 1 ms vorbei?
        goto    Wai2           ; nein, noch nicht
                               ;
        decfsz  loops, F       ; 250 ms vorbei?
        goto    Wai            ; nein, noch nicht
        Return

; das Hauptprogramm

Init
; Port RA0 auf Ausgabe stellen
        clrf   PORTA              ; LED aus
        bsf    STATUS, RP0        ; auf Bank 1 umschalten
        movlw  B'11111110'        ; PortA RA0 output
        movwf  TRISA
        bcf    STATUS, RP0        ; auf Bank 0 zurückschalten

; RB0-Interrupt einstellen
        bsf    STATUS, RP0        ; auf Bank 1 umschalten
        bsf    OPTION_REG, INTEDG ; 0-1-Flanke an RB0
        bcf    STATUS, RP0        ; auf Bank 0 zurückschalten

        bsf    INTCON, INTE       ; RB0-interrupt erlauben
        bsf    INTCON, GIE        ; Interrupt generell erlauben

loop    goto   loop               ; eine Endlosschleife
;**********************************************************

        end
Gast #751731
Lesenswert?

>Keine Calls innerhalb der Interruptroutine. Das geht nicht!

Unfug! Natürlich geht das.

Nur (wie immer): Zu jedem CALL gehört ein RETURN. Man darf eben 
nicht mit CALL eine Routine aufrufen und aus dieser mit GOTO wieder 
herrausspringen. Bei jedem CALL wird die Rücksprungadresse auf dem 
Call-Stack abgelegt, und diese wird mit dem nächsten RETURN wieder 
abgeholt. Einzig auf die Größe des Call-Stacks ist zu achten (ich glaube 
der liegt bei 8 Adressen)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren