You are on page 1of 4

#include <p16f877A.

inc> ;Este fichero contiene los nombres y direcciones de los


N EQU 0XA5
CONT_RET EQU 0X20
Teclado_Comprobación EQU 0xF0
ORG 0X00 ;Dirección del Vector Reset
GOTO INICIO ;Comienzo del Programa
ORG 0x04
GOTO INTERRUP
INICIO
BCF STATUS,RP1 ; Ir al Banco 1
BSF STATUS,RP0
CLRF TRISD ; Poner el PORTD como salida de datos.
BCF STATUS,RP0 ; Ir al Banco 0
CALL Teclado_Inicializa ; Configura las líneas del teclado.
CLRF TRISD
MOVLW B'10001000' ; Habilita la interrupción RBI y la general.
MOVWF INTCON
PRINCIPAL SLEEP ; Espera en modo bajo consumo.
GOTO PRINCIPAL
INTERRUP CALL Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.
;MOVWF PORTC ; Llevar el Acumulador al Puerto C.
CALL HEX_7SEG ; Transformar el código Hexadecimal en código de 7 segmentos.
MOVWF PORTD ; Llevar el código al PORTD.
CALL Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter; mientras permanece pulsado.
BCF INTCON,RBIF ; Limpia flag.
RETFIE
HEX_7SEG ADDWF PCL,F
DT 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0x7D,0X07,0X7F,0X6F ,0x77,0x7C,0x39,0x5E,0x79,0x71
CBLOCK
Tecl_TeclaOrden ; Orden de la tecla a chequear.
ENDC
Tecl_UltimaTecla EQU d'15' ; Valor de orden de la última tecla utilizada.
Teclado_LeeHex call Teclado_LeeOrdenTecla ; Lee el Orden de la tecla pulsada.
btfss STATUS,C ; ¿Pulsa alguna tecla?, ¿C=1?
goto Tecl_FinLeeHex ; No, por tanto sale.
call Tecl_ConvierteOrdenEnHex ; Lo convierte en su valor real mediantetabla.
bsf STATUS,C ; Vuelve a posicionar el Carry, porque la
Tecl_FinLeeHex return ; instrucción "addwf PCL,F" lo pone a "0".
Tecl_ConvierteOrdenEnHex addwf PCL,F ; Según el teclado utilizado resulta:
DT 1h,4h,7h,0Eh ; Primera COLUMNA del teclado.
DT 2h,5h,8h,0h ; Segunda COLUMNA del teclado
DT 3h,6h,9h,0Fh ; Tercera COLUMNA del teclado.
DT 0Ah,0Bh,0Ch,0Dh ; Cuarta COLUMNA del teclado.
Teclado_Inicializa
bsf STATUS,RP0 ; Configura las líneas del puerto:
movlw b'11110000' ; <RB7:RB4> entradas, <RB3:RB0> salidas
movwf PORTB
bcf OPTION_REG,NOT_RBPU ; Habilita resistencia de Pull-Up del Puerto B.
bcf STATUS,RP0 ; Acceso al banco 0.
; call Teclado_EsperaDejePulsar
; return
Teclado_EsperaDejePulsar
movlw 0xF0; Pone a cero las cuatro líneas de salida del
movwf PORTB ; Puerto B.
Teclado_SigueEsperando
call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.
movf PORTB,W ; Lee el Puerto B.
sublw 0xF0; Si es lo mismo que escribió es que ya no pulsa
btfss STATUS,Z ; tecla alguna.
goto Teclado_SigueEsperando
return
Teclado_LeeOrdenTecla
clrf Tecl_TeclaOrden ; Todavía no ha empezado a chequear el teclado.
movlw b'11111110' ; Va a chequear primera fila.
Tecl_ChequeaFila ; (Ver esquema de conexión).
movwf PORTB ; Activa la fila correspondiente.
Tecl_Columna1
btfss PORTB,4 ; Chequea la 1ª columna buscando un cero.
goto Tecl_GuardaValor ; Sí, es cero y por tanto guarda su valor y sale.
incf Tecl_TeclaOrden,F ; Va a chequear la siguiente tecla.
Tecl_Columna2 ; Repite proceso para las siguientes
btfss PORTB,5 ; columnas.
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna3
btfss PORTB,6
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna4
btfss PORTB,7
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_TerminaColumnas
movlw Tecl_UltimaTecla
subwf Tecl_TeclaOrden,W ; (W) = (Tecl_TeclaOrden)-Tecl_UltimaTecla.
btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Tecl_TeclaOrden)<15?
goto Tecl_NoPulsada ; No, se ha llegado al final del chequeo.
bsf STATUS,C ; Sí. Va a chequear la siguiente fila.
rlf PORTB,W ; Apunta a la siguiente fila.
goto Tecl_ChequeaFila
Tecl_NoPulsada
bcf STATUS,C ; Posiciona C=0, indicando que no ha pulsado
goto Tecl_FinTecladoLee ; tecla alguna y sale.
Tecl_GuardaValor
movf Tecl_TeclaOrden,W ; El orden de la tecla pulsada en (W) y sale.
bsf STATUS,C ; Como hay tecla tecla pulsada, pone C=1.
Tecl_FinTecladoLee
return
Retardo_20ms
BANKSEL 0
MOVLW N
MOVWF CONT_RET
REPIT
DECFSZ CONT_RET
GOTO REPIT
RETURN
END

#include <p16f877A.inc> ;Este fichero contiene los nombres y direcciones de los


N EQU 0XA5
CONT_RET EQU 0X20
Teclado_Comprobación EQU 0xF0
CBLOCK 0x20
ENDC
ORG 0 ;Dirección del Vector Reset
GOTO INICIO ;Comienzo del Programa
ORG 4
GOTO INTERRUP
ORG 5
INICIO BCF STATUS,RP1 ; Ir al Banco 1
BSF STATUS,RP0
CLRF TRISC ; Poner el PORTC como salida de datos.
MOVLW 0X07 ; Habilitar el PORTE como señales digitales.
MOVWF ADCON1
CLRF TRISE ; Poner el PORTE como salida de datos.
CLRF TRISD ; Poner el PORTD como salida de datos.
BCF STATUS,RP0 ; Ir al Banco 0
BSF PORTE,0 ; Habilitar el display de las unidades.
CLRF PORTC ; Limpiar el Puerto C
CALL Teclado_Inicializa ; Configura las líneas del teclado.
MOVLW B'10001000' ; Habilita la interrupción RBI y la general.
MOVWF INTCON
PRINCIPAL SLEEP ; Espera en modo bajo consumo.
GOTO PRINCIPAL
INTERRUP CALL Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.
MOVWF PORTC ; Llevar el Acumulador al Puerto C.
CALL HEX_7SEG ; Transformar el código Hexadecimal en código de 7 segmentos.
MOVWF PORTD ; Llevar el código al PORTD.
CALL Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter; mientras permanece pulsado.
BCF INTCON,RBIF ; Limpia flag.
RETFIE
HEX_7SEG ADDWF PCL,F
RETLW 3Fh ; El código 7 segmentos para el "0".
RETLW 06h ; El código 7 segmentos para el "1".
RETLW 5Bh ; El código 7 segmentos para el "2".
RETLW 4Fh ; El código 7 segmentos para el "3".
RETLW 66h ; El código 7 segmentos para el "4".
RETLW 6Dh ; El código 7 segmentos para el "5".
RETLW 7Dh ; El código 7 segmentos para el "6".
RETLW 07h ; El código 7 segmentos para el "7".
RETLW 7Fh ; El código 7 segmentos para el "8".
RETLW 67h ; El código 7 segmentos para el "9".
RETLW 77h ; El código 7 segmentos para el "A".
RETLW 7Ch ; El código 7 segmentos para el "B".
RETLW 39h ; El código 7 segmentos para el "C".
RETLW 5Eh ; El código 7 segmentos para el "D".
RETLW 79h ; El código 7 segmentos para el "E".
RETLW 71h ; El código 7 segmentos para el "F".
CBLOCK
Tecl_TeclaOrden ; Orden de la tecla a chequear.
ENDC
Tecl_UltimaTecla EQU d'15' ; Valor de orden de la última tecla utilizada.
Teclado_LeeHex call Teclado_LeeOrdenTecla ; Lee el Orden de la tecla pulsada.
btfss STATUS,C ; ¿Pulsa alguna tecla?, ¿C=1?
goto Tecl_FinLeeHex ; No, por tanto sale.
call Tecl_ConvierteOrdenEnHex ; Lo convierte en su valor real mediantetabla.
bsf STATUS,C ; Vuelve a posicionar el Carry, porque la
Tecl_FinLeeHex return ; instrucción "addwf PCL,F" lo pone a "0".
Tecl_ConvierteOrdenEnHex addwf PCL,F ; Según el teclado utilizado resulta:
DT 7h,8h,9h,0Fh ; Primera fila del teclado.
DT 4h,5h,6h,0Eh ; Segunda fila del teclado
DT 1h,2h,3h,0Dh ; Tercera fila del teclado.
DT 0Ah,0h,0Bh,0Ch ; Cuarta fila del teclado.
Teclado_FinTablaHex
Teclado_Inicializa bsf STATUS,RP0 ; Configura las líneas del puerto:
movlw b'11110000' ; <RB7:RB4> entradas, <RB3:RB0> salidas
movwf PORTB
bcf OPTION_REG,NOT_RBPU ; Habilita resistencia de Pull-Up del Puerto B.
bcf STATUS,RP0 ; Acceso al banco 0.
; call Teclado_EsperaDejePulsar
; return
Teclado_EsperaDejePulsar
movlw 0xF0; Pone a cero las cuatro líneas de salida del
movwf PORTB ; Puerto B.
Teclado_SigueEsperando
call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.
movf PORTB,W ; Lee el Puerto B.
sublw 0xF0; Si es lo mismo que escribió es que ya no pulsa
btfss STATUS,Z ; tecla alguna.
goto Teclado_SigueEsperando
return
Teclado_LeeOrdenTecla
clrf Tecl_TeclaOrden ; Todavía no ha empezado a chequear el teclado.
movlw b'11111110' ; Va a chequear primera fila.
Tecl_ChequeaFila ; (Ver esquema de conexión).
movwf PORTB ; Activa la fila correspondiente.
Tecl_Columna1
btfss PORTB,4 ; Chequea la 1ª columna buscando un cero.
goto Tecl_GuardaValor ; Sí, es cero y por tanto guarda su valor y sale.
incf Tecl_TeclaOrden,F ; Va a chequear la siguiente tecla.
Tecl_Columna2 ; Repite proceso para las siguientes
btfss PORTB,5 ; columnas.
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna3
btfss PORTB,6
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna4
btfss PORTB,7
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
;;Comprueba si ha chequeado la última tecla, en cuyo caso sale. Para ello testea si
; el contenido del registro Tecl_TeclaOrden es igual al número de teclas del teclado.
Tecl_TerminaColumnas
movlw Tecl_UltimaTecla
subwf Tecl_TeclaOrden,W ; (W) = (Tecl_TeclaOrden)-Tecl_UltimaTecla.
btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Tecl_TeclaOrden)<15?
goto Tecl_NoPulsada ; No, se ha llegado al final del chequeo.
bsf STATUS,C ; Sí. Va a chequear la siguiente fila.
rlf PORTB,W ; Apunta a la siguiente fila.
goto Tecl_ChequeaFila
Tecl_NoPulsada
bcf STATUS,C ; Posiciona C=0, indicando que no ha pulsado
goto Tecl_FinTecladoLee ; tecla alguna y sale.
Tecl_GuardaValor
movf Tecl_TeclaOrden,W ; El orden de la tecla pulsada en (W) y sale.
bsf STATUS,C ; Como hay tecla tecla pulsada, pone C=1.
Tecl_FinTecladoLee
return
Retardo_20ms
BANKSEL 0
MOVLW N
MOVWF CONT_RET
REPIT
DECFSZ CONT_RET
GOTO REPIT
RETURN
END