PDA

View Full Version : 16F877a ASM Interrupt Confused



modifyit
- 19th September 2005, 02:02
I've been trying to get a handle on how to write an assembly interrupt, but I feel like I am missing something simple.

The example given in the Pic Basic Pro manual makes sense, but I'm not sure exactly what to do since the 877a has 4 banks of RAM. I realize I need to save the W and Status register and that I am supposed to reserve a system variable in each bank similar to the following:

--------------
wsave var byte $20 system
wsave1 var byte $a0 system ' If device has RAM in bank1
wsave2 var byte $120 system ' If device has RAM in bank2
wsave3 var byte $1a0 system ' If device has RAM in bank3
--------------
The following is the example given in the PBP manual, but it appears it is an example for a chip with a single bank of RAM. How do I convert the following code so it will work on the 877a and save "wsave1" and "wsave2" etc when needed?

--------------
' Assembly language interrupt example

led var PORTB.1

wsave var byte $20 system
ssave var byte bank0 system
psave var byte bank0 system


Goto start ' Skip around interrupt handler

' Define interrupt handler
define INTHAND myint

' Assembly language interrupt handler
asm
; Save W, STATUS and PCLATH registers
myint movwf wsave
swapf STATUS, W
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave

; Insert interrupt code here
; Save and restore FSR if used

bsf _led ; Turn on LED (for example)

; Restore PCLATH, STATUS and W registers
movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W
retfie
endasm

' PICBASIC PRO™ program starts here
start: Low led ' Turn LED off

' Enable interrupt on PORTB.0
INTCON = %10010000

loop: Goto loop ' Wait here till interrupted
--------------

Thanks in advance for any help

mister_e
- 19th September 2005, 02:24
Each PIC datasheet explain black on white how to save the context variable.

PIC16F877a section 14.12

Darrel Taylor
- 19th September 2005, 02:35
For a 16F877A, and for many others, it's very simple.

Just change the $20 to $70.

There is a small amount of ram space that is common between all BANKS.   It ranges from $70 to $7F.   Any one of those locations can be used.

That way you don't need the wsave1 - wsave3 stuff
<br>

modifyit
- 19th September 2005, 02:42
Here is the code example from the 877a data sheet:


--------
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into W
CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
MOVF PCLATH, W ;Only required if using pages 1, 2 and/or 3
MOVWF PCLATH_TEMP ;Save PCLATH into W
CLRF PCLATH ;Page zero, regardless of current page
:
:(ISR) ;(Insert user code here)
:
MOVF PCLATH_TEMP, W ;Restore PCLATH
MOVWF PCLATH ;Move W into PCLATH
SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
;(sets bank to original state)
MOVWF STATUS ;Move W into STATUS register
SWAPF W_TEMP,F ;Swap W_TEMP
SWAPF W_TEMP,W ;Swap W_TEMP into W
--------

I guess my question is if I define the following variables at the begining of my PBP code:


w_temp var byte $20 system
w_temp1 var byte $a0 system ' If device has RAM in bank1
w_temp2 var byte $120 system ' If device has RAM in bank2
w_temp3 var byte $1a0 system ' If device has RAM in bank3


how do I tell if I am in bank 0,1,2,or 3 when the interrupt occurs, so I know what w_temp variable(0,1,2, or3) to save using the following assembly code?


MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into W

Thanks again

modifyit
- 19th September 2005, 02:45
For a 16F877A, and for many others, it's very simple.

Just change the $20 to $70.

Thanks Darrel, I will give that a shot. I am still interested how to make the wsave1,2,3 stuff work tho.

Darrel Taylor
- 19th September 2005, 03:09
Ok, easy to explain.

When a particular bank is selected with the RP0 and RP1 bits in the STATUS register, any opcode trying to access that bank is limited to 128 bytes. So, $20, $A0, $120 and $1A0 all point to a location that is 32 bytes into their respective BANK. &nbsp; The Variable declarations wsave1-3 are set that way to reserve the same locations in each bank.

That way you don't need to worry which bank you are in. The "MOVWF W_TEMP" always puts the byte in the correct location, no matter which bank is selected.

Then, notice that the STATUS register is restored prior to restoring the W register. That way you always have the same bank selected that was used to save the W reg. to begin with.

HTH,
&nbsp;&nbsp;&nbsp;Darrel

modifyit
- 19th September 2005, 03:14
So even tho I may be in bank 2 the "MOVWF W_TEMP" command will save to W_Temp2 in this case automatically?

Darrel Taylor
- 19th September 2005, 03:16
Correcto Mundo!

I have no idea what I just said, but it sounds right. :)