Baseline PIC12F509 BTFSS Instruction Issue

microcontroller

****Update Scroll Down For More Info****

I've been experimenting with a PIC12F509 and have been writing some simple code in assembly I'm using the internal 4 MHz RC oscillator.

I have set GP3 as an input (MCLR is off) with a 10k pull up resistor connected between GP3 and VDD. A push button switch then pulls GP3 to ground to turn on an LED connected to GP1 which is set as an output the LED is anode switched.

The following code doesn't work as expected for some reason. I would expect the program to loop with the LED off until the push button is pressed and GP3 goes low at which point the LED will turn on but not turn off. Instead it turns on as soon as the PIC is powered.

The btfss instruction should skip the bsf instruction to set GP1 high as long as GP3 is high.

;***** MAIN PROGRAM *****************************************************

;***** Initialisation
start           
    movlw   b'111101'       ; configure GP1 (only) as an output
    tris    GPIO            ; (GP3 is an input)

;***** Main loop
main_loop
    btfss   GPIO,3
    bsf     GPIO,1
    goto    main_loop
    END

I thought it was because GPIO was initially undefined but adding clrf GPIO after the tris instruction didn't solve the issue.

Is it because as the PIC is powering up (this small circuit is being powered by the PICkit3 programmer) GP3 is initially below the logic high threshold for a split second which causes the bsf instruction to be executed?

Of course by adding two more lines like this:

main_loop
    btfss   GPIO,3
    bsf     GPIO,1
    btfsc   GPIO,3
    bcf     GPIO,1
    goto    main_loop

The LED will turn on and off with the switch.

While the previous code isn't very useful I'm curious as to why the LED is turning on.

Thanks In Advance.

**** Update ****

I tried some new code that toggles the LED on and off with a 20 ms debounce subroutine as shown. I removed the 10k pull up resistor and enabled the internal weak pullups as seen in the code.

start   
movlw   b'111101'
tris    GPIO
movlw   b'10111111'
option

main_loop
waitdn  btfsc   GPIO,3
goto    waitdn

movf    sGPIO,w
xorlw   b'000010'
movwf   sGPIO
movwf   GPIO

movlw   .2
pagesel delay10r
call    delay10r
pagesel $

waitup  btfss   GPIO,3
goto    waitup

movlw   .2
pagesel delay10r
call    delay10r
pagesel $

goto    main_loop

END                       ; directive 'end of program'

This code also behaves in the same peculiar way the LED starts in the on state when the PIC is initially powered on. It can then be toggled on or off with a single press and release of the switch.

Best Answer

Well I figured it out and the answer was pretty silly.

As stated before I was powering this tiny circuit from the PICKit3 and my switch was on the disabled MCLR pin which when disabled becomes an input.

The answer is GP3 WAS being pulled low but not by me by the PICKit3. After programming the PICKIT momentarily pulls the MCLR line low to reset the microcontroller (the same line I was using for my input) for a split second. That logic low was enough to turn the LED on in my first bit of code and also toggled the LED on in my second bit of code.

The solution was to disconnect the PICKIT after programming and power the PIC from an external power supply. When powered externally the PIC code works as expected with the LED initially off. That'll teach me to treat the MCLR pin like any other input.