;---------------- Encabezado --------------------

       LIST    P=16F84
       #include       <P16F84.INC>

;------------ Registros de tiempo ---------------

reg1    EQU      0X0C
reg2    EQU      0X0D

;-------------- Vector de reset -----------------

        ORG      0X00
        GOTO     inicio

;-------- Rutina de interrupción (ISR) ----------

        ORG      0X04
        BTFSS    INTCON,1   ; salta si la interr. es por RB0
        GOTO     tmr        ; sino, es por TMR0 y ahí lo atiende
        BCF      INTCON,1   ; limpia bandera INTF
        RETFIE              ; retorno de interrupción
tmr     BCF      INTCON,2   ; Limpia bandera de T0IF
        RETFIE              ; retorno de interrupción

;---------- Configuración de puertos ------------

inicio  BSF      STATUS,RP0
        MOVLW    0XFF       ; carga w con 1111 1111
        MOVWF    TRISA      ; PORTA es entradas
        MOVLW    0X01       ; carga w con 0000 0001
        MOVWF    TRISB      ; RB0=entrada, el resto salida
        MOVLW    0X47       ; carga w con 0100 0111
        MOVWF    OPTION_REG ; RB0=flanco ascendente, prescaler=256
        BCF      STATUS,RP0

;------ Habilitación interrupción por RB0 ----------

        MOVLW    0x90       ; habilitamos interrupciones 1001 0000
        MOVWF    INTCON     ; GIE e INTE (para RB0)
        CLRF     PORTB      ; limpio el puerto B

;----------- ¿El portón está abierto? -----------

        BTFSC    PORTA,2    ; salta si Dcerrar=0 (portón abierto)
        GOTO     dormir     ; sino (portón cerrado) va a dormir

;-----  Si está abierto espera intrucción ----------

espera  BTFSC    PORTB,     ; salta si no se pulsa Abrir.
        GOTO     abrir      ; sino, fue pulsado y lo atiende en abrir
        BTFSC    PORTA,0    ; salta si no se pulsa cerrar
        GOTO     c_rrar     ; sino, fue pulsado y lo atiende en c_rrar
        GOTO     espera

;---- micro en estado de bajo consumo -----------

dormir  SLEEP               ; Espera interrupcion por RB

;------- Rutina para abrir el portón -------------

abrir   BCF     PORTB,4     ; prepara motor para subir
        CALL    retardo     ; hace un pequeño retardo
        BSF     PORTB,1     ; enciende motor (abre)
        BSF     PORTB,2     ; enciende semaforo

d_abrir BTFSS   PORTA,1     ; salta si pulsa Dabrir (sensor)
        GOTO    d_abrir     ; sino lo atienda d_abrir
        BCF     PORTB,1     ; Dabrir=1, entonces detiene motor
        BSF     PORTB,3     ; y enciende timbre

espero  BTFSC   PORTA,0     ; salta si no se pulsa cerrar (pulsador)
        GOTO    c_rrar      ; sino, fue activado y lo atiende en c_rrar
        GOTO    espero      ; espero que se pulse cerrar

;------- Rutina para cerrar portón ----------------

c_rrar  BCF     PORTB,3     ; apaga timbre
        BSF     PORTB,4     ; invierte motor para bajar
        CALL    retardo     ; hace un pequeño retardo
        BSF     PORTB,1     ;enciende motor

dcerrar BTFSS   PORTA,2     ; salta si activa Dcerrar (sensor)
        GOTO    dcerrar     ; sino, espero que se active
        BCF     PORTB,1     ; Dcerrar=1, entonces detiene motor
        BSF     PORTB,5     ; enciende luz de cochera
        BCF     PORTB,2     ; apaga semaforo

;------- Rutina de temporización 50 segundos --------

        MOVLW   00xA0       ; habilita T0IE interrupción por TMR0
        MOVWF   INTCON

        MOVLW   0x2D        ; cargo w co d'45'=0x2D
        MOVWF   reg1        ; lo pasa al rej1

tiempo1 MOVLW   0x64        ; cargo w con 100
        MOVWF   reg2        ; y lo paso a reg2

tiempo  MOVLW   0xD8        ; cargo w con 216
        MOVWF   TMR0        ; lo paso a TMR0

nada    BTFSC   TMR0,7      ; salta si el bit7 de TMR0 es 0
        GOTO    nada        ; sino, espera interrupción por TMR0

        DECFSZ  reg2,1      ; decremento reg2 y salta si reg2=0
        GOTO    tiempo      ; sino, vuelve a cargar TMR0
        DECFSZ  reg1,1      ; decremento reg1 y salta si reg1=0
        GOTO    tiempo1     ; sino, vuelve a cargar reg2

        BCF     PORTB,5     ; 50 sg. cumplidos apago luz de cochera
        CLRF    INTCON      ; desabilito interrupciones
        GOTO    inicio      ; vuelve a empezar para dormir al micro

;------ retardo de 189000 us. aprox.-------------------

retardo MOVLW   0xFA        ; aquí se cargan los registros
        MOVWF   reg1        ; carga reg1 con 250
dos     MOVWF   reg2        ; y reg2 con 250

uno     DECFSZ  reg2,1      ; decrementa y salta si reg2=0
        GOTO    uno
        DECFSZ  reg1,1      ; decrementa y salta si reg1=0
        GOTO    dos         ; irá a cargar reg2 nuevamente
        RETURN              ; regreso del retardo

;---------------------------

        END

;---------------------------
