__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
ENDC
; La clave puede tener cualquier tamaño y su longitud se calcula:
#DEFINE LongitudClave (FinClaveSecreta-ClaveSecreta)
#DEFINE CerraduraSalida PORTA,3
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG 4
goto ServicioInterrupcion
Mensajes
addwf PCL,F
MensajeTeclee
DT "Teclee CLAVE:", 0x00
MensajeClaveCorrecta
DT "Clave CORRECTA", 0x00
MensajeAbraPuerta
DT "Abra la puerta", 0x00
MensajeClaveIncorrecta
DT "Clave INCORRECTA", 0x00
;
LeeClaveSecreta
addwf PCL,F
ClaveSecreta
DT 4h,5h,6h,0Eh ; Ejemplo de clave secreta.
DT 7h,8h
FinClaveSecreta
Inicio call LCD_Inicializa
bsf STATUS,RP0
bcf CerraduraSalida ; Define como salida.
bcf STATUS,RP0
call Teclado_Inicializa ; Configura las líneas del teclado.
call InicializaTodo ; Inicializa el resto de los registros.
movlw b'10001000' ; Habilita la interrupción RBI y la general.
movwf INTCON
Principal
sleep ; Espera en modo bajo consumo que pulse alguna tecla.
goto Principal
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
CBLOCK
ContadorCaracteres
GuardaClaveTecleada
ENDC
ServicioInterrupcion
call Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.
;
; Según va introduciendo los dígitos de la clave, estos van siendo almacenados a partir de
; las posiciones RAM "ClaveTecleada" mediante direccionamiento indirecto y utilizando el
; FSR como apuntador. Por cada dígito leído en pantalla se visualiza un asterisco.
;
movwf INDF ; Almacena ese dígito en memoria RAM con
; con direccionamiento indirecto apuntado por FSR.
movlw '*' ; Visualiza asterisco.
call LCD_Caracter
incf FSR,F ; Apunta a la próxima posición de RAM.
incf ContadorCaracteres,F ; Cuenta el número de teclas pulsadas.
movlw LongitudClave ; Comprueba si ha introducido tantos caracteres
subwf ContadorCaracteres,W ; como longitud tiene la clave secreta.
btfss STATUS,C ; ¿Ha terminado de introducir caracteres?
goto FinInterrupcion ; No, pues lee el siguiente carácter tecleado.
;
; Si ha llegado aquí es porque ha terminado de introducir el máximo de dígitos. Ahora
; procede a comprobar si la clave es correcta. Para ello va comparando cada uno de los
; dígitos almacenados en las posiciones RAM a partir de "ClaveTecleada" con el valor
; correcto de la clave almacenado en la posición ROM "ClaveSecreta".
;
; Para acceder a las posiciones de memoria RAM a partir de "ClaveTecleada" utiliza
; direccionamiento indirecto siendo FSR el apuntador.
;
; Para acceder a memoria ROM "ClaveSecreta" se utiliza direccionamiento indexado con el
; el registro ContadorCaracteres como apuntador.
;
call LCD_Borra ; Borra la pantalla.
clrf ContadorCaracteres ; Va a leer el primer carácter almacenado en ROM.
movlw ClaveTecleada ; Apunta a la primera posición de RAM donde se ha
movwf FSR ; guardado la clave tecleada.
ComparaClaves
movf INDF,W ; Lee la clave tecleada y guardada en RAM.
movwf GuardaClaveTecleada ; La guarda para compararla después.
movf ContadorCaracteres,W ; Apunta al carácter de ROM a leer.
call LeeClaveSecreta ; En (W) el carácter de la clave secreta.
subwf GuardaClaveTecleada,W ; Se comparan.
btfss STATUS,Z ; ¿Son iguales?, ¿Z=1?
goto ClaveIncorrecta ; No, pues la clave tecleada es incorrecta.
incf FSR,F ; Apunta a la próxima posición de RAM.
incf ContadorCaracteres,F ; Apunta a la próxima posición de ROM.
movlw LongitudClave ; Comprueba si ha comparado tantos caracteres
subwf ContadorCaracteres,W ; como longitud tiene la clave secreta.
btfss STATUS,C ; ¿Ha terminado de comparar caracteres?
goto ComparaClaves ; No, pues compara el siguiente carácter.
ClaveCorrecta ; La clave ha sido correcta. Aparecen los mensajes
movlw MensajeClaveCorrecta ; correspondientes y permite la apertura de la
call LCD_Mensaje ; puerta durante unos segundos.
call LCD_Linea2
movlw MensajeAbraPuerta
call LCD_Mensaje
bsf CerraduraSalida ; Activa la cerradura durante unos segundos.
goto Retardo
ClaveIncorrecta
movlw MensajeClaveIncorrecta
call LCD_Mensaje
Retardo
call Retardo_2s
call Retardo_1s
InicializaTodo
bcf CerraduraSalida ; Desactiva la cerradura.
clrf ContadorCaracteres ; Inicializa este contador.
movlw ClaveTecleada ; FSR apunta a la primera dirección de la RAM
movwf FSR ; donde se va a almacenar la clave tecleada.
call LCD_Borra ; Borra la pantalla.
movlw MensajeTeclee ; Aparece el mensaje para que introduzca la clave.
call LCD_Mensaje
call LCD_Linea2 ; Los asteriscos se visualizan en la segunda línea.
FinInterrupcion
call Teclado_EsperaDejePulsar
bcf INTCON,RBIF
retfie
INCLUDE <TECLADO.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <RETARDOS.INC>
; Las posiciones de memoria RAM donde se guardará la clave leída se definen al final, después
; de los Includes, ya que van a ocupar varias posiciones de memoria mediante el
; direccionamiento indirecto utilizado.
CBLOCK
ClaveTecleada
ENDC
END ; Fin del programa.