Hola buenas mira esta es mi libreria para el teclado, la cosa es que cuando ejecuto la subrutina lee_tecla analiza la tecla que e pulsada y la guarda en w(registro de trabajo), pero al compararla con el codigo binario que anteriormente he guardado en registro no me funciona es como si no iciera nada:S:S, aqui dejo mi libreria aver si alguien puede echarle un ojo aver si ve algun fayo o algo muchas gracias.
;**************************** Librería "TECLADO_16F84A.INC" ***********************************
;
; Librería de subrutinas para la gestión de un teclado organizado en una matriz de 4 x 3 y
; conectado al Puerto B según la disposición siguiente:
;
; RB4 RB5 RB6
; ^ ^ ^
; |----|----|----|
; RB0 -->| 0 | 1 | 2 |
; |----|----|----|
; RB1 -->| 3 | 4 | 5 |
; |----|----|----|
; RB2 -->| 6 | 7 | 8 |
; |----|----|----|
; RB3 -->| 9 | 10 | 11 |
; |----|----|----|
;
; Los números que se han dibujado dentro de cada cuadrado, son el orden de las teclas,
; que no tienen por qué coincidir con los números reales de las mismas. El paso del número de orden
; de la tecla al valor real de la misma se hace con una tabla de conversión.
;
; **************************************** ZONA DE DATOS ***********************************
;
CBLOCK
ORDEN_TECLA ;Orden de la tecla a chequear.
CONTADOR1
CONTADOR2
ENDC
ULTIMA_TECLA EQU .11 ;Valor de orden de la última tecla utilizada.
COMPROBAR EQU b'11110000' ;Valor que se utilizará para comprobar si una tecla ha sido
;pulsada o no
; ***********************************Subrutina "LEE_TECLA"***********************************
;
; Cada tecla tiene asignado un número de orden que es contabilizado en el registro
; ORDEN_TECLA. Para convertir a su valor según el tipo de teclado en concreto, se
; utiliza una tabla de conversión.
; A continuación se expone la relación entre el número de orden de la tecla y los
; valores correspondientes para el teclado utilizado.
;
; ORDEN DE TECLA: TECLADO UTILIZADO:
; 0 1 2 1 2 3
; 3 4 5 4 5 6
; 6 7 8 7 8 9
; 9 10 11 * 0 #
;
; Así, en este ejemplo, la tecla "7" ocupa el orden 6, y la tecla "0" el orden 10.
;La secuencia a seguir para esta aplicación será:
; Entrada: En (W) el orden de la tecla pulsada.
; Salida: En (W) el valor decimal y ASCII para este teclado concreto.
;********************************************************************************************
;********************************************************************************************
;La siguiente subrutina configura el Puerto B para la conexión al teclado, programando RB <0:3> como salidas y RB <4:6> como entradas
;********************************************************************************************
CONFIGURAR_TECLADO
BANCO1 ; Selecciona banco 1 para manipular TRISB.
movlw 00h ; Configuramos el pueto B como salida
movwf TRISB ; (para poder escribir el contenido de su registro).
BANCO0
; Seleccionamos banco 0 para manipular PORTB
movlw 0xF0 ; Ponemos a 1 los bits RB7, RB6, RB5, RB4.
movwf PORTB ; Cuando uno de estos pins se ponga a 0 (mediante teclado)
; el registro RBIF se pone a 1, si GIE es 1 y RBIE es 1, el
; programa ejecuta la subrutina de atencion a interrupciones
;********* ; para realizar la lectura de la tecla pulsada.
BANCO1
bcf OPTION_REG,7 ;Habilita resistencia de Pull-Up del Puerto B.
movlw b'11110000' ; Carga W con el binario especificado
movwf TRISB ; Configura RB7 a RB4 como entradas y RB3 a RB0 como salidas
; Se bloquea el nibble alto de PORTB,
; es decir, no podemos modificar el valor
; de PORTB<7:4> mediante instrucciones
; MOVWF PORTB.
return ;Retorno de subrutina.
;**************************************************************************************
LEE_TECLA
call ORDEN_TECLAS ;Lee el Orden de la tecla pulsada.
btfss STATUS,C ;Si se pulsa alguna tecla, hacemos C=1 y ejecutaremos la instrucción call ORDEN_EN_CARACTER
goto FIN_LEE ;Si no se pulsa ninguna tecla se habrá acabado la lectura del teclado
call ORDEN_EN_CARACTER ;Si se ha pulsado alguna tecla la subrutina ORDEN_EN_CARACTER la
;convierte en su valor real mediante una tabla.
bsf STATUS,C ;De nuevo se le da el valor 1 a C porque la instrucción "addwf PCL,F" lo pone a "0".
FIN_LEE
return ;Retorna para ejecutar la instrucción call LCD_CARACTER
ORDEN_EN_CARACTER ;Según el teclado utilizado resulta:
addwf PCL,1
retlw b'00110001'
retlw b'00110010'
retlw b'00110011'
retlw b'00110100'
retlw b'00110101'
retlw b'00110110'
retlw b'00110111'
retlw b'00111000'
retlw b'00111001'
retlw b'00101010'
retlw b'00110000'
retlw b'00100011'
FIN_TABLA
;
; Esta tabla se debe situar al principio de la librería con el propósito de que no supere la
; posición 0FFh de memoria ROM de programa. De todas formas, en caso que así fuera
; visualizaría el siguiente mensaje de error en el proceso de ensamblado:
;
IF (FIN_TABLA > 0xFF)
ERROR "Atención: La tabla ha superado el tamaño de la subpágina de los"
MESSG "primeros 256 bytes de memoria ROM. NO funcionará correctamente."
ENDIF
;********************************************************************************************
;La subrutina Pausa_20ms genera un retardo de 20 ms.
;********************************************************************************************
PAUSA_20ms
BANCO0
movlw .26 ;Carga W con el decimal 26
movwf CONTADOR2 ;Carga CONTADOR2 con 1Ah
BUCLE2
movlw .255 ;Carga W con el decimal 255
movwf CONTADOR1 ;Carga CONTADOR1 con 0FFh
BUCLE1
decfsz CONTADOR1,1 ;Decrementa CONTADOR1
goto BUCLE1 ;Decrementa hasta que CONTADOR1 es cero
decfsz CONTADOR2,1 ;Decrementa CONTADOR2
goto BUCLE2 ;Decrementa hasta que CONTADOR2 es cero
nop ;Consume 1 Ciclo de Instrucción
return ;Retorno de subrutina
;*******************************************************************************************
;
;************************************* Subrutina "ESPERA" ***************************************
;
;Permanece en esta subrutina mientras se mantenga pulsada cualquier tecla.
ESPERA
movlw COMPROBAR ;Con estas dos instrucciones se ponen a cero las cuatro líneas de
movwf PORTB ;salida del Puerto B
SIGUE_ESPERANDO
call PAUSA_20ms ;Espera a que se estabilicen los niveles de tensión al pulsar
movfw PORTB ;Lee el Puerto B pasando su valor a W.
sublw COMPROBAR ;Realiza la operación COMPROBAR, menos contenido de W. Si los valores son los mismos es que no ;hay pulsada ninguna tecla
btfss STATUS,Z ;Comprueba el bit Z de STATUS. Si el resultado de la resta anterior es 0, entonces Z = 1 y no ;se leerá la instrucción goto
goto SIGUE_ESPERANDO ;Si Z = 0, es que hay una tecla pulsada y hay que esperar
return ;Retorno de subrutina. El PC se posiciona en la dirección posterior a call ESPERA
;**************************************Subrutina "ORDEN_TECLA"*********************************
;
; Lee el teclado, obteniendo el orden de la tecla pulsada.
ORDEN_TECLAS
clrf ORDEN_TECLA ;Se borra el registro ORDEN_TECLA
movlw b'11111110' ;Se carga FEh en W. Con este valor se activará la fila 1
CHEQUEA_COLUMNAS
movwf PORTB ;Activa la fila correspondiente.
nop
COLUMNA1
btfss PORTB,4 ;Chequea la 1ª columna buscando un cero.
goto GUARDA_VALOR ;Si el bit 4 del Puerto B fuese cero, guardará el valor del registro ORDEN_TECLA en W y saldrá. ;En caso contrario incrementará el registro ORDEN_TECLA
incf ORDEN_TECLA,F ;Si no encuentra un cero, incrementará el registro ORDEN_TECLA y chequeará la siguiente columna
COLUMNA2 ;El proceso es el mismo para todas las columnas
btfss PORTB,5
goto GUARDA_VALOR
incf ORDEN_TECLA,F
COLUMNA3
btfss PORTB,6
goto GUARDA_VALOR
incf ORDEN_TECLA,F
;=============================================================================
;La siguiente subrutina permite saber si se ha chequeado la última tecla. Para ello comprueba si
;el contenido del registro ORDEN_TECLA es igual al número de teclas del teclado.
;=============================================================================
TERMINA_COLUMNAS
movlw ULTIMA_TECLA ;Carga W con el valor 11 decimal
subwf ORDEN_TECLA,W ;(W) = (ORDEN_TECLA)-(ÚLTIMA_TECLA).
btfsc STATUS,C ;Si C=0, W es negativo, y ORDEN_TECLA<12, y no se leerá goto
goto TECLA_NO_PULSADA ;Si C=1, W es positivo o cero y se habrá completado el chequeo.
bsf STATUS,C ;Para chequear la siguiente fila habrá que poner C a 1
rlf PORTB,W ;La fila anterior se pone a 1 y la siguiente a 0.
goto CHEQUEA_COLUMNAS
TECLA_NO_PULSADA
bcf STATUS,C ;Posiciona C=0, indicando que no ha pulsado
goto FIN_TECLADO ;tecla alguna y sale.
GUARDA_VALOR
call ESPERA
movfw ORDEN_TECLA ;Guarda el orden de la tecla pulsada en (W) y sale.
bsf STATUS,C ;Como hay tecla pulsada, pone C=1.
FIN_TECLADO
return ;Retorna para leer la instrucción posterior a call ORDEN_TECLAS