Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.     __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
  2.     LIST       P=16F84A
  3.     INCLUDE  <P16F84A.INC>
  4.  
  5.     CBLOCK  0x0C
  6.     ENDC
  7.  
  8. ; La clave puede tener cualquier tamaño y su longitud se calcula:
  9.  
  10. #DEFINE  LongitudClave  (FinClaveSecreta-ClaveSecreta)
  11. #DEFINE  CerraduraSalida    PORTA,3
  12.  
  13. ; ZONA DE CÓDIGOS ********************************************************************
  14.  
  15.     ORG 0
  16.     goto    Inicio
  17.     ORG 4
  18.     goto    ServicioInterrupcion
  19.  
  20. Mensajes
  21.     addwf   PCL,F
  22. MensajeTeclee
  23.     DT  "Teclee CLAVE:", 0x00
  24. MensajeClaveCorrecta
  25.     DT  "Clave CORRECTA", 0x00
  26. MensajeAbraPuerta
  27.     DT  "Abra la puerta", 0x00
  28. MensajeClaveIncorrecta
  29.     DT  "Clave INCORRECTA", 0x00
  30. ;
  31. LeeClaveSecreta
  32.     addwf   PCL,F
  33. ClaveSecreta
  34.     DT  4h,5h,6h,0Eh        ; Ejemplo de clave secreta.
  35.     DT  7h,8h
  36. FinClaveSecreta
  37.  
  38. Inicio  call    LCD_Inicializa
  39.     bsf STATUS,RP0
  40.     bcf CerraduraSalida     ; Define como salida.
  41.     bcf STATUS,RP0
  42.     call    Teclado_Inicializa      ; Configura las líneas del teclado.
  43.     call    InicializaTodo      ; Inicializa el resto de los registros.
  44.     movlw   b'10001000'     ; Habilita la interrupción RBI y la general.
  45.     movwf   INTCON
  46. Principal
  47.     sleep               ; Espera en modo bajo consumo que pulse alguna tecla.
  48.     goto    Principal
  49.  
  50. ; Subrutina "ServicioInterrupcion" ------------------------------------------------------
  51. ;
  52.     CBLOCK
  53.     ContadorCaracteres
  54.     GuardaClaveTecleada
  55.     ENDC
  56.  
  57. ServicioInterrupcion
  58.     call    Teclado_LeeHex      ; Obtiene el valor hexadecimal de la tecla pulsada.
  59. ;
  60. ; Según va introduciendo los dígitos de la clave, estos van siendo almacenados a partir de
  61. ; las posiciones RAM "ClaveTecleada" mediante direccionamiento indirecto y utilizando el
  62. ; FSR como apuntador. Por cada dígito leído en pantalla se visualiza un asterisco.
  63. ;
  64.     movwf   INDF            ; Almacena ese dígito en memoria RAM con
  65.                     ; con direccionamiento indirecto apuntado por FSR.
  66.     movlw   '*'         ; Visualiza asterisco.
  67.     call    LCD_Caracter
  68.     incf    FSR,F           ; Apunta a la próxima posición de RAM.
  69.     incf    ContadorCaracteres,F    ; Cuenta el número de teclas pulsadas.
  70.     movlw   LongitudClave       ; Comprueba si ha introducido tantos caracteres
  71.     subwf   ContadorCaracteres,W    ; como longitud tiene la clave secreta.
  72.     btfss   STATUS,C        ; ¿Ha terminado de introducir caracteres?
  73.     goto    FinInterrupcion     ; No, pues lee el siguiente carácter tecleado.
  74. ;
  75. ; Si ha llegado aquí es porque ha terminado de introducir el máximo de dígitos. Ahora
  76. ; procede a comprobar si la clave es correcta. Para ello va comparando cada uno de los
  77. ; dígitos almacenados en las posiciones RAM a partir de "ClaveTecleada" con el valor
  78. ; correcto de la clave almacenado en la posición ROM "ClaveSecreta".
  79. ;
  80. ; Para acceder a las posiciones de memoria RAM a partir de "ClaveTecleada" utiliza
  81. ; direccionamiento indirecto siendo FSR el apuntador.
  82. ;
  83. ; Para acceder a memoria ROM "ClaveSecreta" se utiliza direccionamiento indexado con el
  84. ; el registro ContadorCaracteres como apuntador.
  85. ;
  86.     call    LCD_Borra       ; Borra la pantalla.
  87.     clrf    ContadorCaracteres      ; Va a leer el primer carácter almacenado en ROM.
  88.     movlw   ClaveTecleada       ; Apunta a la primera posición de RAM donde se ha
  89.     movwf   FSR         ; guardado la clave tecleada.
  90. ComparaClaves
  91.     movf    INDF,W          ; Lee la clave tecleada y guardada en RAM.
  92.     movwf   GuardaClaveTecleada ; La guarda para compararla después.
  93.     movf    ContadorCaracteres,W    ; Apunta al carácter de ROM a leer.
  94.     call    LeeClaveSecreta     ; En (W) el carácter de la clave secreta.
  95.     subwf   GuardaClaveTecleada,W   ; Se comparan.
  96.     btfss   STATUS,Z        ; ¿Son iguales?, ¿Z=1?
  97.     goto    ClaveIncorrecta     ; No, pues la clave tecleada es incorrecta.
  98.     incf    FSR,F           ; Apunta a la próxima posición de RAM.
  99.     incf    ContadorCaracteres,F    ; Apunta a la próxima posición de ROM.
  100.     movlw   LongitudClave       ; Comprueba si ha comparado tantos caracteres
  101.     subwf   ContadorCaracteres,W    ; como longitud tiene la clave secreta.
  102.     btfss   STATUS,C        ; ¿Ha terminado de comparar caracteres?
  103.     goto    ComparaClaves       ; No, pues compara el siguiente carácter.
  104. ClaveCorrecta               ; La clave ha sido correcta. Aparecen los mensajes
  105.     movlw   MensajeClaveCorrecta    ; correspondientes y permite la apertura de la
  106.     call    LCD_Mensaje     ; puerta durante unos segundos.
  107.     call    LCD_Linea2
  108.     movlw   MensajeAbraPuerta
  109.     call    LCD_Mensaje
  110.     bsf CerraduraSalida     ; Activa la cerradura durante unos segundos.
  111.     goto    Retardo
  112. ClaveIncorrecta
  113.     movlw   MensajeClaveIncorrecta
  114.     call    LCD_Mensaje
  115. Retardo
  116.     call    Retardo_2s
  117.     call    Retardo_1s
  118. InicializaTodo
  119.     bcf CerraduraSalida     ; Desactiva la cerradura.
  120.     clrf    ContadorCaracteres      ; Inicializa este contador.
  121.     movlw   ClaveTecleada       ; FSR apunta a la primera dirección de la RAM
  122.     movwf   FSR         ; donde se va a almacenar la clave tecleada.
  123.     call    LCD_Borra       ; Borra la pantalla.
  124.     movlw   MensajeTeclee       ; Aparece el mensaje para que introduzca la clave.
  125.     call    LCD_Mensaje
  126.     call    LCD_Linea2      ; Los asteriscos se visualizan en la segunda línea.
  127. FinInterrupcion
  128.     call    Teclado_EsperaDejePulsar
  129.     bcf INTCON,RBIF
  130.     retfie 
  131.  
  132.     INCLUDE  <TECLADO.INC>
  133.     INCLUDE  <LCD_4BIT.INC>
  134.     INCLUDE  <LCD_MENS.INC>
  135.     INCLUDE  <RETARDOS.INC>
  136.  
  137. ; Las posiciones de memoria RAM donde se guardará la clave leída se definen al final, después
  138. ; de los Includes, ya que van a ocupar varias posiciones de memoria mediante el
  139. ; direccionamiento indirecto utilizado.
  140.  
  141.     CBLOCK
  142.     ClaveTecleada
  143.     ENDC
  144.  
  145.     END             ; Fin del programa.