PIC16f18875 assembly: subroutine does not work as expected after a BTFSC

Thread Starter

smarino

Joined Jan 11, 2017
2
Hi, sorry, my English is not good, I'm using the Google translator. I have a problem in the flow of the program in assembly about PIC16F18875, when BTFSC gets 1 then it calls the instruction, CALL subroutine. In the subroutine the bank "banksel porta" is selected and then channel 5 PORTA, 5 is written. But it seems that he does not execute "BANKSEL PORTA" and therefore he does not write ON on PORTA, 5. But if I call BANKSEL before executing CALL subroutine it works fine.



The code, ISR, calls a counter CALL TIMER0_COUNTER. This counter writes data in memory: TIMER01 After, BTFSC TIMER01,4 And if it's 1, CALL SUBRUTINE BLINK_PORTA5 BANKSEL PORTA BSF PORTA, 5 RETURN But BANKSEL PORTA seems not to be executed


ISR CODE 0x0004
;Drive interrupt Timer0
BANKSEL PIR0
BTFSC PIR0,TMR0IF
CALL TIMER0_COUNTER
BTFSC TIMER01,4
CALL BLINK_PORTA5
BANKSEL PIR0
BCF PIR0,TMR0IF
RETFIE


;;;;;SUBRUTINE BLINK PORTA5
BLINK_PORTA5
BANKSEL PORTA *********************** IT IS NOT EXECUTED
BSF PORTA,5
RETURN



TIMER0_COUNTER
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,, BANKSEL PORTA ;;;;;;;;;;;;;;;;;;;;;;; HERE IT WORKS!!! WHY!?!?!?!
MOVLW 0x01
ADDWF TIMER00,1
BTFSS STATUS,C
RETURN

MOVLW TIMER00_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0x01
ADDWF TIMER01,1
BTFSS STATUS,C
RETURN
MOVLW TIMER01_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER02,1
BTFSS STATUS,C
RETURN
MOVLW TIMER02_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER03,1
BTFSS STATUS,C
RETURN
MOVLW TIMER03_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER04,1
BTFSS STATUS,C
RETURN
MOVLW TIMER04_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER05,1
BTFSS STATUS,C
RETURN
MOVLW TIMER05_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER06,1
BTFSS STATUS,C
RETURN
MOVLW TIMER06_OVERFLOW
MOVWF TIMER_OVERFLOW

MOVLW 0X01
ADDWF TIMER07,1
BTFSS STATUS,C
RETURN
MOVLW TIMER07_OVERFLOW
MOVWF TIMER_OVERFLOW

RETURN
 

jpanhalt

Joined Jan 18, 2008
11,087
I have not used that chip, but it appears that PORTA and LATA are in the same bank.

Have you tried instead of:
Code:
BSF PORTA,5
RETURN
Use:
Code:
BSF LATA,5
RETURN
Why do you think BANKSEL PORTA is not being executed?

PS: I did not go through the entire code.
 

Thread Starter

smarino

Joined Jan 11, 2017
2
ANSELA ( digital all 8 ports)
TRISA (output all 8 ports)



1 CALL SOME_ADDER_ROUTINE
2 BTFSC SOME_REG,BIT
3 CALL ROUTINE_BLINK_LED_PORTA5


ROUTINE_BLINK_LED_PORTA5
BANKSEL PORTA
BSF PORTA,5

ok?? well... BANKSEL PORTA seems an NOP :(

but if I call banksel PORTA from SOME_ADDER_ROUTINE (before BTFSC) work fine!

I do not understand
 
Last edited:

jpanhalt

Joined Jan 18, 2008
11,087
You still have not said why you think BANKSEL is being ignored and then say it acts as a NOP. I presume you are using a simulator and seeing each step. A NOP is a step. It is not ignored. If the simulator steps through your BANKSEL it will not be ignored.

It seems more likely that a true "skip" is because a preceding branch (e.g., BTFSC) is skipping it. Now, if the skip you perceive is based on an expected blink of the LED on PORTA,5, it is possible that the step is being executed but the next steps,
Code:
BANKSEL PIR0
BCF PIR0,TMR0IF
RETFIE
are being executed so quickly that you do no see the blink. For example, if the LED's state is turned off in the main code after return from the ISR, the blink may be only a few Tcy.

I have not traced carefully your TIMER0_COUNTER routine, but this instruction stuck out:
Code:
MOVLW TIMER00_OVERFLOW
That moves the register location, not its contents, to W. It is the same as moving a constant to W. There are times when you need to know the register location, e.g., when using indirect accessing or when doing multi-byte manipulations that are similar to indirect addressing, but on the surface that does not appear to be what you intended to do. If you want to move the contents, then use: MOVF TIMER0_COUNTER,W MOVF TIMER00_OVERFLOW, W.

Finally, there are a couple of details it would be nice to know. First, you have not said whether all of your named registers are in General Purpose RAM or Common RAM. If General Purpose RAM, then you will need to be sure you are in the correct bank when addressing them. Second, I am assuming you are compiling as Absolute code,not Relocatable code. Please correct, if wrong.
 
Last edited:
Top