'Interrupts on 16C84'
|Seeing as I have spent half a day chasing this bug, I thought I would share
it with you all.
If you write an interrupt handler on a 16C84, then you need to manually
store the W register and STATUS register to ensure they main program doesn't
go wrong. No problem so far. You also may need to store the FSR if used by
the main program and interrupts, as in a FIFO handling situation... Easy...
So at the start of the handler I store W and STATUS, and at the end I
restore STATUS and W.
I forgot that re-loading W would of course change the Z flag !!!
So you must restore STATUS, then restore W, and then set or clear Z
depending on the stored value of STATUS. What a mess...
ARGGGGGGGGGGGGGGGGG! half a day wasted... You learn something new every day.
(_) _| _ . _ _ Tel +44 973 222257 Nokia orange in stock *NOW*. E&OE
( )(_|( |(_|| ) Fax UK 0500 222258 http://www.eaglenet.co.uk/aa/
Moving to Bracknell? large family ? http://www.eaglenet.co.uk/aa/house/
|Adrian Kennard <rhanna.demon.co.uk> wrote: adrian
> Seeing as I have spent half a day chasing this bug, I thought I
> would share it with you all.
> If you write an interrupt handler on a 16C84, then you need to
> manually store the W register and STATUS register to ensure they
> main program doesn't go wrong. .... I forgot that re-loading W would
> of course change the Z flag !!! So you must restore STATUS, then
> restore W, and then set or clear Z depending on the stored value of
> STATUS. What a mess...
Sorry you wasted half a day on this. An easier way is the
following, which is on mmy web page and has been in the Microchip
data books for a couple of years now:
INTW EQU [any page-0 register]
INTS EQU [any page-0 register]
; INTERRUPT SERVICE ROUTINE:
PUSH MOVWF INTW ;SAVE THE W-REGISTER.
SWAPF STATUS,W ;SAVE THE STATUS
MOVWF INTS ;REGISTER.
BCF STATUS,RP0 ;MAKE SURE WE'RE ON
;REGISTER PAGE 0
POP SWAPF INTS,W ;RESTORE THE STATUS
MOVWF STATUS ;REGISTER
SWAPF INTW ;RESTORE THE
SWAPF INTW,W ;W-REGISTER.
RETFIE ;RETURN AND RE-ENABLE
Note that the STATUS register doesn't HAVE to be SWAPFed into and
out of INTS; doing so just keeps the Z flag from being disturbed on
ENTRY to the interrupt handler. I've never needed this feature, but
it doesn't take any more code or time than using MOVFs, so there's
no reason not to do it.
Andrew Warren - ix.netcom.comfastfwd
Fast Forward Engineering, Vista, California
|Adrian Kennard wrote:
> I forgot that re-loading W would of course change the Z flag !!!
> So you must restore STATUS, then restore W, and then set or clear Z
> depending on the stored value of STATUS. What a mess...
Actually, only it's the MOVF reg,W that modifies the Z flag. However,
if you follow the Microchip data sheet (at least the 16C6x one), you'll
see entry and exit code for an interrupt routine that looks something
MOVWF Int_W ;Copy W to a temporay register, (could be either
bank 0 or 1)
SWAPF STATUS,W ;Copy status to be saved into W. Note that a
MOVF clears Z, which
;would be O.K. now but not when we exit the ISR.
BCF STATUS,RP0 ;Point to BANK 0
MOVWF Int_Stat ;Save status in bank 0
;Interrupt routine ...
SWAPF Int_Stat,W ;Get the original status register
MOVWF STATUS ;and restore it. (This also restores the
original bank pointer)
SWAPF Int_W, F ;Restore W with original value. Again, we can't
use a MOVF because
SWAPF Int_W, W ;the Z flagged gets corrupted
RETFIE ;Return from Interrupt
Note that the SWAPF instruction does not affect the Z flag.
You can also check out Andy W's PIC question 44 at:
P.S. Adrian, you're lucky it only took a half a day to find that bug. You must
burned like this once before!
More... (looser matching)
- Last day of these posts
- In 1996
, 1997 only
- New search...