Datasheet

© 2007 Microchip Technology Inc. DS80202G-page 5
PIC18F2585/2680/4585/4680
19. Module: Interrupts
If an interrupt occurs during a two-cycle instruction
that modifies the STATUS, BSR or WREG register,
the unmodified value of the register will be saved
to the corresponding Fast Return (Shadow)
register. Upon a fast return from the interrupt, the
unmodified value will be restored to the STATUS,
BSR or WREG register.
For example, if a high priority interrupt occurs dur-
ing the instruction “MOVFF TEMP, WREG”, the
MOVFF instruction will be completed and WREG
will be loaded with the value of TEMP before
branching to ISR. However, the previous value of
WREG will be saved to the Fast Return register
during ISR branching. Upon return from the inter-
rupt with a fast return, the previous value of WREG
in the Fast Return register will be written to WREG.
This results in WREG containing the value it had
before execution of MOVFF TEMP, WREG.
Affected instructions are:
MOVFF Fs, Fd
where Fd is WREG, BSR or STATUS;
MOVSF Zs, Fd
where Fd is WREG, BSR or STATUS; and
MOVSS [Zs], [Zd]
where the destination is WREG, BSR or STATUS.
Work around
1. Assembly Language Programming:
a) If any two-cycle instruction is used to
modify the WREG, BSR or STATUS
register, do not use the RETFIE FAST
instruction to return from the interrupt.
Instead, save/restore WREG, BSR and
STATUS via software per Example 8-1
in the Device Data Sheet. Alternatively,
in the case of MOVFF, use the MOVF
instruction to write to WREG instead.
For example, use:
MOVF TEMP, W
MOVWF BSR
instead of MOVFF TEMP, BSR.
b) As another alternative, the following
work around shown in Example 2 can
be used. This example overwrites the
Fast Return register by making a
dummy call to Foo with the fast option
in the high priority service routine.
EXAMPLE 2:
2. C Language Programming: The exact work
around depends on the compiler in use. Please
refer to your C compiler documentation for
more details.
If using the Microchip MPLAB
®
C18 C Compiler,
define both high and low priority interrupt han-
dler functions as “low priority” by using the
pragma interruptlow directive.
This directive instructs the compiler to not use
the RETFIE FAST instruction. If the proper high
priority interrupt bit is set in the IPRx register,
then the interrupt is treated as high priority in
spite of the pragma interruptlow directive.
The code segment, shown in Example 3 on the
next page, demonstrates the work around
using the C18 compiler.
ISR @ 0x0008
CALL Foo, FAST ; store current value of WREG, BSR, STATUS for a second time
Foo:
POP ; clears return address of Foo call
: ; insert high priority ISR code here
:
RETFIE FAST