JophMax
JophMax

Reputation: 11

Why My Assembler Subroutine doesn't get executed?

I'm currently creating code to begin a sequence lighting 10 leds whenever I push a button. However, when I apply my BTFSS and begin the simulation on Proteus, everything remains the same, even If I press the button.

Here's the code of the program:

include <p16f877a.inc>
list p=16f877a

A EQU 0x20
N EQU 0x21
M EQU 0x22

BSF STATUS,5
MOVLW B'11111111'
MOVWF TRISA
CLRF TRISB
CLRF TRISD
BCF STATUS,5
MOVLW D'7'
MOVWF CMCON
CLRF PORTA
CLRF PORTB
CLRF PORTD

INICIO
BTFSS PORTA,0
GOTO INICIO
CALL RUTINA_1
GOTO INICIO

RUTINA_1
CALL ANTI_REBOTE
;10
CLRF TRISB
MOVLW B'00000010'
MOVWF PORTD
MOVLW D'200'
MOVWF A
CALL RETARDO
;9
MOVLW B'00000001'
MOVWF PORTD
MOVLW D'200'
MOVWF A
CALL RETARDO
;8
CLRF PORTD
MOVLW B'10000000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;7
MOVLW B'01000000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;6
MOVLW B'00100000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;5
MOVLW B'00010000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;4
MOVLW B'00001000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;3
MOVLW B'00000100'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;2
MOVLW B'00000010'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;1
MOVLW B'00000001'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
GOTO RUTINA_1

ANTI_REBOTE
BTFSC PORTA,0
GOTO ANTI_REBOTE
RETURN

RETARDO
TRES
    MOVLW D'80'
    MOVWF M
DOS
    MOVLW D'25'
    MOVWF N
UNO
    NOP
    NOP
    DECFSZ N,1
    GOTO UNO
    DECFSZ M,1
    GOTO DOS
    DECFSZ A,1
    GOTO TRES
RETURN
END

I've used the animate option in MPLAB along with a stimulus where I set the RA0 port to high but still, nothing happened.

Upvotes: 1

Views: 67

Answers (1)

Kozmotronik
Kozmotronik

Reputation: 2520

The analog control register for the PIC16F877A is not the CMCON register but the ADCON1 register. According to the datasheet of the PIC16F877A, section 4.1:

On a Power-on Reset, these pins are configured as analog inputs and read as ‘0’.
The comparators are in the off (digital) state

So there is no need to configure the CMCON since it is configured to be off by default.

What you need to configure is the ADCON1 register since the PORTA has analog inputs (ANx pins). Those pins are configured as analog by default hence always read as 0. This is why nothing happens when you press the input button on RA0 pin.

This is because the ports are multiplexed with multiple kinds of internal hardware like ADC, comparators and digital buffers. You need to select the correct hardware to connect to the input pin, so it is the digital buffer what you want.

All that being said, the proper setup for you to use the RA0 pin as a digital input and all the analog pins as digital IO would be as following:

include <p16f877a.inc>
list p=16f877a

A EQU 0x20
N EQU 0x21
M EQU 0x22

    ORG 0 ; <-- Reset vector
; Setup code starts from the reset vector (program memory adress 0)
BCF     STATUS,RP0
BCF     STATUS,RP1  ; Bank0
CLRF    PORTA       ; Clear garbage on IO buffers
CLRF    PORTB       ; It is a good practice to reset all used output ports 
CLRF    PORTD       ; since their values on reset is unknown.
BSF     STATUS,RP0  ; Bank1
MOVLW   D'6'        ; Configure all ANx pins as digital IO
MOVWF   ADCON1
MOVLW   B'11111111' ; Set all pins of PORTA as input
MOVWF   TRISA
CLRF    TRISB       ; Set all PORTB pins as output
CLRF    TRISD       ; Set all PORTD pins as output

INICIO
BTFSS   PORTA,0
GOTO    INICIO
CALL    RUTINA_1    ; You better debounce the button press before proceeding
GOTO    INICIO

Upvotes: 1

Related Questions