__CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
CONTADOR
CONTADOR_1
PDel0
PDel1
PDel2
PDel3
PDel4
REG_1
FLAG
ENDC
#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1
ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES
ORG 0X05
INICIO
bsf STATUS,5 ; activa la página 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidas)
bcf STATUS,5 ; volvemos a la página 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados
clrf CONTADOR
clrf FLAG
ESPERA ; Leemos los pulsadores.
btfss PUL_I ; si está pulsado Izq. va a ANTIRREBOTES, si no
goto $+3 ; va tres posiciones para adelante
call ANTIRREBOTES ; al volver de Antirrebotes se va a MAIN
goto MAIN
btfss PUL_D ; si está pulsado va a ANTIRREBOTES, si no
goto ESPERA ; vuelve a leer los pulsadores.
call ANTIRREBOTES ; al volver de Antirrebotes se va a MAIN
goto MAIN
TABLA ;esta tabla nos dirá que hay que hacer
addwf PCL,1
goto ESPERA ; aquí nunca vendrá, pero por si acaso....
goto DERECHA
goto IZQUIERDA
goto LOS_DOS
MAIN
btfss PUL_D ; miramos si en PUL_D hay un 1 o un 0
bcf REG_1,0 ; y escribimos en un registro lo que haya
btfsc PUL_D ; en el bit 0
bsf REG_1,0
btfss PUL_I ; hacemos lo mismo con el otro pulsador
bcf REG_1,1 ; éste lo escribimos en el bit 1
btfsc PUL_I
bsf REG_1,1 ; aquí ya tenemos los dos pulsadores leidos y anotados en un registro
movf REG_1,0 ; lo movemos a W
call TABLA
goto ESPERA
IZQUIERDA
btfsc PUL_I ; Aquí espera hasta que se suelte pulsador
goto $-1 ; va una posición para atrás
clrf CONTADOR
btfss FLAG,0 ; miramos si hay un 1 en el Flag,0
goto ACTIVAR_I ; si no lo hay nos vamos a activar parpadeo Izq.
DESACTIVAR_I
bcf FLAG,0
bcf LED_I
clrf CONTADOR
btfsc PUL_I ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volvería a secuencia
return ; apaga flag e intermitente y vuelve a MAIN, FLAG estaba a 1
ACTIVAR_I
bsf FLAG,0 ; ponemos un 1 en el Flag,0
btfsc PUL_I ; salta si no está pulsado el Izq.
goto DESACTIVAR_I ; si mientras está ejecutando una secuencia
; se pulsa un botón empieza de nuevo
btfsc PUL_D ; salta si no está pulsado el Dcho.
goto DERECHA ; si lo estuviese nos vamos a encender Dcho.
ENCIENDE_I
bsf LED_I ; enciende intermitente Izq.
call DEMORA ; está un tiempo encendido
btfsc PUL_D ; salta si no está pulsado el Dcho.
goto DESACTIVAR_I ; si mientras esta ejecutando una secuencia
; se pulsa un botón empieza de nuevo
btfsc PUL_I ; salta si no está pulsado el Izq.
goto IZQUIERDA ; si lo estuviese nos vamos a encender Izq.
; incf CONTADOR_1,1
; movlw .5 ; número de veces que se repite el retardo de 50ms
; subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
; btfss STATUS,Z ; salta si el bit Z de Status es 1.
; goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador y nos vamos a apagar el led.
APAGA_I
bcf LED_I ; apaga el led Izq.
call DEMORA ; lo mantiene apagado 50ms.
btfsc PUL_D ; salta si no está pulsado el Dcho.
goto DESACTIVAR_I ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_I ; salta si no está pulsado el Izq.
goto IZQUIERDA ; si lo está nos vamos a
incf CONTADOR_1,1
movlw .40 ; número de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador
incf CONTADOR,1 ; para número de veces que encenderá
movlw .10 ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z ; van 10 veces?
goto ACTIVAR_I ; no, vuelve a repetir secuencia
clrf CONTADOR
goto DESACTIVAR_I
DERECHA
btfsc PUL_D ; Aquí espera hasta que se suelte pulsador
goto $-1 ; va una posición para atrás
clrf CONTADOR
btfss FLAG,1
goto ACTIVAR_D
DESACTIVAR_D
bcf FLAG,1 ; pone un 0 en el bit 1 de Flag.
bcf LED_D ; apaga led Dcho.
clrf CONTADOR ; pone a 0 el Contador.
btfsc PUL_D ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volvería a secuencia
return ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
ACTIVAR_D
bsf FLAG,1
btfsc PUL_D ; salta si no está pulsado el Dcho.
goto DESACTIVAR_D ; si mientras esta ejecutando una secuencia
; se pulsa un botón empieza de nuevo
btfsc PUL_I ; salta si no está pulsado el Izq.
goto IZQUIERDA
ENCIENDE_D
bsf LED_D ; enciende intermitente Dcho.
call DEMORA ; está un tiempo encendido
btfsc PUL_D
goto DESACTIVAR_D ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_I
goto IZQUIERDA
; incf CONTADOR_1,1
; movlw .50 ; número de veces que se repite el retardo de 50ms
; subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
; btfss STATUS,Z
; goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador
APAGA_D
bcf LED_D ; apaga
call DEMORA
btfsc PUL_D
goto DESACTIVAR_D ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .40 ; número de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador
incf CONTADOR,1 ; para número de veces que encenderá
movlw .10 ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z ; van 10 veces?
goto ACTIVAR_D ; no, vuelve a repetir secuencia
clrf CONTADOR
goto DESACTIVAR_D
LOS_DOS
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si están sin pulsar ambos botones
goto $-3
btfss FLAG,2 ; flag para saber si apagamos o encendemos
goto ACTIVAR_LOSDOS
DESACTIVAR_LOSDOS
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si están sin pulsar ambos botones
goto $-3
bcf FLAG,2 ;apagamos intermitentes y borramos flag, ya que estaba a 1
clrf PORTB ; apagamos intermitentes
return
ACTIVAR_LOSDOS
bsf FLAG,2 ; el flag estaba a 0 lo activamos
btfsc PUL_I
goto DESACTIVAR_LOSDOS ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_D
goto DESACTIVAR_LOSDOS
movlw 0x18
movwf PORTB ; ponemos a 1 bits 3 y 4 del puerto B
ENCIENDE_LOSDOS
call DEMORA ; tiempo encendidos
btfsc PUL_I
goto DESACTIVAR_LOSDOS ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_D
goto DESACTIVAR_LOSDOS
; incf CONTADOR_1,1
; movlw .50 ; número de veces que se repite el retardo de 50ms
; subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
; btfss STATUS,Z
; goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
APAGA_LOSDOS
clrf PORTB ; lo hago así porque supongo que no tienes mas cosas coectadas en PORTB
call DEMORA
btfsc PUL_I
goto DESACTIVAR_LOSDOS ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
btfsc PUL_D
goto DESACTIVAR_LOSDOS
incf CONTADOR_1,1
movlw .40 ; número de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este número se aumentará o reducirá en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto ACTIVAR_LOSDOS
ANTIRREBOTES
; 300ms, aparte de servir de antirrebotes, también compensará ; si no se pulsan exactamente al mismo tiempo los dos botones
movlw .117 ; 1 set número de repetición (B)
movwf PDel2 ; 1 |
PLoop3 movlw .213 ; 1 set número de repetición (A)
movwf PDel3 ; 1 |
PLoop4
; clrwdt ; 1 clear watchdog
PDelL8 goto PDelL9 ; 2 ciclos delay
PDelL9 goto PDelL10 ; 2 ciclos delay
PDelL10
decfsz PDel3,1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop4 ; 2 no, loop
decfsz PDel2,1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop3 ; 2 no, loop
PDelL11 goto PDelL12 ; 2 ciclos delay
PDelL12
; clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-----------------------------------------------
DEMORA ; retardo de 50ms que se repetirá las veces que sea necesario
; para completar el tiempo adecuado para las intermitencias
movlw .55 ; 1 set número de repetición (B)
movwf PDel0 ; 1 |
PLoop1 movlw .181 ; 1 set número de repetición (A)
movwf PDel1 ; 1 |
PLoop2
; clrwdt ; 1 clear watchdog
; clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
return ; 2+2 Fin.
END