;---------------- Encabezado --------------------

	 LIST      P=16F84A
                include "P16F84A.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 interrup. 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 instrucción ------

espera	BTFSC	PORTB,0		; 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 interrupción por RB0

;--------- 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 semáforo

d_abrir	BTFSS	PORTA,1		; salta si se pulsa Dabrir (sensor)
	GOTO	d_abrir		; sino lo atiende en 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 el 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 se 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 semáforo

;------- Rutina de temporización 50 segundos -------

	MOVLW	0xA0		; habilita T0IE interrupción por TMR0
	MOVWF	INTCON
	
	MOVLW	0x2D		; cargo w con d'45'=0x2D 
	MOVWF	reg1		; lo pasa a reg1

tiempo1	MOVLW	0x64		; cargo w con 100
	MOVWF	reg2		; y lo pasa a reg2

tiempo	MOVLW	0xD8		; cargo w con 216
	MOVWF	TMR0		; lo pasa a TMR0

nada	BTFSC	TMR0,7		; Salta si Bit7 de TMR0 es cero
	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		; decrementa reg1 y salta si reg1=0
	GOTO	tiempo1		; sino vuelve a cargar reg2

	BCF	PORTB,5		; 50 seg. cumplidos apago luz de cochera
	CLRF	INTCON		; deshabilito interrupciones
	GOTO	inicio		; vuelve a empezar para dormir al micro

; ------ retardo de 189000 us. aproximadamente --------

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
;------------------------------------------