Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
list p=16f877
include p16f877.inc
__CONFIG _CP_OFF&_WDT_OFF&_DEBUG_OFF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_XT_OSC
;__config 0x3F18
cblock 0x20
TECLA ;valor de tecla pulsada
SN ;valor de tecla si/no
CONT ;para retardo
LCD_ApuntaCaracter ; posición del carácter a visualizar respecto del comienzo
LCD_ValorCaracter ; Código ASCII del carácter a visualizar
;Caract
LCD_Dato
LCD_GuardaDato
LCD_GuardaTRISD
LCD_Auxiliar1
LCD_Auxiliar2
R_ContA ; Contadores para los retardos.
R_ContB
R_ContC
endc
LCD_CPorLinea EQU .16
#DEFINE LCD_PinRS PORTE,0
#DEFINE LCD_PinRW PORTE,1
#DEFINE LCD_PinEnable PORTE,2
#DEFINE LCD_BusDatos PORTD
;::::::::::::::::::::::::::::::::::::::::::::::::::::
org 0x00
MOVLW b'00000000'
MOVWF INTCON ; deshabilitamos GIE y T0IE
BCF STATUS,RP0
INI
bsf STATUS,RP0 ; Cambio a banco 1
;PUERTO C, CONTROL DE TECLADO MATRICIAL
movlw 0x38 ; RC3, RC4 y RC5 como entradas: columnas
movwf TRISC ; y RC2, RC1 y RC0 como salidas: filas
;PUERTOS A Y B PARA TTL TESTER, SE CONFIGURARÁN DEPENDIENDO DE LO QUE SE REQUIERA
;PUERTO D PARA BUS DE DATOS DE LCD
clrf TRISD ; Puerto D como salida
;PUERTO E PARA CONTROL DE LCD
;E0 RS
;E1 R/W
;E2 EN
bsf STATUS,RP0 ; Cambio a banco 1
clrf TRISE ; Puerto E como salida
;
BCF STATUS, RP1 ; Bank0
;CLRF PORTA ; Initialize PORTA by
; clearing output
; data latches
BSF STATUS, RP0 ; Selecciona Banco 1
MOVLW 0x06 ; Configura los pines de PTOA y PTOE
MOVWF ADCON1 ; como i/o digital
MOVLW 0x00 ;
MOVWF TRISE; PUERTO E COMO SALIDA DIGITAL
;INICIALIZAR LCD CON BUS DE 8 BITS
INI_LCD
call LCD_Inicializa
;ESCRIBIR EL LA LCD: ELIJA COMPUERTA
Inicio
movlw Mensaje0 ; Carga la posición del mensaje inicial.
call LCD_Mensaje ; Visualiza el mensaje.
PRINCIPAL
call TTL ; Llamar a rutina de teclado
goto PRINCIPAL ; Ejecución cíclica del programa
;LEE TECLADO
TTL
clrf TECLA ; Limpiar variable TECLA
movlw b'00000110' ; Poner un cero en la primer
movwf PORTC ; fila del puerto C (RC0)
CHECA_COL
btfss PORTC,3 ; Si al 1er columna es "0"
goto ANTIRREBOTES ; salta a la rutina ANTIRREBOTES
incf TECLA,f ; Si es "1" incrementa TECLA
btfss PORTC,4 ; Si la 2da columna es "0"
goto ANTIRREBOTES ; salta a la rutina ANTIRREBOTES
incf TECLA,f ; Si es "1" incrementa TECLA
;para que despues de revisar teclas, si ni ha habido alguna
;pulsación regrese a revisar la tecla 0 o recorra el 0 en las filas
movlw d'5'
subwf TECLA,w
btfsc STATUS,Z ; si ha revisado todas las teclas y nunguna ha sido pulsada
goto TTL ; reiniciará la revisión del teclado
bsf STATUS,C ; si no ha terminado con la revisión del teclado
rlf PORTC,f ; rotará el 0 a la siguiente fila
goto CHECA_COL ; revisará las columnas
ANTIRREBOTES
C1 btfss PORTC,3
goto C1
C2 btfss PORTC,4
goto C2
movf TECLA,w
call COMPUERTA
; goto SI_NO
; return
; Mensaje: ¿Revisar otra?
movlw Mensaje13 ; Carga la posición del mensaje inicial.
call LCD_Borra ;
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
SI_NO
clrf SN ; Limpiar variable SN
movlw b'00000110' ; Poner un cero en la primer
movwf PORTC ; fila del puerto C (RC0)
CHECA_COLSI
btfss PORTC,5 ; Si la columna es "0" (TECLA SI: PRESIONADA)
goto TTL ; regresa a leer el teclado
incf SN,F
movlw d'2'
subwf SN,w
btfsc STATUS,Z
goto TTL
bsf STATUS,C
rlf PORTC,f
btfss PORTC,5 ; Si la columna es "0" (TECLA NO: PRESIONADA)
goto final ; sale del programa
goto CHECA_COLSI ; ningún botón ha sido pulsado, regresa a revisar teclado
COMPUERTA
addwf PCL,F ; Salta a la configuración adecuada.
;Tabla
goto AND
goto NOT
goto NOR
goto OR
goto NAND
goto XOR
AND
movlw 0x0D
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta AND
bcf STATUS,RP0 ; Cambio a banco 0
movlw 0x9B ;
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 0
;Escribe AND en la LCD
movlw Mensaje1 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
;------------------------------
;REVISA COMPUERTA AND1 DEL INTEGRADO
bcf PORTA,3
bcf PORTA,2
btfsc PORTA,1
call E1
bcf PORTA,3
bsf PORTA,2
btfsc PORTA,1
call E1
bsf PORTA,3
bsf PORTA,2
btfss PORTA,1
call E1
;-----------------
;REVISA COMPUERTA AND2 DEL INTEGRADO
bcf PORTA,0
bcf PORTB,7
btfsc PORTB,6
call E2
bcf PORTA,0
bsf PORTB,7
btfsc PORTB,6
call E2
bsf PORTA,0
bsf PORTB,7
btfss PORTB,6
call E2
;----------------------
;REVISA COMPUERTA AND3 DEL INTEGRADO
bcf PORTB,0
bcf PORTB,1
btfsc PORTB,2
call E3
bcf PORTB,0
bsf PORTB,1
btfsc PORTB,2
call E3
bsf PORTB,0
bsf PORTB,1
btfss PORTB,2
call E3
;------------------------
;REVISA COMPUERTA AND4 DEL INTEGRADO
bcf PORTB,3
bcf PORTB,4
btfsc PORTB,5
call E4
bcf PORTB,3
bsf PORTB,4
btfsc PORTB,5
call E4
bsf PORTB,3
bsf PORTB,4
btfss PORTB,5
call E4
goto fin_comp
OR
movlw 0x0D
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta OR
movlw 0x9B ;
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 1
movlw Mensaje2 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
;-----------------------------------
;REVISA COMPUERTA OR1 DEL INTEGRADO
bcf PORTA,3
bcf PORTA,2
btfsc PORTA,1
call E1
bcf PORTA,3
bcf PORTA,2
btfss PORTA,1
call E1
bsf PORTA,3
bsf PORTA,2
btfss PORTA,1
call E1
;-----------------------------------
;REVISA COMPUERTA OR2 DEL INTEGRADO
bcf PORTA,0
bcf PORTB,7
btfsc PORTB,6
call E2
bcf PORTA,0
bcf PORTB,7
btfss PORTB,6
call E2
bsf PORTA,0
bsf PORTB,7
btfss PORTB,6
call E2
;-----------------------------------
;REVISA COMPUERTA OR3 DEL INTEGRADO
bcf PORTB,0
bcf PORTB,1
btfsc PORTB,2
call E3
bcf PORTB,0
bcf PORTB,1
btfss PORTB,2
call E3
bsf PORTB,0
bsf PORTB,1
btfss PORTB,2
call E3
;-----------------------------------
;REVISA COMPUERTA OR4 DEL INTEGRADO
bcf PORTB,3
bcf PORTB,4
btfsc PORTB,5
call E4
bcf PORTB,3
bcf PORTB,4
btfss PORTB,5
call E4
bsf PORTB,3
bsf PORTB,4
btfss PORTB,5
call E4
goto fin_comp
NOT
movlw 0x0A
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta NOT
movlw 0x95 ;
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 1
movlw Mensaje3 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
bcf PORTA,3
btfss PORTA,2
call E1
;-----------------------------------
;REVISA COMPUERTA NOT1 DEL INTEGRADO
bcf PORTA,1
btfss PORTA,0
call E1
;-----------------------------------
;REVISA COMPUERTA NOT2 DEL INTEGRADO
bcf PORTB,7
btfss PORTB,6
call E2
;-----------------------------------
;REVISA COMPUERTA NOT3 DEL INTEGRADO
bcf PORTB,0
btfss PORTB,1
call E3
;-----------------------------------
;REVISA COMPUERTA NOT4 DEL INTEGRADO
bcf PORTB,2
btfss PORTB,3
call E4
;-----------------------------------
;REVISA COMPUERTA NOT5 DEL INTEGRADO
bcf PORTB,4
btfss PORTB,5
call E5
;-----------------------------------
;REVISA COMPUERTA NOT6 DEL INTEGRADO
bcf PORTB,6
btfss PORTB,7
call E6
goto fin_comp
NAND
movlw 0x0D
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta OR
movlw 0x9B ;
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 1
movlw Mensaje4 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
;-----------------------------------
;REVISA COMPUERTA NAND1 DEL INTEGRADO
bcf PORTA,3
bcf PORTA,2
btfss PORTA,1
call E1
bcf PORTA,3
bsf PORTA,2
btfss PORTA,1
call E1
bsf PORTA,3
bsf PORTA,2
btfsc PORTA,1
call E1
;-----------------------------------
;REVISA COMPUERTA NAND2 DEL INTEGRADO
bcf PORTA,0
bcf PORTB,7
btfss PORTB,6
call E2
bcf PORTA,0
bsf PORTB,7
btfss PORTB,6
call E2
bsf PORTA,0
bsf PORTB,7
btfsc PORTB,6
call E2
;-----------------------------------
;REVISA COMPUERTA NAND3 DEL INTEGRADO
bcf PORTB,0
bcf PORTB,1
btfss PORTB,2
call E3
bcf PORTB,0
bsf PORTB,1
btfss PORTB,2
call E3
bsf PORTB,0
bsf PORTB,1
btfsc PORTB,2
call E3
;-----------------------------------
;REVISA COMPUERTA NAND4 DEL INTEGRADO
bcf PORTB,3
bcf PORTB,4
btfss PORTB,5
call E4
bcf PORTB,3
bsf PORTB,4
btfss PORTB,5
call E4
bsf PORTB,3
bsf PORTB,4
btfsc PORTB,5
call E4
goto fin_comp
NOR
movlw 0x06
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta OR
movlw 0xF6 ;
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 0
movlw Mensaje5 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
;-----------------------------------
;REVISA COMPUERTA NOR1 DEL INTEGRADO
bcf PORTA,3
bcf PORTA,2
btfss PORTA,1
call E1
bcf PORTA,3
bsf PORTA,2
btfsc PORTA,1
call E1
bsf PORTA,3
bsf PORTA,2
btfsc PORTA,1
call E1
;-----------------------------------
;REVISA COMPUERTA NOR2 DEL INTEGRADO
bcf PORTA,0
bcf PORTB,7
btfss PORTB,6
call E2
bcf PORTA,0
bsf PORTB,7
btfsc PORTB,6
call E2
bsf PORTA,0
bsf PORTB,7
btfsc PORTB,6
call E2
;-----------------------------------
;REVISA COMPUERTA NOR3 DEL INTEGRADO
bcf PORTB,0
bcf PORTB,1
btfss PORTB,2
call E3
bcf PORTB,0
bsf PORTB,1
btfsc PORTB,2
call E3
bsf PORTB,0
bsf PORTB,1
btfsc PORTB,2
call E3
;-----------------------------------
;REVISA COMPUERTA NOR4 DEL INTEGRADO
bcf PORTB,3
bcf PORTB,4
btfss PORTB,5
call E4
bcf PORTB,3
bsf PORTB,4
btfsc PORTB,5
call E4
bsf PORTB,3
bsf PORTB,4
btfsc PORTB,5
call E4
movlw Mensaje5 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
XOR
movlw 0x0D
bsf STATUS,RP0 ; Cambio a banco 1
movwf TRISA ; configurar las entradas y salidas de la compuerta OR
movlw 0x9B ;
movwf TRISB ;
bcf STATUS,RP0 ; Cambio a banco 1
movlw Mensaje6 ; Carga la posición del mensaje.
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
;-----------------------------------
;REVISA COMPUERTA XOR1 DEL INTEGRADO
bcf PORTA,3
bcf PORTA,2
btfss PORTA,1
call E1
bsf PORTA,3
bcf PORTA,2
btfsc PORTA,1
call E1
bsf PORTA,3
bsf PORTA,2
btfss PORTA,1
call E1
;-----------------------------------
;REVISA COMPUERTA XOR2 DEL INTEGRADO
bcf PORTA,0
bcf PORTB,7
btfss PORTB,6
call E2
bsf PORTA,0
bcf PORTB,7
btfsc PORTB,6
call E2
bsf PORTA,0
bsf PORTB,7
btfss PORTB,6
call E2
;-----------------------------------
;REVISA COMPUERTA XOR3 DEL INTEGRADO
bcf PORTB,0
bcf PORTB,1
btfss PORTB,2
call E3
bsf PORTB,0
bcf PORTB,1
btfsc PORTB,2
call E3
bsf PORTB,0
bsf PORTB,1
btfss PORTB,2
call E3
;-----------------------------------
;REVISA COMPUERTA XOR4 DEL INTEGRADO
bcf PORTB,3
bcf PORTB,4
btfss PORTB,5
call E4
bsf PORTB,3
bcf PORTB,4
btfsc PORTB,5
call E4
bsf PORTB,3
bsf PORTB,4
btfss PORTB,5
call E4
goto fin_comp
fin_comp
return
;** FIN SUBRUTINA REVISIÓN DE TTLs **
;***Subrutina de Inicialización de LCD
LCD_Inicializa
bsf STATUS,RP0 ; Configura las líneas conectadas al pines RS,
bcf LCD_PinRS ; R/W y E.
bcf STATUS,RP0
bcf LCD_PinEnable
bsf STATUS,RP0
bcf LCD_PinRW
bcf STATUS,RP0
bsf STATUS,RP0
bcf LCD_PinRW ; En caso de que esté conectado le indica
; que se va a escribir en el LCD.
bcf STATUS,RP0
bcf LCD_PinEnable ; Impide funcionamiento del LCD poniendo E=0.
bcf LCD_PinRS ; Activa el Modo Comando poniendo RS=0.
call Retardo_200ms
movlw b'00111000'
call LCD_Envia ; Escribe el dato en el LCD.
call Retardo_5ms
movlw b'00110000'
call LCD_Envia
call Retardo_200micros
movlw b'00110000'
call LCD_Envia
call Retardo_200micros ; Este retardo es necesario para simular en PROTEUS.
movlw b'00110000' ; Interface de 8 bits.
call LCD_Envia
call Retardo_20micros ; Este retardo es necesario para simular en PROTEUS.
; Ahora configura el resto de los parámetros:
call LCD_2Lineas8Bits5x7 ; LCD de 2 líneas y caracteres de 5x7 puntos, bus de 8.
call LCD_Borra ; Pantalla encendida y limpia. Cursor al principio
call LCD_CursorOFF ; de la línea 1. Cursor apagado.
call LCD_CursorIncr ; Cursor en modo incrementar.
return
;Subrutinas para inicializacion LCD
LCD_CursorOFF ; Pantalla encendida y cursor apagado.
movlw b'00001100'
goto LCD_EnviaComando
LCD_Borra ; Borra toda la pantalla, memoria DDRAM y pone el
movlw b'00000001' ; cursor a principio de la línea 1.
goto LCD_EnviaComando
LCD_CursorIncr ; Cursor en modo incrementar.
movlw b'00000110'
goto LCD_EnviaComando
LCD_2Lineas8Bits5x7 ; Define la pantalla de 2 líneas, con caracteres
movlw b'00111000' ; de 5x7 puntos y conexión al PIC mediante bus de
goto LCD_EnviaComando ; 8 bits.
LCD_EnviaComando
bcf LCD_PinRS ; Activa el Modo Comando, poniendo RS=0.
goto LCD_Envia
Caract
bsf LCD_PinRS ; Activa el "Modo Dato", poniendo RS=1.
LCD_Envia
movwf LCD_GuardaDato ; Guarda el dato a enviar.
bsf STATUS,RP0 ; Acceso al Banco 1.
movf TRISD,W ; Guarda la configuración que tenía antes TRISD.
movwf LCD_GuardaTRISD
clrf TRISD ; Puerto D como salida.
bcf STATUS,RP0 ; Acceso al Banco 0.
;
movf LCD_GuardaDato,W ; Recupera el dato a enviar.
movwf LCD_BusDatos ; Envía el dato al módulo LCD.
bcf STATUS,RP0
bsf LCD_PinEnable ; Permite funcionamiento del LCD mediante un pequeño
nop
bcf STATUS,RP0
bcf LCD_PinEnable ; pulso y termina impidiendo el funcionamiento del LCD.
bsf STATUS,RP0 ; Acceso al Banco 1. Restaura el antiguo valor en
movf LCD_GuardaTRISD,W ; la configuración del Puerto B.
movwf TRISD
bcf STATUS,RP0 ; Acceso al Banco 0.
btfss LCD_PinRS ; Debe garantizar una correcta escritura manteniendo
call Retardo_20ms ; 2 ms en modo comando y 50 µs en modo cáracter.
call Retardo_50micros
return
; ***SUBRUTINAS DE MENSAJES***
LCD_Mensaje
movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.
movlw Mensajes ; Halla la posición relativa del primer carácter
subwf LCD_ApuntaCaracter,F ; del mensaje respecto de etiqueta "Mensajes".
decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".
LCD_VisualizaOtroCaracter
movf LCD_ApuntaCaracter,W
call Mensajes ; Obtiene el código ASCII del carácter apuntado.
movwf LCD_ValorCaracter ; Guarda el valor de carácter.
movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En caso
btfsc STATUS,Z ; que sea "0x00", que es código indicador final
goto LCD_FinMensaje ; de mensaje, sale fuera.
LCD_NoUltimoCaracter
call Caract ; Visualiza el carácter ASCII leído.
incf LCD_ApuntaCaracter,F ; Apunta a la posición del siguiente carácter
goto LCD_VisualizaOtroCaracter ; dentro del mensaje.
LCD_FinMensaje
return
;Tabla de contenido de mensajes
Mensajes
addwf PCL,F
Mensaje0 ; Mensaje de inico
DT "ELIJA COMPUERTA", 0x0E ; Terminación de mensaje
Mensaje1 ; Mensaje compuerta AND
DT "AND", 0x08 ; Terminación de mensaje
Mensaje2 ; Mensaje compuerta OR
DT "OR", 0x08 ; Terminación de mensaje
Mensaje3 ; Mensaje compuerta NOT
DT "NOT", 0x08 ; Terminación de mensaje
Mensaje4 ; Mensaje compuerta NAND
DT "NAND", 0x08 ; Terminación de mensaje
Mensaje5 ; Mensaje compuerta NOR
DT "NOR", 0x08 ; Terminación de mensaje
Mensaje6 ; Mensaje compuerta XOR
DT "XOR", 0x08 ; Terminación de mensaje
Mensaje7 ; Mensaje compuerta E1
DT "Error Compuerta1", 0x0F ; Terminación de mensaje
Mensaje8 ; Mensaje compuerta E2
DT "Error Compuerta2", 0x0F ; Terminación de mensaje
Mensaje9 ; Mensaje compuerta E3
DT "Error Compuerta3", 0x0F ; Terminación de mensaje
Mensaje10 ; Mensaje compuerta E4
DT "Error Compuerta4", 0x0F ; Terminación de mensaje
Mensaje11 ; Mensaje compuerta E5
DT "Error Compuerta5", 0x0F ; Terminación de mensaje
Mensaje12 ; Mensaje compuerta E6
DT "Error Compuerta6", 0x0F ; Terminación de mensaje
Mensaje13 ; Mensaje compuerta E6
DT "¿Revisar otra?", 0x0E ; Terminación de mensaje
FinMensajes
;Errores
E1
movlw Mensaje7 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
E2
movlw Mensaje8 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
E3
movlw Mensaje9 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
E4
movlw Mensaje10 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
E5
movlw Mensaje11 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
E6
movlw Mensaje12 ; Carga la posición del mensaje.
call LCD_Borra ;borra LCD
call LCD_Mensaje ; Visualiza el mensaje.
call Retardo_500ms
return
;***RETARDOS***
; RETARDOS de 4 hasta 10 microsegundos ---------------------------------------------------
;
; A continuación retardos pequeños teniendo en cuenta que para una frecuencia de 4 MHZ,
; la llamada a subrutina "call" tarda 2 ciclos máquina, el retorno de subrutina
; "return" toma otros 2 ciclos máquina y cada instrucción "nop" tarda 1 ciclo máquina.
;
Retardo_10micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
Retardo_5micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
Retardo_4micros ; La llamada "call" aporta 2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;
; RETARDOS de 20 hasta 500 microsegundos ------------------------------------------------
;
Retardo_500micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d'164' ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_200micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d'64' ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_100micros ; La llamada "call" aporta 2 ciclos máquina.
movlw d'31' ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_50micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d'14' ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_20micros ; La llamada "call" aporta 2 ciclos máquina.
movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "K".
RetardoMicros
movwf R_ContA ; Aporta 1 ciclo máquina.
Rmicros_Bucle
decfsz R_ContA,F ; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto Rmicros_Bucle ; Aporta (K-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
Retardo_200ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_100ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_50ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'50' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_20ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_10ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'10' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_5ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_2ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'2' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_1ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'1' ; Aporta 1 ciclo máquina. Este es el valor de "M".
Retardos_ms
movwf R_ContB ; Aporta 1 ciclo máquina.
R1ms_BucleExterno
movlw d'249' ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
nop ; Aporta KxMx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
goto R1ms_BucleInterno ; Aporta (K-1)xMx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1ms_BucleExterno ; Aporta (M-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
Retardo_500ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "N".
Retardo_1Decima
movwf R_ContC ; Aporta 1 ciclo máquina.
R1Decima_BucleExterno2
movlw d'100' ; Aporta Nx1 ciclos máquina. Este es el valor de "M".
movwf R_ContB ; Aporta Nx1 ciclos máquina.
R1Decima_BucleExterno
movlw d'249' ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta MxNx1 ciclos máquina.
R1Decima_BucleInterno
nop ; Aporta KxMxNx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.
decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
final
end
banksel TRISA; Cambio a banco 1
;PUERTO C, CONTROL DE TECLADO MATRICIAL
movlw 0x38 ; RC3, RC4 y RC5 como entradas: columnas
movwf TRISC ; y RC2, RC1 y RC0 como salidas: filas
;PUERTOS A Y B PARA TTL TESTER, SE CONFIGURARÁN DEPENDIENDO DE LO QUE SE REQUIERA
;PUERTO D PARA BUS DE DATOS DE LCD
clrf TRISD ; Puerto D como salida
;PUERTO E PARA CONTROL DE LCD
;E0 RS
;E1 R/W
;E2 EN
clrf TRISE ; Puerto E como salida
MOVLW 0x06 ; Configura los pines de PTOA y PTOE
MOVWF ADCON1 ; como i/o digital
banksel PORTA;Cambio a banco 0
;**************************** Librería "TECLADO2.INC" ***********************************
;
; Librería de subrutinas para la gestión de un teclado organizado en una matriz de 4 x 4 y
; conectado al Puerto B según la disposición siguiente:
;
; RC4 RC5 RC6 RC7
; ^ ^ ^ ^
; |----|----|----|----|
; RC0 --> | 0 | 1 | 2 | 3 |
; |----|----|----|----|
; RC1 --> | 4 | 5 | 6 | 7 |
; |----|----|----|----|
; RC2 --> | 8 | 9 | 10 | 11 |
; |----|----|----|----|
; RC3 --> | 12 | 13 | 14 | 15 |
; |----|----|----|----|
;
; Los números que se han dibujado dentro de cada cuadrado son el orden de las teclas
; que no tienen por qué coincidir con lo serigrafiado sobre ellas. El paso del número de orden
; de la tecla al valor que hay serigrafiado sobre la misma se hace con una tabla de conversión.
;
; ZONA DE DATOS **********************************************************************
;
CBLOCK
Tecl_TeclaOrden ; Orden de la tecla a chequear.
Caracter_Hex
ENDC
Tecl_UltimaTecla EQU d'15' ; Valor de orden de la última tecla utilizada.
; Subrutina "Teclado_LeeHex" ************************************************************
;
; Cada tecla tiene asignado un número de orden que es contabilizado en la variable
; Tecl_TeclaOrden. 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 hexadecimal utilizado.
;
; ORDEN DE TECLA: TECLADO HEX. UTILIZADO:
; 0 1 2 3 1 2 3 A
; 4 5 6 7 6 5 4 B
; 8 9 10 11 7 8 9 C
; 12 13 14 15 E 0 F D
;
; Así, en este ejemplo, la tecla "7" ocupa el orden 8, la tecla "F" ocupa el orden 14 y la
; tecla "9" el orden 10.
; Si cambia el teclado también hay cambiar de tabla de conversión.
;
; Entrada: En (W) el orden de la tecla pulsada.
; Salida: En (W) el valor hexadecimal para este teclado concreto.
;
ORG 0x00E0
Tecl_ConvierteOrdenEnHex ; Según el teclado utilizado resulta:
addwf PCL,F
DT 1h,2h,3h,0Ah ; Primera fila del teclado.
DT 4h,5h,6h,0Bh ; Segunda fila del teclado
DT 7h,8h,9h,0Ch ; Tercera fila del teclado.
DT 0Eh,0h,0Fh,0Dh ; Cuarta fila del teclado.
Teclado_FinTablaHex
;;
; ORG 0x0750
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 mediante tabla.
movwf Caracter_Hex
call Teclado_EsperaDejePulsar
bsf STATUS,C ; Vuelve a posicionar el Carry, porque la
Tecl_FinLeeHex ; instrucción "addwf PCL,F" lo pone a "0".
return
;
;
; Esta tabla se sitúa 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 (Teclado_FinTablaHex > 0xFFF)
; ERROR "Atención: La tabla ha superado el tamaño de la página de los"
; MESSG "primeros 256 bytes de memoria ROM. NO funcionará correctamente."
; ENDIF
;;
; Subrutina "Teclado_Inicializa" --------------------------------------------------------
;
; Esta subrutina configura las líneas del Puerto B según la conexión del teclado realizada
; y comprueba que no hay pulsada tecla alguna al principio.
Teclado_Inicializa
bsf STATUS,RP0 ; Configura las líneas del puerto:
movlw b'11110000' ; <RC7:RC4> entradas, <RC3:RC0> salidas
movwf PORTD
bcf STATUS,RP0 ; Acceso al banco
return
; Subrutina "Teclado_EsperaDejePulsar" --------------------------------------------------
;
;Permanece en esta subrutina mientras siga pulsada la tecla.
;
Teclado_Comprobacion EQU b'11110000'
Teclado_EsperaDejePulsar
movlw Teclado_Comprobacion ; Pone a cero las cuatro líneas de salida del
movwf PORTD ; Puerto B.
Teclado_SigueEsperando
call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.
movf PORTD,W ; Lee el Puerto B.
sublw Teclado_Comprobacion ; Si es lo mismo que escribió es que ya no pulsa
btfss STATUS,Z ; tecla alguna.
goto Teclado_SigueEsperando
return
;
; Subrutina "Teclado_LeeOrdenTecla" -----------------------------------------------------
;
; Lee el teclado, obteniendo el orden de la tecla pulsada.
;
; Salida: En (W) el número de orden de la tecla pulsada. Además Carry se pone a "1" si
; se pulsa una tecla ó a "0" si no se pulsa tecla alguna.
;
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 PORTD ; Activa la fila correspondiente.
call Retardo_1ms ; Espera a que se estabilicen los niveles de tensión.
Tecl_Columna1
btfss PORTD,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 PORTD,5 ; columnas.
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna3
btfss PORTD,6
goto Tecl_GuardaValor
incf Tecl_TeclaOrden,F
Tecl_Columna4
btfss PORTD,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 PORTD,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
#include <18F452.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=4000000,RESTART_WDT)
#use fast_io(c)
#include <KBD.C>
char a;
void main()
{
port_b_pullups(TRUE);
kbd_init();
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_oscillator(False);
set_tris_c(0x00);
while(1)
{
a=kbd_getc();
if (a!=0)
{
if(a=='1')
output_c(0x01);
if(a=='2')
output_c(0x02);
if(a=='3')
output_c(0x03);
if(a=='4')
output_c(0x04);
if(a=='5')
output_c(0x05);
if(a=='6')
output_c(0x06);
if(a=='7')
output_c(0x07);
if(a=='8')
output_c(0x08);
if(a=='9')
output_c(0x09);
if(a=='*')
output_c(0x0A);
if(a=='0')
output_c(0x00);
if(a=='#')
output_c(0x0B);
}
}
}