Programa en ensamblador con PIC18F4520 que controle dos arrays de 8 leds

Buenas yo tengo otro problema con un ejercicio en ensamblador , es muy sencillo pero no se estabilizar la señal de los pulsadores, ya que estos no son ideales y por eso creo una función que se llama esperar200ms para estabilizarla pero estoy indecisa. Ayuda, el ejercicio esta incompleto.

;Ejercicio de ensamblador (60 puntos)
;Desarrolla un programa en ensamblador del PIC18F4520 que controle dos arrays de 8 leds conectados a los puertos C y D siguiendo las siguientes directrices.
;• Al iniciar el sistema todos los leds de los puertos C y D permanecerán apagados.
;• Cada vez que se pulse el pulsador conectado a la línea RB1, se encenderá el led apagado del puerto C conectado a la línea de menos peso. Es decir, cada pulsación en RB1 provocará el encendido del siguiente led del puerto C de derecha a izquierda.
;• Cada vez que se pulse el pulsador conectado a la línea RB2 se encenderá el led apagado del puerto D conectado a la línea de menos peso.
;• Si se pulsan RB1 o RB2, estando todos los leds del puerto C o D encendidos, dicha pulsación quedará sin efecto.
;• Si se pulsa el pulsador conectado a RB0 se apagarán todos los leds de los puertos C y D.

;Por otro lado en el puerto E se han conectado otros tres diodos led en sus líneas de menos peso: RE0, RE1 y RE2.
;• RE0 se activará cuando el número de leds encendidos del puerto C sea inferior al número de leds encendidos del puerto D.
;• RE1 cuando ambos número sean idénticos.
;• Y RE2 cuando el puerto D cuente con más leds encendidos que el puerto C.

Código:
;********CONFIGURACION Y ETIQUETAS***********
include"p18f4520.inc"

CONFIG OSC=EC, WDT=OFF,PBADEN=OFF


clrf TRISC    ;salidas puerto c , d y e
clrf TRISD
clrf TRISE
clrf LATC
clrf LATD     ; borrar latches
clrf LATE
setf PORTB   ; entrada puerto B

;********INTERRUPCIONES Y EL TIMER 0***********
org 0x0  ; vector de reset
        goto inicio ; saltar a configuracion
org 0x08  ; vector de interrupciones (prioridad)
_
_
_
_
_



;************************INICIO DEL PROGRAMA**************************

Inicio

        call pulsador1
        call pulsador2
        call pulsador3
        return 
;****PULSADORES*****
pulsador1

            btfss PORTB, RB1  ; si RB1=1 vete a luces
            return              ; NO vuelve
            goto luces1          ; Si, vete a luces1


pulsador2  

            btfss PORTB, RB2 ; si RB2=1 vete a luces2
            return           ; No!
            goto luces2      ; Si, vete a luces2


pulsador3  ;reseteo de luces

            btfss PORTB,RBO  ; si Rb0=1 resetea los puertos
            return             ;No, vuelve a mirar
            clrf PORTC       ; Si, borra el puerto C
            clrf PORTD       ;Si,  borra el puerto D
            goto inicio

;********LUCES*******

luces1

            bsf STATUS,C   ; pone a 1 el bit C del status
            rlcf LATC, F   ; Rota sin carry los leds del puerto C
            goto comparabarras  ; Ahora comparamos las luces 
            goto inicio
luces2

            bsf STATUS,C              ; pone a 1 el bit C del status
            rlcf LATD, F           ; Rota sin carry los leds del puerto D
            goto comparabarras   ; Ahora comparamos las luces 
            goto inicio

;***************************COMPARA BARRAS*******************************

comparabarras
            movff  PORTD,W
            movff  PORTC,F
            cpfsgt F,W   ; compara f con w salta si PUERTOC>PUERTOD = RE0 encendido
            goto menor   ; No! pueden ser iguales las luces o menores 
            bsf PORTE,0  ; Si, entonces enciende RE0 =1

        menor
                    cpfslt F,W   ; compara f con W y salta si es menor 
                    bsf PORTE,1  ; No, entocnes los leds son iguales RE1=1
                    bsf PORTE,2  ; Si, entonces es menor RE2=1


;*********TIEMPO DE REBOTE********************
; los pulsadores no son ideales por lo tanto necesitamos un tiempo de estabilizacion de la señal

espera200ms

        movlw d'200'
        movwf cont2   ;cont2=200
        rcall espera1ms
        decfsz cont2  ; decrementa hasta llegar a 0
        bra $-4
        return
    espera1ms
        clrf cont1   ; cont1=0
        nop
        incfsz cont1
        bra $-4
        return 

END
 
Última edición por un moderador:
Kaixo, paisana!

Dos cosas:

1- Es correcto realizar una pausa para eliminar los rebotes del pulsador. Creo que 200ms es demasiado; yo probaría con 20ms, pero bueno, si no te pones muy nerviosa con los teclados torpes, puedes dejarlo en 200.

2- Detecto un fallo importante en tu programa, que va a hacer que no funcione: En "Inicio" llamas a tres subrutinas de comprobación de pulsadores. En todas tienes el mismo problema. Mira, vamos a analizar la primera:

Inicio: (...)
call pulsador1

(...)

pulsador1:
btfss PORTB, RB1 ; si RB1=1 vete a luces
return ; NO vuelve
goto luces1 ; Si, vete a luces1
(...)

luces1

bsf STATUS,C ; pone a 1 el bit C del status
rlcf LATC, F ; Rota sin carry los leds del puerto C
goto comparabarras ; Ahora comparamos las luces
goto inicio ; ¡¡¡¡¡¡¡¡¡ CUIDADO !!!!!!!!!


¿Lo has visto? Llamas con CALL y retornas con GOTO. Fallo. Se te va a colgar el micro.

El retorno de una subrutina llamada con CALL ha de hacerse siempre con RETURN. De lo contrario, en cuanto pulses el pulsador se te llenará la pila (stack).

Míralo bien, porque te ocurre en los tres casos (en los tres pulsadores).

Gero arte!
 
Atrás
Arriba