'Manejo de RElE
'En este proyecto usaremos:
'TECLADO 3x4 Tipo Telefonico
'LCD 16x2 Hitachi
'RELE 5V
'PIC16F873

'*********************************************************
'*********************************************************
'******* Definimos Nuestras Constantes y Variables********
'*********************************************************
'*********************************************************

'Comenzamos
'Definimos el Oscilador
DEFINE OSC 4

'Para el Manejo de LCD
DEFINE LCD_DREG PORTB	'Puerto B sera Datos
DEFINE LCD_DBIT 4	'Comienza por el 4to Bit
DEFINE LCD_RSREG PORTA	'Pin RS Porta.0
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTA	'Pin EN Porta.1
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4	'Definimos que son 4 Bits
DEFINE LCD_LINES 2	'LCD de 2 Lineas
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

'Manejo Teclado
L1 CON %01110000
L2 CON %10110000
L3 CON %11010000
L4 CON %11100000

TECLA var byte
FLAG VAR BYTE
CONTRA VAR BYTE

'Manejo de Contraseña y Eeprom
PASS1 vAR BYTE[4]
PASS2 VAR BYTE[4]
COUNT1 VAR BYTE
I VAR BYTE

'Definimos puerto que servira para activar el Relé
RELE VAR PORTA.2

'*********************************************************
'*********************************************************
'************ Aqui comenzamos a programar  ***************
'*********************************************************
'*********************************************************
'Inicializamos la Eeprom
DATA @0,"1234"	'Pass Por Defecto

'Inicializamos a valores Digitales
ADCON1 = 7
OPTION_REG=0 'Activamos Pull-up
TRISB = %00001111
TRISA = 0

INICIO:
'Mensaje Inicial
LCDOUT $FE,1,"  ACTIVA  RELE  "
LCDOUT $FE,$C0,"   [9]=ON/OFF"

'Revisamos tecla, si se pulsa 9
'Cambiamos de Estado a Rele
REVISA_TEC:
GOSUB TECLADO	'Rutina revisa Teclado
IF FLAG=0 THEN REVISA_TEC	'Si se presiono una Tecla FLAG=1
IF TECLA="9" THEN ACT_RELE      'Si tecla no es 9 
GOTO REVISA_TEC			'Sigue revisando teclado
ACT_RELE:	
PAUSE 100	'Espero un Tiempo debido a los rebotes

'Pido Ingreso de Contraseña
LCDOUT $FE,1,"  INGRESE PASS  "
PAUSE 500

'Rutina que pide Contraseña
GOSUB VER_PASS		 'Devuelve contra = 1 o 0
'1 si se ingreso contraseña (4 Digitos y #)
'0 si se cancelo, se pulso *

IF contra = 0 THEN INICIO
GOSUB LEE_EPROM		 'Lee Contraseña y lo guarda en pass2
GOSUB COMPRUEBA		 'Devuelve contra 0 si contraseña es correcta
IF contra = 1 THEN INICIO
	TOGGLE RELE	 'Cambia Estado de Rele
GOTO INICIO

'******************************
TECLADO:
FLAG=0
TECLA=$FF
PORTB = L1
SELECT CASE PORTB & $0F
CASE %1110
	TECLA="*"
	FLAG = 1
CASE %1101
	TECLA="0"
	FLAG = 1
CASE %1011
	TECLA="#"
	FLAG = 1 
END SELECT

PORTB = L2	'Lin 120
SELECT CASE PORTB & $0F
CASE %1110
	TECLA="1"
	FLAG = 1
CASE %1101
	TECLA="2"
	FLAG = 1 
CASE %1011
	TECLA="3" 
	FLAG = 1 
END SELECT 

PORTB = L3
SELECT CASE PORTB & $0F
CASE %1110
	TECLA="4"
	FLAG = 1 
CASE %1101
	TECLA="5" 
	FLAG = 1 
CASE %1011
	TECLA="6"
	FLAG = 1 
END SELECT 

PORTB = L4
SELECT CASE PORTB & $0F
CASE %1110
	TECLA="7"
	FLAG = 1 
CASE %1101
	TECLA="8"
	FLAG = 1 
CASE %1011
	TECLA="9"
	FLAG = 1 
END SELECT 
PAUSE 50
RETURN


'*******************
'*******************
VER_PASS:
'Limpia el LCD
LCDOUT $FE, 1
COUNT1 = 1
REPITE:
FLAG=0
GOSUB TECLADO 'Ingresa Tecla
PAUSE 10
IF FLAG=0 THEN REPITE
PAUSE 100
SELECT CASE TECLA
CASE "*"	'Indica cancelacion de Ingreso
	contra = 0
	RETURN
CASE "#"	'Indica fin de contraseña
	IF COUNT1 < 5 THEN
	GOTO REPITE
	ELSE
	contra = 1
	RETURN
	ENDIF
END SELECT

IF COUNT1 < 5 THEN
pass1[COUNT1-1]=TECLA	'Guardamos tecla presionada
COUNT1 = COUNT1 +1
ENDIF

ASTERISCOS:
LCDOUT $FE,1
IF COUNT1>1 then
For i=2 to COUNT1
LCDOUT "*"
Next i
ENDIF

IF COUNT1 =5 THEN	'Si va en la 5ta cuenta se presiona #
LCDOUT $FE,$C0,"       [#]"
ENDIF
GOTO REPITE


'Lee contraseña de la eprom en pass2
LEE_EPROM:
For i=0 To 3
DISABLE 'Detengo posibles interrupciones
READ i,pass2[i]
PAUSE 10
Next i
RETURN

'Rutina que compara contraseña ingresada en pass1 con pass2
'retorna contra = 0 si son iguales
COMPRUEBA:
'Leo Contraseña Actual
For i=0 To 3
pass1[i]=pass1[i]-$30
pass2[i]=pass2[i]-$30
Next i
contra = (pass1[0]*1000+pass1[1]*100+pass1[2]*10+pass1[3]) - (pass2[0]*1000+pass2[1]*100+pass2[2]*10+pass2[3])
RETURN

END
