lecture 10 corrigido - sel.eesc.usp.br
TRANSCRIPT
Interrupts
#include <P16F628A.inc>__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _HS_OSCRES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of programINT_VECT CODE 0x0004 ; interrupt vector
GOTO ISR ; go to interrupt service routine
MAIN_PROG CODE ; let linker place main programSTART
BSF STATUS, RP0 ; go to bank 1CLRF TRISA ; set all PORTA as OUTPUTCLRF TRISB ; set all PORTB as OUTPUTBSF TRISB, 0 ; set RB0 as inputBCF STATUS, RP0 ; go to bank 0MOVLW b'10010000‘ ; Enable External (INT) InterruptMOVWF INTCON ; Global interrupt enabled, INT enabledGOTO MAIN
;Interrupt service routine--------------------------------------------------------ISR
BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineBCF PORTA, 0 ; clear RA.0BCF INTCON, INTF ; Clear external interrupt flag bitBSF INTCON, GIE ; Enable all interrupts on exitRETFIE
;Main routine---------------------------------------------------------------------MAIN
BSF PORTA, 0 ; Set RA.0GOTO MAIN ; Loop infinity while not happens an external interrupt
END
#include <P16F628A.inc>__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _HS_OSCRES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of programINT_VECT CODE 0x0004 ; interrupt vector
GOTO ISR ; go to interrupt service routine
MAIN_PROG CODE ; let linker place main programSTART
BSF STATUS, RP0 ; go to bank 1CLRF TRISA ; set all PORTA as OUTPUTMOVLW 0xFFMOVWF TRISB ; set all PORTB as INPUTBCF STATUS, RP0 ; go to bank 0MOVLW b'10001000‘ ; Enable Interrupt On Change Interrupt (RB)MOVWF INTCON ; Global interrupt enabled, RB enabledGOTO MAIN
;Interrupt service routine--------------------------------------------------------ISR
BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineBCF PORTA, 0 ; clear RA.0BCF INTCON, RBIF ; Clear interrupt on change flag bitBSF INTCON, GIE ; Enable all interrupts on exitRETFIE
;Main routine---------------------------------------------------------------------MAIN
BSF PORTA, 0 ; Set RA.0GOTO MAIN ; Loop infinity while not happens an external interrupt
END
#include <P16F628A.inc>__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _HS_OSCRES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of programINT_VECT CODE 0x0004 ; interrupt vector
GOTO ISR ; go to interrupt service routineMAIN_PROG CODE ; let linker place main programSTART
BSF STATUS, RP0 ; go to bank 1CLRF TRISA ; set all PORTA as OUTPUTMOVLW 0xFFMOVWF TRISB ; set all PORTB as INPUTBCF STATUS, RP0 ; go to bank 0MOVLW b'10011000‘ ; Enable External (INT) and On Change Interrupts (RB)MOVWF INTCON ; Global interrupt enabled, INT and RB enabledGOTO MAIN
;Interrupt service routine--------------------------------------------------------ISR
BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineBCF PORTA, 0 ; clear RA.0BCF INTCON, RBIF ; Clear interrupt on change flag bitBCF INTCON INTF ; Clear external interrupt flag bitBSF INTCON, GIE ; Enable all interrupts on exitRETFIE
;Main routine---------------------------------------------------------------------MAIN
BSF PORTA, 0 ; Set RA.0GOTO MAIN ; Loop infinity while not happens an external interrupt
END
Not necessary if GIE is disabled, eg, if I do: BCF INTCON,GIE
START• • •MOVLW b'10011000‘ ; Enable External (INT) and On Change Interrupts (RB)MOVWF INTCON ; Global interrupt enabled, INT and RB enabledGOTO MAIN• • •
Priority (Interrupt on change) > Priority (External Interrupt)When an interrupt happens, the ISR must:- Disable all interrupts- Save the context (W and STATUS)- Check first the Interrupt on Change Flag (RBIF)
- If it is the case do what is required (CALL RB_ROUTINE)- Clear RBIF- Then check the External interrupt
- If it is also the case CALL INT_ROUTINE- Clear INTF- Retrieve context (W and STATUS)- Reactivate all interrupts- Return from the interrupt (RETFIE)
ISR BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineMOVWF TEMPW ; Save part 1/2 of the context (W)SWAPF STATUS,0 ; Save part 2/2 of the context (STATUS), step 1/2MOVWF TEMPS ; Save part 2/2 of the context (STATUS), step 2/2BTFSC INTCON, RBIF ; Check if the interrupt source was a port change value
; Any one of the RB7:RB4 bits changed?CALL RB_ROUTINE ; Yes! Then do what is suposed by calling RB_ROUTINE
; No! So do nothing.BCF INTCON, RBIF ; Clear the flag associated to Interrupt on changeBTFSC INTCON INTF ; Check if the interrupt source was an external interruptCALL INT_ROUTINE ; Yes! Then do what is suposed by calling INT_ROUTINE
; No! So do nothing.BCF INTCON INTF ; Clear external interrupt flag bitSWAPF TEMPS, 0 ; Retrieve part 1/2 of the context (STATUS), step 1/2MOVWF STATUS ; Retrieve part 1/2 of the context (STATUS), step 2/2MOVF TEMPW, W ; Retrieve part 2/2 of the context (W)BSF INTCON, GIE ; Enable all interrupts inside interrupt service routineRETFIE ; Return to main routine (MAIN)
RB_ROUTINEBCF PORTA, 0 ; Clear RA0RETURN ; Return to ISR TO EXECUTE BCF INTCON,RBIF
INT_ROUTINENOP ; Do nothing (don’t forget that this is an example)RETURN ; Return to ISR TO EXECUTE BCF INTCON,INTF
Concluding remarks
Priority (Interrupt on change) > Priority (External Interrupt)
ISR BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineMOVWF TEMPW ; Save part 1/2 of the context (W)SWAPF STATUS,0 ; Save part 2/2 of the context (STATUS), step 1/2MOVWF TEMPS ; Save part 2/2 of the context (STATUS), step 2/2BTFSC INTCON, RBIF ; Check if the interrupt source was a port change value
; Any one of the RB7:RB4 bits changed?CALL RB_ROUTINE ; Yes! Then do what is suposed by calling RB_ROUTINE
; No! So do nothing.BCF INTCON, RBIF ; Clear the flag associated to Interrupt on changeBTFSC INTCON INTF ; Check if the interrupt source was an external interruptCALL INT_ROUTINE ; Yes! Then do what is suposed by calling INT_ROUTINE
; No! So do nothing.BCF INTCON INTF ; Clear external interrupt flag bit
SWAPF TEMPS, 0 ; Retrieve part 1/2 of the context (STATUS), step 1/2MOVWF STATUS ; Retrieve part 1/2 of the context (STATUS), step 2/2MOVF TEMPW, W ; Retrieve part 2/2 of the context (W)BSF INTCON, GIE ; Enable all interrupts inside interrupt service routineRETFIE ; Return to main routine (MAIN)
If
But, if
Concluding remarks
Priority (Interrupt on change) < Priority (External Interrupt)
ISR BCF INTCON, GIE ; Disable all interrupts inside interrupt service routineMOVWF TEMPW ; Save part 1/2 of the context (W)SWAPF STATUS,0 ; Save part 2/2 of the context (STATUS), step 1/2MOVWF TEMPS ; Save part 2/2 of the context (STATUS), step 2/2BTFSC INTCON INTF ; Check if the interrupt source was an external interruptCALL INT_ROUTINE ; Yes! Then do what is suposed by calling INT_ROUTINE
; No! So do nothing.BCF INTCON INTF ; Clear external interrupt flag bitBTFSC INTCON, RBIF ; Check if the interrupt source was a port change value
; Any one of the RB7:RB4 bits changed?CALL RB_ROUTINE ; Yes! Then do what is suposed by calling RB_ROUTINE
; No! So do nothing.BCF INTCON, RBIF ; Clear the flag associated to Interrupt on change
SWAPF TEMPS, 0 ; Retrieve part 1/2 of the context (STATUS), step 1/2MOVWF STATUS ; Retrieve part 1/2 of the context (STATUS), step 2/2MOVF TEMPW, W ; Retrieve part 2/2 of the context (W)BSF INTCON, GIE ; Enable all interrupts inside interrupt service routineRETFIE ; Return to main routine (MAIN)