Save W

Status
Not open for further replies.
hi

movwf w_temp ; save off current W register contents
Use a higher Bank.?

EDIT:
Hi Suraj,
Sorry I clipped the 16F876 register image by mistake.!!

Have you used ALL the free registers in Banks 0 and 1 .??
 

Attachments

  • AAesp05.gif
    57.9 KB · Views: 165
Last edited:
Because if i save W in Bank0

What will happen if an interrupt happens while you were in Bank1 in the main routine?

It will overite the same offset in Bank1, so it will corrupt data.
 
Because if i save W in Bank0

What will happen if an interrupt happens while you were in Bank1 in the main routine?

It will overite the same offset in Bank1, so it will corrupt data.

I assume when you service an ISR call you are saving the Wreg and STATUS reg at the start of the ISR and restoring at the end of the ISR...????

Also recall that GPR's 70h thru 7Fh are shared by all the Banks

Code:
    ORG     0x004             ; interrupt vector location

    movwf   w_temp            ; save off current W register contents
    movf    STATUS,w          ; move status register into W register
    movwf    status_temp       ; save off contents of STATUS register
    movf    PCLATH,w      ; move pclath register into w register
    movwf    pclath_temp      ; save off contents of PCLATH register

; isr code can go here or be located as a call subroutine elsewhere

    movf    pclath_temp,w      ; retrieve copy of PCLATH register
    movwf    PCLATH          ; restore pre-isr PCLATH register contents
    movf    status_temp,w     ; retrieve copy of STATUS register
    movwf    STATUS            ; restore pre-isr STATUS register contents
    swapf   w_temp,f
    swapf   w_temp,w          ; restore pre-isr W register contents
    retfie                    ; return from interrupt
 
Last edited:
Hello PIC16F873A is not like other PICs.

There is no common bank area between Bank0 & Bank1.So the above code will not work.

That's why I'm still struggling how to save W register.
 
Hello PIC16F873A is not like other PICs.

There is no common bank area between Bank0 & Bank1.So the above code will not work.

That's why I'm still struggling how to save W register.

The last 16 bytes of all 4 banks access the same (common) area. See page 17 of the data sheet.

Mike.
 
Mike its in Page 18.Not in Page 17.

Bank0 & Bank1 is not shared in PIC16F873A.

@Suraj
Mosiac gave the correct idea by saving W in a SFR which is not used.Other wise you have to switch to another PIC like PIC16F886 which has the same pin count.
 
Last edited:
I never realised that the 873 didn't have any common area and presumed the family all had the same common area. However, the problem is easily solved, define W_TEMP at the same offset in both banks (call it W_TEMP1 in bank 1). For example at 0x20 and 0xA0. Then use the context save from the data sheet.

Code:
	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

The alternative would be FSR if it's not being used. You could also use INTCON but the restoring would be a few instructions.

Mike.
 
Last edited:

The above method works if 0xA0 location is free in Bank1.But OP has stated he used all Bank1 registers with some data.So he will loose original 0xA0 location data when it goes to ISR while he is accessing Bank1 registers in the main routine.

The alternative would be FSR if it's not being used. You could also use INTCON but the restoring would be a few instructions.

This will work.
 
hi Suraj,
I would advise you upgrade from a 16F873 to a pin compatible 16F876, this would solve your GPR problems.
 

Attachments

  • AAesp01.gif
    31.4 KB · Views: 195
Last edited:
Ok guys I planned to shift to another PIC that's the only solution because registers like FSR & INTCON I use both in main & in the ISR.So I cannot use a SFR in this design.
 
If you are going to a better chip then may I suggest the newer 16F886 as that has an internal clock.

However, you can still use INTCON. You just need to set it's value at the end of the ISR,
Code:
	movwf	[COLOR="red"]INTCON[/COLOR]		;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	[COLOR="red"]INTCON[/COLOR],F	;Swap W_TEMP
	swapf	[COLOR="red"]INTCON[/COLOR],W	;Swap W_TEMP into W
	[COLOR="red"]clrf	INTCON
	bsf	INTCON,TMR0IE	;restore to required value
	bsf	INTCON,other bits[/COLOR].
	retfie			;will set INTCON,GIE

Note, you should not set bit 7 of intcon (GIE) in the ISR as the retfie will set that for you and setting it in the interrupt could cause a nested interrupt which is very nasty.

Edit, also, you cannot use this if more than one interrupt is enabled.

Mike.
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…