'ISR how to'
Here is something I have been doing with the 73.
Given that an interupt can occur at any given time, and code execution could
be taking place on any page and working with any bank.
What does this mean?
I had found like many others that things with a PIC are not nicely restored
with a RETI.
So we all do the status and w thing, no big deal. But what about rp0 (bank)
and pclath.3 (page)?
Well, the first thing you do in your ISR is clear rp0, now you are safe to
do the status and w thing. But how do you know what rp0 was before you
cleared it? I have heard said, "you can duplicate _copy FR in both banks",
yuck, and I am tight on space. What else can I do?
Hey, hold on a sec. my ISR seems like it is all over the place some times.
I know I have code in page 1 and that the pclath is adjusted appropriately
for calls, lookups etc. This definetly can cause problems executing my ISR
in page 0. Hmm, now it looks like I need to record and restore pclath as
well. Now things are looking ugly.
I need a FR that can be addressed from either bank. That is where I will
store rp0 and pclath.3.
Well, this is how I have been doing it. I use the status register, bits
Any comments welcomed, good/bad, does this help anyone?
;bank = status.7 ;general purpose bit 0=bank 0, 1=bank 1
;page = status.6
:loop clrb gie ;turn off int.
jb gie, :loop
setb bank ;*Recording the
status of rp0
clrb rp0 ;set bank 0 ;*Make sure that you
are accessing the right bank
mov w_copy,w ;*Doing the status and
setb page ;*Recording the
status of pclath
clrb pclath.3 ;*Make sure that
you are accessing the right page
<Work your magic here>
setb pclath.3 ;restore page
setb rp0 ;restore bank
clrb bank ;reset bank flag
DO NOT FORGET
clrb page ;reset page flag
Take care -jim
|On Tue, 19 May 1998 14:14:33 -0700 jhobbs <QUIKNET.COM> writes: jhobbs
The conventional method uses just one more byte, which is "over" the
place where W is stored. Once you have W stored, then the RP0 bit can be
stored along with the rest of the status register.
isrsavew equ 0x20
isrsavewh equ 0xA0 ;Must reserve space here
(isrsavew + 80)
org 4 ;ISR goes here.
movwf isrsavew ;May end up in page 0 or 1.
bcf STATUS,RP0 ;ISR uses page 0 for everything.
>Hey, hold on a sec. my ISR seems like it is all over the place some
>I know I have code in page 1 and that the pclath is adjusted
>for calls, lookups etc. This definetly can cause problems executing
>in page 0. Hmm, now it looks like I need to record and restore pclath
>well. Now things are looking ugly.
One of these:
* Store PCLATH (in page 0) and reset it to 0 before goto, call, etc. The
conventional approach needs 5 instructions and 1 byte RAM.
* Don't let an interrupt occur while PCLATH is out of page 0.
* Don't use any gotos, calls, or PCL modifies in the ISR.
* Put identical copies of all ISR routines that are the target of goto,
call in all code pages. Seems like the best way to do this would be to
write the ISR as a macro and place it at 0x004, 0x804, etc. Uses lots of
code space but no time or RAM.
>I need a FR that can be addressed from either bank. That is where I
>store rp0 and pclath.3.
>;bank = status.7 ;general purpose bit 0=bank 0, 1=bank 1
>;page = status.6
Obviously this won't work with PICs that use these bits for something
else. So some (yet to be released) chips will need another approach.
> org 04h
>:loop clrb gie ;turn off int.
> jb gie, :loop
You don't have to do this. GIE is always cleared by hardware before the
> snb rp0
> setb bank ;*Recording
>status of rp0
If RP0 was zero, the status of 'bank' is indeterminate (it will stay what
it was last time). Somewhere you need to clear bank.
> clrb rp0 ;set bank 0 ;*Make sure that
>are accessing the right bank
> mov w_copy,w ;*Doing the
> mov s_copy,status
Especially when writing ISR code, it helps to use "native" PIC
instructions so it is clear exactly what is happening. But this will
> snb pclath.3
> setb page ;*Recording
>status of pclath
> clrb pclath.3 ;*Make sure
>you are accessing the right page
The same problem with 'bank' will happen with 'page'.
Ok, you're doing it here. I would strongly recommend doing this at the
top of the ISR in case the main program changes these bits to ones for
some reason. Also it will be easier not to forget.
Overall the technique seems to have little advantage (2 RAM locations)
over conventional methods.
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]
|Here's an interrupt entry and exit code for a '74 project:
; .... insert more RAM use declarations ....
rTempW2 ; must also reserve this location to store W
; .... insert more RAM use declarations ....
ORG 4 ; Interrupt vector
movwf rTempW ; save W value (could be in page0 or 1!)
swapf STATUS,W ;
bcf STATUS,RP0 ; set RAM page 0
movwf rTempStatus ; save STATUS value
movfw PCLATH ;
movwf rTempPCLATH ; save PCLATH Value
movfw FSR ;
movwf rTempFSR ; save FSR value
bcf PCLATH,3 ; set program memory page 0
; .... interrupt handling ....
bcf STATUS,RP0 ; be sure RAM page 0 is selected
movfw rTempFSR ;
movwf FSR ; restore FSR value
movfw rTempPCLATH ; restore PCLATH Value
movwf PCLATH ;
swapf rTempStatus,W ; restore W and Status
movwf STATUS ;
swapf rTempW,F ;
swapf rTempW,W ;
retfie ; done with interrupt
This requires five RAM locations, and it takes 20 instruction cycles. If at all
possible, avoid calling subroutines and using the FSR in the interrupt handler.
Sometimes you have to take action on an interrupt as quickly as possible -
context saving eats up valuable time.
PIC interrupt handling cannot be interrupted by a subsequent interrupt, so
clearing GIE is not required. I am not familiar with some of instructions in
your code (is it Parallax assembler?), but it appears that when saving your W
register, you could be altering the STATUS,Z bit.
| Jim, sorry for the late reply. I noticed that you also use the Parallax
assembler. First note that it has been updated as CVASM and is available as
part of the commercial TDE package from Tech Tools. The assembler is free
and now includes support for the 16C76/77 and a few other enhancements. You
can assemble your Parallax code `as-is'. To update to CVASM, download the
TDE demo from:
Back to interrupts and 16C73/74/76/77 devices, I normally use the example
from the 16C7x data book. Obviously you will want to modify it to suit your
application. The following is a `Parallax-friendly' ISR `wrapper' in mostly
; Bank 0 Registers
W_copy DS 1 ; Copy of W Reg for Interrupt Handler
S_copy DS 1 ; Copy of STATUS Reg for Interrupt Handler
PCHcopy DS 1 ; Copy of PCLATH Reg for Interrupt Handler
FSRcopy DS 1 ; Copy of FSR for Interrupt Handler
; Clone W_copy as the first byte in each bank:
ORG 20h ; Bank 1, etc...
W_copy1 DS 1
The last line assumes SPASM v4.7 or earlier. With CVASM, you can use:
ORG 0A0h ; Bank 1, etc...
; Interrupt Handler
MOVWF W_copy ; Copy W to temp
SWAPF STATUS,W ; Swap STATUS to be saved in W
CLRF STATUS ; Switch to Bank 0
MOVWF S_copy ; Copy STATUS to temp
MOVF PCLATH,W ; Copy PCLATH to temp
CLRF PCLATH ; Switch to Page 0
BCF STATUS,7 ; Point IRP to Bank 0
MOVF FSR,W ; Copy FSR to temp
MOVF FSRcopy,W ; Restore FSR
MOVF PCHcopy,W ; Restore PCLATH
SWAPF S_copy,W ; Restore STATUS
SWAPF W_copy,F ; Restore W
Mike Keitz pointed out other `gotchas' and suggestions:
>* Store PCLATH (in page 0) and reset it to 0 before goto, call, etc. The
> conventional approach needs 5 instructions and 1 byte RAM.
>* Don't let an interrupt occur while PCLATH is out of page 0.
>* Don't use any gotos, calls, or PCL modifies in the ISR.
>* Put identical copies of all ISR routines that are the target of goto,
> call in all code pages. Seems like the best way to do this would be to
> write the ISR as a macro and place it at 0x004, 0x804, etc. Uses lots of
> code space but no time or RAM.
At 02:14 PM 5/19/98 -0700, Jim/jhobbs wrote:
>Here is something I have been doing with the 73.
>Given that an interupt can occur at any given time, and code execution could
>be taking place on any page and working with any bank.
>What does this mean?
>Take care -jim
More... (looser matching)
- Last day of these posts
- In 1998
, 1999 only
- New search...