M!ni M0nk3y
17.09.2013, 18:34
Hallo,
ich habe ein Problem mit einer Interruptroutine.
Diese wird nur einmalig ausgeführt (bei RB7 = low) und dann nie wieder.
Der PIC soll eigentlich immer schlafen, es sei denn RB6 oder RB7 wechseln von high zu low - dann soll er eine Routine abarbeiten und wieder einschlafen
Beim ersten Interrupt durch RB7 springt der PIC in das richtige Unterprogramm (im Bsp unten "UP1"), arbeitet es ab und stellt danach komplett seine Arbeit ein. Dann kann ich an RB6 / 7 soviel Pegelwechsel vornehmen wie ich will, es passiert nichts mehr.
Ich habe mal den Quelltext angehängt: Mache ich etwas falsch mit dem Setzen / Rücksetzen der Interruptbits?
Oder habe ich ein Problem mit dem "Einschlafen"?
Danke schonmal für alle Tipps im Voraus!
org 0x0000 ;Startadresse des Prozessors
goto main ;springe in das Hauptprogramm
;************************************************* *********************
;-----------Interrupt-Service-Routine---------------
org 0x4 ; Startadresse ISR
;Interruptroutine
bcf INTCON,GIE
bcf INTCON,RBIE ; PortB Interrupt verbieten
bcf INTCON,RBIF
movwf w_copy ; Arbeitsregister retten
swapf STATUS,w ; Status retten
movfw s_copy ; statusregister retten
btfss PORTB,7 ;Wenn Eingang AB=0 überspringe nächsten Befehl
call UP1 ;Rufe UP AB_Setzen auf
btfss PORTB.6 ;Wenn Eingang AB=0 überspringe nächsten Befehl
call UP2 ;Rufe UP AB_Setzen auf
swapf s_copy,w ; STATUS zurückholen
movwf STATUS ; Status aus dem Arbeitsregister in die Speicherzelle schreiben
swapf w_copy,f ; w zurück mit flags
swapf w_copy,w
bsf INTCON, RBIE ; RBIF kann wecken
bcf INTCON, RBIF
bsf INTCON, GIE
retfie ; ISR verlassen
; Hauptprogramm
main: ;Initialisierung
clrf PORTA ; PortA löschen
clrf PORTB ; PortB löschen
bsf STATUS,RP0 ; Umschalten auf Bank1
movlw B'00011111' ;
movwf TRISA ; RA0-RA4 als Eingang definieren
movlw B'11000111' ;
movwf TRISB ; RB0-2=Eingang; RB3-5= Ausgang; RB6&7=Eingang
bcf OPTION_REG, 7
bcf STATUS,RP0 ; Umschalteten auf Bank0
clrf INTCON ; GIE aus
bsf INTCON, RBIE ; RBIF kann wecken
bcf INTCON, RBIF
bsf INTCON, GIE
sleeploop
sleep
nop
goto sleeploop
ich habe ein Problem mit einer Interruptroutine.
Diese wird nur einmalig ausgeführt (bei RB7 = low) und dann nie wieder.
Der PIC soll eigentlich immer schlafen, es sei denn RB6 oder RB7 wechseln von high zu low - dann soll er eine Routine abarbeiten und wieder einschlafen
Beim ersten Interrupt durch RB7 springt der PIC in das richtige Unterprogramm (im Bsp unten "UP1"), arbeitet es ab und stellt danach komplett seine Arbeit ein. Dann kann ich an RB6 / 7 soviel Pegelwechsel vornehmen wie ich will, es passiert nichts mehr.
Ich habe mal den Quelltext angehängt: Mache ich etwas falsch mit dem Setzen / Rücksetzen der Interruptbits?
Oder habe ich ein Problem mit dem "Einschlafen"?
Danke schonmal für alle Tipps im Voraus!
org 0x0000 ;Startadresse des Prozessors
goto main ;springe in das Hauptprogramm
;************************************************* *********************
;-----------Interrupt-Service-Routine---------------
org 0x4 ; Startadresse ISR
;Interruptroutine
bcf INTCON,GIE
bcf INTCON,RBIE ; PortB Interrupt verbieten
bcf INTCON,RBIF
movwf w_copy ; Arbeitsregister retten
swapf STATUS,w ; Status retten
movfw s_copy ; statusregister retten
btfss PORTB,7 ;Wenn Eingang AB=0 überspringe nächsten Befehl
call UP1 ;Rufe UP AB_Setzen auf
btfss PORTB.6 ;Wenn Eingang AB=0 überspringe nächsten Befehl
call UP2 ;Rufe UP AB_Setzen auf
swapf s_copy,w ; STATUS zurückholen
movwf STATUS ; Status aus dem Arbeitsregister in die Speicherzelle schreiben
swapf w_copy,f ; w zurück mit flags
swapf w_copy,w
bsf INTCON, RBIE ; RBIF kann wecken
bcf INTCON, RBIF
bsf INTCON, GIE
retfie ; ISR verlassen
; Hauptprogramm
main: ;Initialisierung
clrf PORTA ; PortA löschen
clrf PORTB ; PortB löschen
bsf STATUS,RP0 ; Umschalten auf Bank1
movlw B'00011111' ;
movwf TRISA ; RA0-RA4 als Eingang definieren
movlw B'11000111' ;
movwf TRISB ; RB0-2=Eingang; RB3-5= Ausgang; RB6&7=Eingang
bcf OPTION_REG, 7
bcf STATUS,RP0 ; Umschalteten auf Bank0
clrf INTCON ; GIE aus
bsf INTCON, RBIE ; RBIF kann wecken
bcf INTCON, RBIF
bsf INTCON, GIE
sleeploop
sleep
nop
goto sleeploop