Hola quisiera hacer las siguientes rutinas de control tanto de un teclado matricial como de una lcd en lenguaje C. Las rutinas en ensamblador son las siguientes:
;LCD_CXX.ASM
;El conjunto de rutinas que se presentan a continuaci¢n permiten realizar
;las tareas básicas de control del m¢dulo de visualizaci¢n LCD. Se emplean
;con los PIC 16cxx. En el programa principal se deber reservar memoria
;para el bloque de variables que utiliza el LCD del modo:
; LCD_VAR EQU dir_inicio_del_bloque
;BLOQUE DE ETIQUETAS
#define ENABLE bsf PORTA,2 ;Activa E
#define DISABLE bcf PORTA,2 ;Desactiva
#define LEER bsf PORTA,1 ;Pone LCD en Modo RD
#define ESCRIBIR bcf PORTA,1 ;Pone LCD en Modo WR
#define OFF_COMANDO bcf PORTA,0 ;Desactiva RS (modo comando)
#define ON_COMANDO bsf PORTA,0 ;Activa RS (modo datos)
CBLOCK LCD_VAR
LCD_TEMP_2 ;Inicio de las variables. Ser la primera direcci¢n libre
; disponible
LCD_TEMP_1
ENDC
;RUTINA UP_LCD: Con esta rutina se configura el PIC para que trabaje con el LCD.
UP_LCD bsf STATUS,RP0 ;Banco 1
clrf PORTB ;RB <0-7> salidas digitales
clrf PORTA ;RA <0-4> salidas digitales
bcf STATUS,RP0 ;Banco 0
OFF_COMANDO ;RS=0
DISABLE ;E=0
return
;RUTINA LCD_BUSY: Con esta rutina se chequea el estado del
;flag BUSY del m¢dulo LCD, que indica, cuando est activado, que el
;m¢dulo a£n no ha terminado el comando anterior. La rutina espera a
;que se complete cualquier comando anterior antes de retornar al
;programa principal, para poder enviar un nuevo comando.
LCD_BUSY LEER ;Pone el LCD en Modo RD
bsf STATUS,RP0
movlw H"FF"
movwf PORTB ;Puerta B como entrada
bcf STATUS,RP0 ;Selecciona el banco 0
ENABLE ;Activa el LCD
nop
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY
DISABLE ;Desactiva LCD
bsf STATUS,RP0
clrf PORTB ;Puerta B salida
bcf STATUS,RP0
ESCRIB ;Pone LCD en modo WR
return
;RUTINA LCD_E: Se trata de una peque¤a rutina que se encarga de generar
;un impulso de 1æ s (para una frecuencia de funcionamiento de 4 Mhz)
;por la patita de salida de la Puerta A RA2, que se halla conectada
;a la se¤al E (Enable) del m¢dulo LCD. Con esta rutina se pretende activar
;al m¢dulo LCD.
LCD_E ENABLE ;Activa E
nop
DISABLE ;Desactiva E
return
;RUTINA LCD_DATO: Es una rutina que pasa el contenido cargado en el
;registro W, el cual contiene un car cter ASCII, a la PUERTA B, para
;visualizarlo por el LCD o escribirlo en la CGRAM.
LCD_DATO OFF_COMANDO ;Desactiva RS (modo comando)
movwf PORTB ;Valor ASCII a sacar por PORTB
call LCD_BUSY ;Espera a que se libere el LCD
ON_COMANDO ;Activa RS (modo dato)
call LCD_E ;Genera pulso de E
return
;RUTINA LCD_REG: Rutina parecida a la anterior, pero el contenido de W
;ahora es el c¢digo de un comando para el LCD, que es necesario pasar
;tambi‚n a la PUERTA B para su ejecuci¢n.
LCD_REG OFF_COMANDO ;Desactiva RS (modo comando)
movwf PORTB ;C¢digo de comando
call LCD_BUSY ;LCD libre?.
call LCD_E ;S¡. Genera pulso de E.
return
;RUTINA LCD_INI: Esta rutina se encarga de realizar la secuencia de
;inicializaci¢n del m¢dulo LCD de acuerdo con los tiempos dados por
;el fabricante (15 ms). Se especifican los valores de DL, N y F,
;as¡ como la configuraci¢n de un interfaz de 8 l¡neas con el bus
;de datos del PIC, y 2 l¡neas de 16 caracteres de 5 x 7 pixels.
LCD_INI movlw b"00111000"
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
movlw b"00111000"
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
movlw b"00111000"
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
return
;RUTINA BORRA_Y_HOME: Borra el display y retorna el cursor a la posici¢n 0.
BORRA_Y_HOME movlw b"00000001" ;Borra LCD y Home.
call LCD_REG
return
;RUTINA DISPLAY_ON_CUR_OFF: Control del display y cursor.
;Activa el display y desactiva es cursor
DISPLAY_ON_CUR_OFF movlw b"00001100" ;LCD on, cursor off.
call LCD_REG
return
;RUTINA LCD_DELAY: Se trata de un rutina que implementa un retardo
;o temporizaci¢n de 5 ms. Utiliza dos variables llamadas LCD_TEMP_1
;y LCD_TEMP_2, que se van decrementando hasta alcanzar dicho tiempo.
LCD_DELAY clrwdt
movlw 10
movwf LCD_TEMP_1
clrf LCD_TEMP_2
LCD_DELAY_1 decfsz LCD_TEMP_2,F
goto LCD_DELAY_1
decfsz LCD_TEMP_1,F
goto LCD_DELAY_1
return
TECLADO.ASM
;Conjunto de rutinas para el manejo del teclado.
;No es un programa en s¡ mismo. Para utilizarlo hay que
;colocar en el programa principal:
;KEY_VAR EQU dir_inicio_del_bloque
;BLOQUE DE ETIQUETAS
CBLOCK KEY_VAR ;Inicio de las variables
TECLA ;Retorno del c¢digo de tecla
KEY_1 ;N§ de filas a explorar
KEY_2 ;Temporal de c¢digo
KEY_DELAY_1 ;Variable de temporizaci¢n
KEY_DELAY_2 ;Variable de temporizaci¢n
ENDC
;RUTINA KEY_SCAN: Rutina de exploraci¢n del teclado. La variable
;"Tecla" retorna con el c¢digo de la tecla pulsada o el c¢digo 0x80
;si no se pulsa ninguna.
KEY_SCAN bsf STATUS,RP0 ;Selecciona p gina 1
movlw b"00001111"
movwf PORTB ;RB7-RB4 salidas, RB3-RB0 entradas
bsf OPTION_REG,NOT_RBPU ;Activa cargas pull-up
bcf STATUS,RP0 ;Selecciona p gina 0
movlw 4
movwf KEY_1 ;N§ de columnas a explorar
movlw b"01111111"
movwf TECLA ;Columna a activar
KEY_SCAN_1 movf TECLA,W
movwf PORTB ;Activa fila
nop
movf PORTB,W
movwf KEY_2
subwf TECLA,W ;Lee las columnas
btfss STATUS,Z ;Hay alguna pulsada ?
goto KEY_SCAN_2 ;Si hay alguna pulsada
bsf STATUS,C ;No hay ninguna en esa fila
rrf TECLA,F ;Selecciona siguiente fila
decfsz KEY_1,F ;Salta si se han terminado las filas
goto KEY_SCAN_1
movlw 0x80
goto VOLVER ;Retorna c¢digo 0x80 (no hay pulsaci¢n)
KEY_SCAN_2 movlw .100 ;Bucle de temporizaci¢n de unos 20 ms
movwf KEY_DELAY_1 ;para evitar el rebote de los pulsadores
KEY_SCAN_3 clrf KEY_DELAY_2
clrwdt
KEY_SCAN_4 decfsz KEY_DELAY_2,F
goto KEY_SCAN_4
decfsz KEY_DELAY_1,F
goto KEY_SCAN_3
movf TECLA,W ;Tras la temporizaci¢n se lee nuevamente
movwf PORTB ;si la tecla es la misma. As¡ se
nop ;evitan los rebotes.
movf PORTB,W
subwf KEY_2,W
btfss STATUS,Z ;Es la misma ??
goto KEY_SCAN_1 ;No, seguir con la exploraci¢n
movf KEY_2,W ;S¡, guardar en variable de salida TECLA el valor
; recogido
VOLVER movwf TECLA
return ;Fin de exploraci¢n
;RUTINA KEY_HEX: Convierte el c¢digo de tecla que haya en la variable
;"Tecla" a Hex. (0-F). El resultado se devuelve en la variable "Tecla".
;Usa como rutina auxiliar Key_tabla
KEY_TABLA movf KEY_1,W
addwf PCL,F ;Calcula desplazamiento
retlw 0x7D ;0
retlw 0xEE ;1
retlw 0xED ;2
retlw 0xEB ;3
retlw 0xDE ;4
retlw 0xDD ;5
retlw 0xDB ;6
retlw 0xBE ;7
retlw 0xBD ;8
retlw 0xBB ;9
retlw 0x7E ;A
retlw 0x7B ;B
retlw 0x77 ;C
retlw 0xB7 ;D
retlw 0xD7 ;E
retlw 0xE7 ;F
KEY_HEX movf TECLA,W
movwf KEY_2 ;Almacena el c¢digo temporalmente
clrf KEY_1 ;Contador HEX a 0
KEY_HEX_2 call KEY_TABLA ;Busca c¢digo en la tabla
subwf KEY_2,W ;Compara con el de la tecla
btfsc STATUS,Z ;Coincide ?
goto KEY_HEX_1 ;S¡
incf KEY_1,F ;No, incrementa contador HEX
goto KEY_HEX_2
KEY_HEX_1 movf KEY_1,W
movwf TECLA ;Carga contador HEX en la variable de salida
return
;RUTINA HEX_7SEG: Rutina de conversi¢n de HEX (0-F) a 7 segmentos.
;El acumulador W contiene, durante la llamada, el c¢digo HEX y, al retornar,
;el correspondiente a 7 segmentos
HEX_7SEG andlw b"00001111"
addwf PCL,F ;Desplazamiento sobre la tabla
retlw b"00111111" ;0
retlw b"00000110" ;1
retlw b"01011011" ;2
retlw b"01001111" ;3
retlw b"01100110" ;4
retlw b"01101101" ;5
retlw b"01111101" ;6
retlw b"00000111" ;7
retlw b"01111111" ;8
retlw b"01100111" ;9
retlw b"01110111" ;A
retlw b"01111100" ;B
retlw b"00111001" ;C
retlw b"01011110" ;D
retlw b"01111001" ;E
retlw b"01110001" ;F
gracias por tu aportación.
mi correo:jdj_valt@hotmail.com