You are on page 1of 22

Interrupts

How to do 2 things at the same time

Need for interrupts


Computers often have to deal with asynchronous events. That is to say events that occur times that are unpredictable relative to the rest of your program. Whilst a computer is busy running a program something unexpected may occur:
A packet may arrive on a communications line A key may be pressed A clock tic occurs

Alternative- Polling
One alternative is to have your program running a loop checking for input/output events. This is called Polling. It is what all the examples so far have done. Polling wastes processor resources checking for events that rarely happen Polling makes it hard to get the computer to do any useful work.

Idea of interrupts
Main program
repeat Do this press Do that Try something else For ages

Interrupt handler
Key pressed read input port store result return

Interrupts occur between two instructions. Control is transferred by the hardware to an interrupt location. The interrupt routine does its stuff It then returns to the following instruction in the main program.

An interrupt is a procedure called by the hardware of the computer rather than by your program.

Interrupt control registers

Intcon
ENABLES
FLAGS

global interupt enable

GP port change interrupt INT pin interrupt TMR0 overflow interrupt

GP port change interrupt INT pin interrupt TMR0 overflow interrupt

what happens
When an interrupt is serviced: The GIE is cleared to disable any further interrupt The return address is pushed onto the stack The PC is loaded with 0004h Once in the Interrupt Service Routine, the source(s) of the interrupt can be determined by polling the interrupt flag bits. The interrupt flag bit(s) must be cleared in software before re-enabling interrupts to avoid GP2/ INT recursive interrupts.

Interrupts on the PIC


Context Saving During Interrupts During an interrupt, only the return PC value is saved on the stack. Typically, users may wish to save key registers during an interrupt, e.g., W register and STATUS register. This must be implemented in software.

timing of interrupt

Vectors
Reset vector, where we start on powerup Interrupt vector where we go on an interrupt
memory
Goto main 0 1 2 3 4

Goto isr

Sample start of program


ORG goto ORG goto 0x000 Init 0x004 isr ; processor reset vector ; go to beginning of program ; Interrupt vector location ; go to interrupt routine

Save context
Registers that are used by the interrupt routine must always be saved. Program counter saved automatically but there are some you must save: W reg STATUS reg 3 PCLATH reg 10 FSR reg 4

Save registers
Isr
;Interrupt Vector - Interrupt Sources Used: ; 1. 2. TIMER0 Overflow GP3 Pin-Change

movwf movf clrf movwf movf movwf movf movwf BANK1

WTEMP STATUS,w STATUS STATUSTEMP PCLATH,w PCLATHTEMP FSR,w FSRTEMP

;Save current W register ;Force to page0 ;Save STATUS in STATUSTEMP ;Save PCLATH ;Save FSR ;select bank 1

Determine source
We next need to inspect the interrupt flags to see what device caused the interrupt: TOIF Timer Overflow Interrupt Flag = bit 2 of INTCON GPIF Gpio interrupt flag= bit 0 of intcon

Check what is enabled


We only need to test these flags if they are enabled. This means we must first check the relevant interrupt enable bits

Interrupt Source Checks


;**************************************************************************** ;**************************************************************************** Timer0InterruptCheck btfss INTCON,TOIE ;Is T0IE Set? goto Next1 ;No ;Yes btfsc INTCON,TOIF ;Is TOIF Set? goto Timer0Interrupt ;Yes Next1 GPIFInterruptCheck btfss INTCON,GPIE ;Is GPIE Set? goto Next2 ;No btfsc INTCON,GPIF ;Yes ;Is GPIF Set? goto GPIFInterrupt ;Yes

Interrupt Source Code


Timer0Interrupt call Display bcf INTCON,T0IF ;Update LED Array ;Clear TMR0 Interrupt Flag ; this prevents interrupt ; from occuring again ; spuriously

goto EndIsr

Restore old registers


Finally we must restore any saved registers There is a particular problem with this because of the fact that our saving code may change the flags in the status register This requires care to get round

Cleanup code
EndIsr clrf movf movwf movf movwf movf movwf swapf swapf STATUS ;Select Bank0 FSRTEMP,w FSR ;Restore FSR PCLATHTEMP,w PCLATH ;Restore PCLATH STATUSTEMP,w STATUS ;Restore STATUS WTEMP,f WTEMP,w ;Restore W without ; corrupting STATUS bits ;Return from interrupt

retfie

Swapf
This is defined to do the following:
SWAPF f,d Swap halves f f(0:3)<->f(4:7)->d
It does not alter the z flag of the status register
swapf
swapf

WTEMP,f
WTEMP,w

swap halves of wtemp


swap again and store in W

Net result is that W contains original form of wtemp

You might also like