George Loman
George Loman

Reputation: 43

PIC Assembly - Checking Status of Push Button

My code is seen as below, I am trying to use a push button to turn an LED on and off. So pressing it once will turn it on, and it will stay on, until the button is pressed again.

However, I get one error during compilation - "address label duplicated or different in second pass" The error points to the second occurence of the line starting with "check BTFSS".

What am I doing wrong here?

Thanks in advance. :)

;Program name: T code

;CPU Configuration
processor 16F84A
include <p16f84a.inc>

__config _XT_OSC & _WDT_OFF & _PWRTE_ON

;Register Label Equates
PORTA   equ 05
PORTB   equ 06
Count   equ 0C

;Register Bit Label Equates
Input   equ 4   ;PUSH BUTTON INPUT RA4
LED1    equ 0   ;LED OUTPUT RB0

;*****Program Start*****

org 0

;Initialize  (Default = Input)
movlw   B'00000000'     ;Define Port B output
tris    PORTB       ; and set bit direction
goto    check

;Main Loop
check   BTFSS   PORTA,Input     ;If button is OFF, goto check, and keep waiting for button       HIGH condition.
    goto    check       ;
bsf PORTB,LED1        ;Turn the LED ON

check   BTFSS   PORTA,Input     ;Assuming the LED is currently ON, keep checking for a button press...
    goto    check
bcf PORTB,LED1        ;Turn the LED OFF
goto    check       ;repeat always

END

Upvotes: 0

Views: 10328

Answers (2)

DrRobotNinja
DrRobotNinja

Reputation: 1421

There a few errors in this program:

You have the check tag in there twice, you need to rename it.

The two blocks of code are essentially identical, so each of the BTFSS directive will pause execution until you press the button, then the code rapid executes. I'm assuming your LED will be either on or off when you release the button (random as to which) and then it goes halfway bright while you hold the button.

You'll need something along the lines of:

check_a    BTFSS PORTA,Input ; Wait for button push
           GOTO check_a 

           ; You need a delay here to debounce the switch
           MOVLW D'1000' ; You need to tune this value, I'm just guessing
           MOVWF Delay
delay_a    DECFSZ Delay, 1
           GOTO delay_a

check_b    BTFSC PORTA,Input ; Wait for button release
           GOTO check_b     

           ; You need a delay here to debounce the switch
           MOVLW D'1000' ; You need to tune this value, I'm just guessing
           MOVWF Delay
delay_b    DECFSZ Delay, 1
           GOTO delay_b

           BTG PORTB,LED1    ; Toggle LED on or off
           GOTO check_a

Debouncing is critical because mechanical pushbuttons have small metal leaves that made and break contact faster than humans can tell but much slower than microcontroller can tell, so a single button push shows up as multiple rapid pushes to the microcontroller. I usually use a delay of 20 milliseconds or so.

At the moment, I don't have a development board to try this on, so there's a chance it will require some debugging.

Upvotes: 1

us2012
us2012

Reputation: 16253

You have two different labels called check, so the assembler can't decide where to jump to. Rename one of those labels.

Upvotes: 2

Related Questions