LIST p=16F88 ; list directive to define processor
#INCLUDE <p16f88.inc> ; processor specific variable definitions
;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file. See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _FOSC_HS
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
ERRORLEVEL -302
ERRORLEVEL -305
;------------------------------------------------------------------------------
;
; VARIABLE DEFINITIONS
;
; Available Data Memory divided into Bank 0 through Bank 3. Each Bank contains
; Special Function Registers and General Purpose Registers at the locations
; below:
;
; SFR GPR SHARED GPR's
; Bank 0 0x00-0x1F 0x20-0x6F 0x70-0x7F
; Bank 1 0x80-0x9F 0xA0-0xEF 0xF0-0xFF
; Bank 2 0x100-0x10F 0x110-0x16F 0x170-0x17F
; Bank 3 0x180-0x18F 0x190-0x1EF 0x1F0-0x1FF
;
;------------------------------------------------------------------------------
; ZONA DE DATOS
;------------------------------------------------------------------------------
CBLOCK 0x20
LCD_ApuntaCaracter
LCD_ValorCaracter
LCD_Dato
LCD_GuardaDato
LCD_GuardaTRISB
Temp1_20ms
Temp2_20ms
Temp1_5ms
Temp2_5ms
Temp1_200micros
Temp2_200micros
Temp1_2ms
Temp2_2ms
Temp1_50micros
ENDC
LCD_CaracteresPorLinea EQU .16 ;Numero de caracteres por linea de la pantalla
#DEFINE LCD_PinRW PORTA,1
#DEFINE LCD_PinRS PORTA,2
#DEFINE LCD_PinEnable PORTA,3
#DEFINE LCD_BusDatos PORTB
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG 0x0000 ;processor reset vector
PAGESEL START
GOTO START ;go to beginning of program
;Tabla para Mensajes.........................
Mensajes ;Etiqueta obligatoria
addwf PCL,F
Mensaje0 ;Posicion inicial del mensaje
DT "PRUEBA LCD",0x00 ;Mensaje terminado en 0x00
Mensaje1
DT "MIQUEL SERVERA",0x00
;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
START
;Configuramos los puertos del PIC
banksel PORTA
clrf PORTA
clrf PORTB
banksel ANSEL
movlw b'00000000'
movwf ANSEL
clrf TRISA
clrf TRISB
;Configuramos el LCD
call LCD_Inicializa
Principal
pageselw Mensaje0
movlw Mensaje0
call LCD_Mensaje
call LCD_Linea2
pageselw Mensaje1
movlw Mensaje1
call LCD_Mensaje
sleep
;********************************************************************************************
;Subrutina "LCD_Inicializa"
;********************************************************************************************
LCD_Inicializa
;bsf STATUS,RP0 ;Banco 1
bcf LCD_PinRS
bcf LCD_PinEnable
bcf LCD_PinRW
bcf STATUS,RP0 ;Banco 0
bcf LCD_PinRW ;En caso de que este conectado le indica que
;se va a escribir en el LCD
bcf LCD_PinEnable ;Impide funcionamiento del LCD poniendo E=0
bcf LCD_PinRS ;Activa el Modo Comando poniendo RS=0
call Retardo_20ms
movlw b'00110000'
call LCD_EscribeLCD ;Escribe el dato en el LCD
call Retardo_5ms
movlw b'00110000'
call LCD_EscribeLCD
call Retardo_200micros
movlw b'00110000'
call LCD_EscribeLCD
movlw b'00100000' ;Interface de 4 bits
call LCD_EscribeLCD
;Ahora configuramos el resto de parámetros
call LCD_2Lineas4Bits5x7 ;LCD de 2 lineas y caracteres de 5x7 puntos
call LCD_Borra ;Pantalla encendida y limpia. Cursor al principio
call LCD_CursorOFF ;de la linea 1. Cursor apagado
call LCD_CursorIncr ;Cursor en modo incrementar
return
;********************************************************************************************
;Subrutina "LCD_EscribeLCD"
;********************************************************************************************
LCD_EscribeLCD
andlw b'11110000' ;Se queda con el nibble alto del dato que es el
movwf LCD_Dato ;que hay que enviar y lo guarda
movf LCD_BusDatos,W ;Lee la informacion actual de la parte baja
andlw b'00001111' ;del PORTB que no se debe alterar
iorwf LCD_Dato,F ;Enviara la parte alta del dato de entrada
;y en la parte baja lo que habia antes
bsf STATUS,RP0 ;Banco 1
movf TRISB,W ;Guarda la configuracion que tenia antes TRISB
movwf LCD_GuardaTRISB
movlw b'00001111' ;Las 4 lineas inferiores del PORTB se dejan
andwf PORTB,F ;como estaban y las 4 superiores como salida
bcf STATUS,RP0 ;Banco 0
movf LCD_Dato,W ;Recupera el dato a enviar
movwf LCD_BusDatos ;Envia el dato al módulo LCD
bsf LCD_PinEnable ;Permite funcionamiento del LCD mediante un pequeño
bcf LCD_PinEnable ;pulso y termina impidiendo el funcionamiento del LCD
bsf STATUS,RP0 ;Banco 1
movf LCD_GuardaTRISB,W ;Restaura el antiguo valor en la configuracion del PORTB
movwf PORTB ;Realmente es TRISB
bcf STATUS,RP0 ;Banco 0
return
;********************************************************************************************
;Subrutinas variadas para el control del modulo LCD
;********************************************************************************************
LCD_CursorIncr ;Cursor en modo incrementar.
movlw b'00000110'
goto LCD_EnviaComando
LCD_Linea1 ;Cursor al principio de la Línea 1.
movlw b'10000000' ;Dirección 00h de la DDRAM
goto LCD_EnviaComando
LCD_Linea2 ;Cursor al principio de la Línea 2.
movlw b'11000000' ;Dirección 40h de la DDRAM
goto LCD_EnviaComando
LCD_PosicionLinea1 ;Cursor a posición de la Línea 1, a partir de la
iorlw b'10000000' ;dirección 00h de la DDRAM más el valor del
goto LCD_EnviaComando ;registro W.
LCD_PosicionLinea2 ;Cursor a posición de la Línea 2, a partir de la
iorlw b'11000000' ;dirección 40h de la DDRAM más el valor del
goto LCD_EnviaComando ;registro W.
LCD_OFF ;Pantalla apagada.
movlw b'00001000'
goto LCD_EnviaComando
LCD_CursorON ;Pantalla encendida y cursor encendido.
movlw b'00001110'
goto LCD_EnviaComando
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_2Lineas4Bits5x7 ;Define la pantalla de 2 líneas, con caracteres
movlw b'00101000' ;de 5x7 puntos y conexión al PIC mediante bus de
;goto LCD_EnviaComando ;4 bits.
;********************************************************************************************
;Subrutina "LCD_Mensaje"
;********************************************************************************************
LCD_Mensaje
movwf LCD_ApuntaCaracter
movlw Mensajes
subwf LCD_ApuntaCaracter,F
decf LCD_ApuntaCaracter,F
LCD_VisualizaOtroCaracter
movf LCD_ApuntaCaracter,W
call Mensajes
movwf LCD_ValorCaracter
movf LCD_ValorCaracter,F
btfsc STATUS,Z
goto LCD_FinMensaje
LCD_NoUltimoCaracter
call LCD_Caracter
incf LCD_ApuntaCaracter,F
;-------------------------------------------------------------------------------------
btfss STATUS,C ;Si hay acarreo al incrementar LCD_ApuntaCaracter es por
incf PCLATH ;haber cambiado de pagina por lo que hay que sumar 1 al PCLATH
;-------------------------------------------------------------------------------------
goto LCD_VisualizaOtroCaracter
LCD_FinMensaje
return
;********************************************************************************************
;Subrutinas "LCD_EnviaComando" y "LCD_Caracter"
;********************************************************************************************
LCD_EnviaComando
bcf LCD_PinRS ;Activa el "Modo Comando", poniendo RS=0
goto LCD_Envia
LCD_Caracter
bsf LCD_PinRS ;Activa el "Modo Dato", poniendo RS=1
call LCD_CodigoCGROM ;Obtiene el codigo para su correcta visualizacion
LCD_Envia
movwf LCD_GuardaDato ;Guarda el dato a enviar
call LCD_EscribeLCD ;Primero envia el nibble alto
swapf LCD_GuardaDato,W ;Ahora envia el nibble bajo, para ello pasa el
;nibble bajo del dato a enviar a parte alta del byte
call LCD_EscribeLCD ;Se envia al visualizador LCD
btfss LCD_PinRS ;Debe garantizar una correcta escritura manteniendo
call Retardo_2ms ;2ms en modo comando y 50us en modo caracter
call Retardo_50micros
return
;********************************************************************************************
;Subrutina "LCD_CodigoCGROM"
;********************************************************************************************
LCD_CodigoCGROM
movwf LCD_Dato ;Guarda el valor del caracter
goto LCD_FinCGROM
LCD_FinCGROM
movf LCD_Dato,W ;En (W) el codigo buscado
return
;********************************************************************************************
;Subrutinas de retardos para uso del LCD
;********************************************************************************************
Retardo_20ms:
movlw .110
movwf Temp1_20ms
movlw .181
movwf Temp2_20ms
nop
nop
decfsz Temp2_20ms,F
goto $-3
decfsz Temp1_20ms,F
goto $-7
goto $+1
goto $+1
nop
return
;------------------------------------------------------------
Retardo_5ms:
movlw .44
movwf Temp1_5ms
movlw .141
movwf Temp2_5ms
nop
decfsz Temp2_5ms,F
goto $-2
decfsz Temp1_5ms,F
goto $-6
goto $+1
nop
return
;------------------------------------------------------------
Retardo_200micros:
movlw .248
movwf Temp1_200micros
nop
decfsz Temp1_200micros,F
goto $-2
goto $+1
nop
return
;------------------------------------------------------------
Retardo_2ms:
movlw .8
movwf Temp1_2ms
movlw .249
movwf Temp2_2ms
nop
nop
decfsz Temp2_2ms,F
goto $-3
decfsz Temp1_2ms,F
goto $-7
goto $+1
nop
return
;------------------------------------------------------------
Retardo_50micros:
movlw .61
movwf Temp1_50micros
nop
decfsz Temp1_50micros,F
goto $-2
nop
return
END