Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Hi i have free RAM in Bank0 but not in Bank1.
There is no any timer in Bank1.
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.
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
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.
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 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.
The alternative would be FSR if it's not being used. You could also use INTCON but the restoring would be a few instructions.
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