And most people don't realize it, but you can have an interrupt on *ANY* pin - sort of. This is handy when you have a switch that simply must be read and it is on port C, for example.
Just run a high-speed interrupt on TMR0 and read whatever pins you want inside the ISR. I typically run a 1mSec interrupt.
A small example of an "interrupt header"
Code:
PreloadH VAR BYTE BANKA SYSTEM
PreloadL VAR BYTE BANKA SYSTEM
MasterClock VAR WORD BANKA SYSTEM
ButtonFlag var BYTE BANKA SYSTEM
PreloadH= $D8
PreloadL = $F7 ; 1 mSec@40Mhz
T0CON = %10001000 ; Timer ON, no prescaler
'---------------------------------- --------------------------------
INCLUDE "DT_INTS-18.bas"
' INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, MainTimer, ASM, yes
; INT_Handler RX1_INT, GetChar, PBP, yes
endm
INT_CREATE
ENDASM
Goto OverInt
'---[INT - interrupt handler]---------------------------------------------------
Asm
MainTimer
movff PreloadH,TMR0H ; Preload depends on clk speed
movff PreloadL,TMR0L
clrf INTCON,2
infsnz MasterClock
incf MasterClock + 1
btfss PORTC,4
bsf ButtonFlag,0
@ INT_RETURN
ENDASM
OverInt:
ButtonFlag = 0
MasterClock = 0
INTCON =%11100000 ; just to be certain!
@ INT_ENABLE TMR0_INT
Your program here
This particular code will increment MasterClock at a 1000Hz rate (1 ms / count). You can read it at any time, although you should either disable INTs when you test it, or only test that it is ABOVE (not equal to) a value, since it is a 16 bit var and can increment in the middle of a PBP read.
ButtonFlag.0 will be set any time after someone has pressed a button bringing PORTC.4 to GND. You can read it anytime, then clear it in your main code.
If you have more complicated things to do on an interrupt, you can write it in PBP.
So THERE! mister_e and pxidr84!
Bookmarks