TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: akira_ve en 10 de Marzo de 2017, 01:21:54

Título: NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 10 de Marzo de 2017, 01:21:54
Hola amigos tengo un problema, estoy usando el PIC 16F88 para un proyecto, le falta inegrar el manejo del LCD y no logro hacerlo use la libreria LCD_4BIT.INC y no funciona probe con el 16f84A y todo bien use hasta el mismo circuito pero con el 16F88 y no aparece nada.......he revisado cada linea de ejecucion y nada, agregue los temporisadores que recomiendad en caso de simulacion con Proteus y nada les muestro abajo el programa basico para probar

;************************************** LCD_01.asm **************************************
;
;   ===================================================================
;     Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;     E. Palacios, F. Remiro y L. López.
;      Editorial Ra-Ma.  www.ra-ma.es
;   ===================================================================
;
; El módulo LCD visualiza el mensaje "Hola".
;
; ZONA DE DATOS **********************************************************************
   list P=16F88
   #include p16f88.inc
   __CONFIG    _CONFIG1, _CP_ALL & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO

   __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

#DEFINE   BANCO0   BCF   STATUS,RP0
#DEFINE   BANCO1   BSF   STATUS,RP0

   CBLOCK 0x20
   ENDC

; ZONA DE CÓDIGOS ********************************************************************

   ORG   0

   BANCO1            ; select memory bank 1
   movlw   B'00000111'   ; comparators off
   movwf   CMCON
   movlw   B'000000000'; digital inputs
   movwf   ANSEL
   movlw   B'01101000'   ; 0110 for 4MHz
   movwf   OSCCON      ;
   BANCO0            ; select memory bank 0

Inicio
   call   LCD_Inicializa
   movlw   'H'
   call   LCD_Caracter
   movlw   'o'
   call   LCD_Caracter
   movlw   'l'
   call   LCD_Caracter
   movlw   'a'
   call   LCD_Caracter
   sleep            ; Entra en modo de bajo consumo.

   INCLUDE  <LCD_4BIT.INC>   ; Subrutinas de control del módulo LCD.
   INCLUDE  <RETARDOS.INC>   ; Subrutinas de retardo.
   END            ; Fin del programa.

;   ===================================================================
;     Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;     E. Palacios, F. Remiro y L. López.
;      Editorial Ra-Ma.  www.ra-ma.es
;   ===================================================================

Si se dan cuensta ese programa es mas que conocido y lo modifique para el F88

De todas manera le dare la libreria que uso

;**************************** Librería "LCD_4BIT.INC" ***********************************
;
;   ===================================================================
;     Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;     E. Palacios, F. Remiro y L. López.
;      Editorial Ra-Ma.  www.ra-ma.es
;   ===================================================================
;
; Estas subrutinas permiten realizar las tareas básicas de control de un módulo LCD de 2
; líneas por 16 caracteres, compatible con el modelo LM016L.
;
; El visualizador LCD está conectado al Puerto B del PIC mediante un bus de 4 bits. Las
; conexiones son:
;    -   Las 4 líneas superiores del módulo LCD, pines <DB7:DB4>  se conectan a las 4
;   líneas superiores del Puerto B del PIC, pines <RB7:RB4>.
;    -   Pin RS del LCD a la línea RA0 del PIC.
;    -   Pin R/W del LCD a la línea RA1 del PIC, o a masa.
;    -   Pin Enable del LCD a la línea RA2 del PIC.
;
; Se utilizan llamadas a subrutinas de retardo de tiempo localizadas en la librería RETARDOS.INC.
;
; ZONA DE DATOS *********************************************************************

   CBLOCK
   LCD_Dato
   LCD_GuardaDato
   LCD_GuardaTRISB
   LCD_Auxiliar1
   LCD_Auxiliar2
   ENDC

LCD_CaracteresPorLinea   EQU   .16   ; Número de caracteres por línea de la pantalla.

#DEFINE  LCD_PinRS   PORTA,0
#DEFINE  LCD_PinRW   PORTA,1
#DEFINE  LCD_PinEnable   PORTA,2
#DEFINE  LCD_BusDatos   PORTB

; Subrutina "LCD_Inicializa" ------------------------------------------------------------
;
; Inicialización del módulo LCD: Configura funciones del LCD, produce reset por software,
; borra memoria y enciende pantalla. El fabricante especifica que para garantizar la
; configuración inicial hay que hacerla como sigue:
;
LCD_Inicializa
   bsf   STATUS,RP0      ; Configura las líneas conectadas al pines RS,
   bcf   LCD_PinRS      ; R/W y E.
   bcf   LCD_PinEnable
   bcf   LCD_PinRW
   bcf   STATUS,RP0
   bcf   LCD_PinRW      ; En caso de que esté 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
   call    Retardo_20micros    ; Retardo necesario para simular en PROTEUS.
   movlw   b'00100000'      ; Interface de 4 bits.
   call   LCD_EscribeLCD
   call Retardo_20micros       ; Retardo necesario para simular en PROTEUS.
      
; Ahora configura el resto de los parámetros:

   call   LCD_2Lineas4Bits5x7   ; LCD de 2 líneas y caracteres de 5x7 puntos.
   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

; Subrutina "LCD_EscribeLCD" -----------------------------------------------------------
;
; Envía el dato del registro de trabajo W al bus de dato y produce un pequeño pulso en el pin
; Enable del LCD. Para no alterar el contenido de las líneas de la parte baja del Puerto B que
; no son utilizadas para el LCD (pines RB3:RB0), primero se lee estas líneas y después se
; vuelve a enviar este dato sin cambiarlo.

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 información actual de la parte baja
   andlw   b'00001111'      ; del Puerto B, que no se debe alterar.
   iorwf   LCD_Dato,F      ; Enviará la parte alta del dato de entrada
               ; y en la parte baja lo que había antes.
   bsf   STATUS,RP0      ; Acceso al Banco 1.
   movf   TRISB,W      ; Guarda la configuración que tenía antes TRISB.
   movwf   LCD_GuardaTRISB
   movlw   b'00001111'      ; Las 4 líneas inferiores del Puerto B se dejan
   andwf   PORTB,F         ; como estaban y las 4 superiores como salida.
   bcf   STATUS,RP0      ; Acceso al Banco 0.
;
   movf   LCD_Dato,W      ; Recupera el dato a enviar.
   movwf   LCD_BusDatos      ; Envía 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      ; Acceso al Banco 1. Restaura el antiguo valor en
   movf   LCD_GuardaTRISB,W   ; la configuración del Puerto B.
   movwf   PORTB         ; Realmente es TRISB.
   bcf   STATUS,RP0      ; Acceso al Banco 0.
   return

; Subrutinas variadas para el control del módulo LCD -----------------------------------------
;
;Los comandos que pueden ser ejecutados son:
;
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.

; Subrutinas "LCD_EnviaComando" y "LCD_Caracter" ------------------------------------
;
; "LCD_EnviaComando". Escribe un comando en el registro del módulo LCD. La palabra de
; comando ha sido entregada a través del registro W.  Trabaja en Modo Comando.
; "LCD_Caracter". Escribe en la memoria DDRAM del LCD el carácter ASCII introducido a
; a través del registro W. Trabaja en Modo Dato.
;
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 código para correcta visualización.
LCD_Envia
   movwf   LCD_GuardaDato      ; Guarda el dato a enviar.
   call   LCD_EscribeLCD      ; Primero envía el nibble alto.
   swapf   LCD_GuardaDato,W   ; Ahora envía el nibble bajo. Para ello pasa el
               ; nibble bajo del dato a enviar a parte alta del byte.
   call   LCD_EscribeLCD      ; Se envía al visualizador LCD.
   btfss   LCD_PinRS      ; Debe garantizar una correcta escritura manteniendo
   call   Retardo_2ms      ; 2 ms en modo comando y 50 µs en modo cáracter.
   call   Retardo_50micros
   return   

; Subrutina "LCD_CodigoCGROM" -----------------------------------------------------------
;
; A partir del carácter ASCII número 127 los códigos de los caracteres definidos en la
; tabla CGROM del LM016L no coinciden con los códigos ASCII. Así por ejemplo, el código
; ASCII de la "Ñ" en la tabla CGRAM del LM016L es EEh.
;
; Esta subrutina convierte los códigos ASCII de la "Ñ", "º" y otros, a códigos CGROM para que
; que puedan ser visualizado en el módulo LM016L.
;
; Entrada:   En (W) el código ASCII del carácter que se desea visualizar.
; Salida:   En (W) el código definido en la tabla CGROM.

LCD_CodigoCGROM
   movwf   LCD_Dato      ; Guarda el valor del carácter y comprueba si es
LCD_EnheMinuscula         ; un carácter especial.
   sublw   'ñ'          ; ¿Es la "ñ"?
   btfss   STATUS,Z
   goto   LCD_EnheMayuscula   ; No es "ñ".
   movlw   b'11101110'      ; Código CGROM de la "ñ".
   movwf   LCD_Dato
   goto   LCD_FinCGROM
LCD_EnheMayuscula
   movf   LCD_Dato,W      ; Recupera el código ASCII de entrada.
   sublw   'Ñ'          ; ¿Es la "Ñ"?
   btfss   STATUS,Z
   goto   LCD_Grado      ; No es "Ñ".
   movlw   b'11101110'      ; Código CGROM de la "ñ". (No hay símbolo para
   movwf   LCD_Dato      ; la "Ñ" mayúscula en la CGROM).
   goto   LCD_FinCGROM   
LCD_Grado
   movf   LCD_Dato,W      ; Recupera el código ASCII de entrada.
   sublw   'º'          ; ¿Es el símbolo "º"?
   btfss   STATUS,Z
   goto   LCD_FinCGROM      ; No es "º".
   movlw   b'11011111'      ; Código CGROM del símbolo "º".
   movwf   LCD_Dato
LCD_FinCGROM
   movf   LCD_Dato,W      ; En (W) el código buscado.
   return

; Subrutina "LCD_DosEspaciosBlancos" y "LCD_LineaBlanco" --------------------------------
;
; Visualiza espacios en blanco.

LCD_LineaEnBlanco
   movlw   LCD_CaracteresPorLinea
   goto   LCD_EnviaBlancos
LCD_UnEspacioBlanco
   movlw   .1
   goto   LCD_EnviaBlancos
LCD_DosEspaciosBlancos
   movlw   .2
   goto   LCD_EnviaBlancos
LCD_TresEspaciosBlancos
   movlw   .3
LCD_EnviaBlancos
   movwf   LCD_Auxiliar1      ; (LCD_Auxiliar1) se utiliza como contador.
LCD_EnviaOtroBlanco   
   movlw   ' '         ; Esto es un espacio en blanco.
   call   LCD_Caracter      ; Visualiza tanto espacios en blanco como se
   decfsz   LCD_Auxiliar1,F      ; haya cargado en (LCD_Auxiliar1).
   goto   LCD_EnviaOtroBlanco
   return

; Subrutinas "LCD_ByteCompleto" y "LCD_Byte" --------------------------------------------
;
; Subrutina "LCD_ByteCompleto", visualiza el byte que almacena el registro W en el
; lugar actual de la pantalla. Por ejemplo, si (W)=b'10101110' visualiza "AE".
;
; Subrutina "LCD_Byte" igual que la anterior, pero en caso de que el nibble alto sea cero
; visualiza en su lugar un espacio en blanco. Por ejemplo si (W)=b'10101110' visualiza "AE"
; y si (W)=b'00001110', visualiza " E" (un espacio blanco delante).
;
; Utilizan la subrutina "LCD_Nibble" que se analiza más adelante.
;
LCD_Byte
   movwf   LCD_Auxiliar2      ; Guarda el valor de entrada.
   andlw   b'11110000'      ; Analiza si el nibble alto es cero.
   btfss   STATUS,Z      ; Si es cero lo apaga.
   goto   LCD_VisualizaAlto      ; No es cero y lo visualiza.
   movlw   ' '         ; Visualiza un espacio en blanco.
   call   LCD_Caracter
   goto   LCD_VisualizaBajo

LCD_ByteCompleto
   movwf   LCD_Auxiliar2      ; Guarda el valor de entrada.
LCD_VisualizaAlto
   swapf   LCD_Auxiliar2,W      ; Pone el nibble alto en la parte baja.
   call   LCD_Nibble      ; Lo visualiza.
LCD_VisualizaBajo
   movf   LCD_Auxiliar2,W      ; Repite el proceso con el nibble bajo.
;   call   LCD_Nibble      ; Lo visualiza.
;   return

; Subrutina "LCD_Nibble" ----------------------------------------------------------------
;
; Visualiza en el lugar actual de la pantalla, el valor hexadecimal que almacena en el nibble
; bajo del registro W. El nibble alto de W no es tenido en cuenta. Ejemplos:
; - Si (W)=b'01010110', se visualizará "6".
; - Si (W)=b'10101110', se visualizará "E".
;
LCD_Nibble
   andlw   b'00001111'      ; Se queda con la parte baja.
   movwf   LCD_Auxiliar1      ; Lo guarda.
   sublw   0x09         ; Comprueba si hay que representarlo con letra.
   btfss   STATUS,C   
   goto   LCD_EnviaByteLetra
   movf   LCD_Auxiliar1,W
   addlw   '0'         ; El número se pasa a carácter ASCII sumándole
   goto    LCD_FinVisualizaDigito   ; el ASCII del cero y lo visualiza.
LCD_EnviaByteLetra
   movf   LCD_Auxiliar1,W
   addlw   'A'-0x0A         ; Sí, por tanto, se le suma el ASCII de la 'A'.
LCD_FinVisualizaDigito
   goto   LCD_Caracter      ; Y visualiza el carácter. Se hace con un "goto"
               ; para no sobrecargar la pila.
               
;   ===================================================================
;     Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;     E. Palacios, F. Remiro y L. López.
;      Editorial Ra-Ma.  www.ra-ma.es
;   ===================================================================
 Abajo les muestro el diagrama

 - Tienes que ingresar para ver archivos adjuntos -
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: Miquel_S en 10 de Marzo de 2017, 04:51:49
Hola akira_ve has tenido en cuenta la configuración de pines de entrada y salida, el 16f88 tiene pines que pueden ser analógicos o digitales y por defecto vienen configurados como analógicos.
Para tener todos los pines como digitales debes poner el registro ANSEL a 0x00.

Saludos.

Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 11 de Marzo de 2017, 03:36:25
amigo no se si leistes el codigo ASM pero eso esta hecho, al comienzo del programa asi como deshabilito el comparador y configuro los 4 Mhz internos del PIC
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: KILLERJC en 11 de Marzo de 2017, 17:23:42
No veo nada malo en la configuracion.

Fuses:
- Oscilador : Correcto
- Debug: dehsabilitado para que se pueda usar RB6 y RB7
- WDT: Off
- MCLR: Off

Programa:
- Puertos: Correctos
- Oscilador: Correcto, es inmediato
- Le falta un loop infinito, por mas que posea el sleep le falta.. Luego del sleep un NOP y luego pones el salto.

Libreria:
No la mire, asumo que funciona.

Simulador:
- Puede que este definido otra frecuencia, ya que el simulador no le hace caso a la configuracion de los fuses. Es decir deberias configurarlo de forma correcta en el programa por lo anterior.

Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 11 de Marzo de 2017, 21:37:22
El programa funciona tal cual.............con el F84, claro cambio lo del CBLOCK y quito los Config......funciona de maravilla..................lo corro liena a linea.......y antes de llegar al SLEEP se ve el mensaje HOLA en el F88 nunca se ve
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 11 de Marzo de 2017, 21:39:09
Uso la misma Frecuencia en ambos............pero revisare bien...............gracias amigo
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 12 de Marzo de 2017, 14:16:09
Revise la configuracion del oscilardor y lo corregi y la cambie por 01100110 o 102 y nada pero lo simule en PIC Simulator Ide y funciona................esto me confunde mas
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: KILLERJC en 12 de Marzo de 2017, 15:29:18
Revise la configuracion del oscilardor y lo corregi y la cambie por 01100110 o 102 y nada pero lo simule en PIC Simulator Ide y funciona................esto me confunde mas

Ahi tenes tu problema. Es un simulador y puede tener errores
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 12 de Marzo de 2017, 23:12:52
Si amigo he modificado el programa y con el PIC SIMULATOR IDE funciona bien.............se supone que deberia ser al revez pues proteus es un programa mas avanzado.............o mas completo que el otro jajajaja
Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 19 de Marzo de 2017, 02:28:15
Amigo KILLERJC, descargue el Hex en el pic...........y no funciono, revise la libreria y y no funcionaba bien en la inicializacion del LCD,,,,,,,,,,,,lei teoria del LCD, busque programas para analizar iniciaban el LCD y me gusto uno que me parecio simple, y lo adapte a la libreria,,,,y me parece bien ahora, pues puedo usar todo el PUERTO B para controlar el LCD en su totalidad a 4 BIT, a cintinuacion les dejoe
 mi aporte, pues pueden cambiarlo a cualquier otro puerto...........si encuentrar algun error avisenme



; ************************************ LCD_4BITX.INC *******************************************
; Programa: Manejo de LCD 16X2 con inerfaz de 4 Bits
; Utiliza unicamente el Puerto B pero usarse en cualquiera
; BUS ( RB4 - RB7 ) Pin RS ( RB3 ) Pin E ( RB2 ) el Pin R / W se coecta al Negativo
; *******************************************************************************

   CBLOCK
   LCD_GuardaDato
   LCD_Dato
   LCD_CaracteresPorLinea
   LCD_Auxiliar1
   LCD_Auxiliar2
   ENDC

#DEFINE   Pin_RS   PORTB,2         ; Definicion del Pin RS
#DEFINE   Pin_E   PORTB,3         ; Definicion del Pin E


; *******************************************************************************
; Inicialización del LCD ****
; *******************************************************************************

LCD_Inicializa:

   bsf   STATUS,RP0   ; Seleccionar el Banco 1
   movlw   B'00000011'    ; Puerto B como salidas (Control, ( RS, RB3 )- ( E, RB2 ) )-( Datos, RB4-RB7 )
   movwf   TRISB
   movlw   B'00000111'   ; Comparadores apagados
   BCF   STATUS,RP0   ; Regresar al Banco 0
   clrf   PORTB

   movlw   B'00000010'   ; Habilitar el LCD
   call    LCD_Escribe_Co   ; Envíar los datos al LCD por el puerto B
   movlw   B'00101000'    ; Activar Función
   call    LCD_Escribe_Co
   movlw   B'00000110'    ; Seleccionar Modo
   call    LCD_Escribe_Co
   movlw   B'00001100'    ; Encender o apagar la pantalla
   call    LCD_Escribe_Co
   movlw   B'00000001'    ; Borrar la pantalla
   call    LCD_Escribe_Co
   return

; *******************************************************************************
; Ésta subrutina manda una instrucción o dato al LCD
; *******************************************************************************

LCD_Escribe_Co:
   bcf      Pin_RS         ; RS = 0 Si es una instrucción para el LCD
   goto   Continua

LCD_Escribe_Da:
   bsf      Pin_RS         ; RS = 1 Si es un dato para el LCD

; *******************************************************************************   
; Ésto es para no modificar el contenido de los 4 bit menos significativos del puerto B
; *******************************************************************************

Continua:
   movwf   LCD_GuardaDato
   movlw   0x0F
   andwf   PORTB,f         ; AND entre 15 y el puerto B
   movf   LCD_GuardaDato,w   
   andlw   0xF0         ; AND entre literal 240 y w en el cual esta el valor de Aux y guarda el resultado en w
   iorwf   PORTB,f         ; OR entre w  y el puerto B
   bsf      Pin_E         ; E = 1 Habilitar el LCD
   call   Retardo_2ms   
   bcf      Pin_E         ; E = 0 Deshabilitar el LCD
   call   Retardo_2ms
   movlw   0x0F
   andwf   PORTB,f         ; AND entre 15 el puerto B
   swapf   LCD_GuardaDato,w   ; Intercambia los nibles de Aux y los guarda en w
   andlw   0xF0         ; AND entre 240 y W, en el cual está el valor de Aux con los nibles intercambiados
   iorwf   PORTB,f         ; OR entre w  y el puerto B
   bsf      Pin_E         ; E = 1 Habilitar el LCD
   call   Retardo_2ms
   bcf      Pin_E         ; E = 0 Deshabilitar el LCD
   call   Retardo_2ms
   return

; *******************************************************************************
; Subrutinas para manejar el LCD, Como posicion y Uso De Cursor
; *******************************************************************************

LCD_CursorIncr:            ; Cursor en modo incrementar.
   movlw   b'00000110'
   goto   LCD_Escribe_Da

LCD_Linea1:               ; Cursor al principio de la Línea 1.
   movlw   b'10000000'      ; Dirección 00h de la DDRAM
   goto   LCD_Escribe_Da

LCD_Linea2:               ; Cursor al principio de la Línea 2.
   movlw   b'11000000'      ; Dirección 40h de la DDRAM
   goto   LCD_Escribe_Da

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_Escribe_Co   ; 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_Escribe_Co   ; registro W.

LCD_OFF:               ; Pantalla apagada.
   movlw   b'00001000'
   goto   LCD_Escribe_Da

LCD_CursorON:            ; Pantalla encendida y cursor encendido.
   movlw   b'00001110'
   goto   LCD_Escribe_Da
LCD_CursorOFF            ; Pantalla encendida y cursor apagado.
   movlw   b'00001100'
   goto   LCD_Escribe_Da

LCD_Borra:               ; Borra toda la pantalla, memoria DDRAM y pone el
   movlw   b'00000001'      ; cursor a principio de la línea 1.
   goto   LCD_Escribe_Da

; *******************************************************************************   
; Rutinas para manejos Especiales, La GROM, Minusculas, Mayusculas y Simbolo de Grados Centigrado
; *******************************************************************************

LCD_CodigoCGROM:
   movwf   LCD_Dato      ; Guarda el valor del carácter y comprueba si es

LCD_EnheMinuscula:         ; un carácter especial.
   sublw   'ñ'          ; ¿Es la "ñ"?
   btfss   STATUS,Z
   goto   LCD_EnheMayuscula   ; No es "ñ".
   movlw   b'11101110'      ; Código CGROM de la "ñ".
   movwf   LCD_Dato
   goto   LCD_FinCGROM

LCD_EnheMayuscula:
   movf   LCD_Dato,W      ; Recupera el código ASCII de entrada.
   sublw   'Ñ'          ; ¿Es la "Ñ"?
   btfss   STATUS,Z
   goto   LCD_Grado      ; No es "Ñ".
   movlw   b'11101110'      ; Código CGROM de la "ñ". (No hay símbolo para
   movwf   LCD_Dato      ; la "Ñ" mayúscula en la CGROM).
   goto   LCD_FinCGROM
   
LCD_Grado:
   movf   LCD_Dato,W      ; Recupera el código ASCII de entrada.
   sublw   'º'          ; ¿Es el símbolo "º"?
   btfss   STATUS,Z
   goto   LCD_FinCGROM   ; No es "º".
   movlw   b'11011111'      ; Código CGROM del símbolo "º".
   movwf   LCD_Dato

LCD_FinCGROM:
   movf   LCD_Dato,W      ; En (W) el código buscado.
   return

; *******************************************************************************   
; Rutinas para Manejo de Espacios y Lineas en en Blanco
; *******************************************************************************

LCD_LineaEnBlanco:
   movlw   LCD_CaracteresPorLinea
   goto   LCD_EnviaBlancos

LCD_UnEspacioBlanco:
   movlw   .1
   goto   LCD_EnviaBlancos

LCD_DosEspaciosBlancos:
   movlw   .2
   goto   LCD_EnviaBlancos

LCD_TresEspaciosBlancos:
   movlw   .3

LCD_EnviaBlancos:
   movwf   LCD_Auxiliar1      ; (LCD_Auxiliar1) se utiliza como contador.

LCD_EnviaOtroBlanco:   
   movlw   ' '               ; Esto es un espacio en blanco.
   call   LCD_Escribe_Da      ; Visualiza tanto espacios en blanco como se
   decfsz   LCD_Auxiliar1,F      ; haya cargado en (LCD_Auxiliar1).
   goto   LCD_EnviaOtroBlanco
   return

; *******************************************************************************   
; Rutinas Pa operaciones de Majeos de Vizualiacion de BYTE en la LCD
; *******************************************************************************

LCD_Byte:
   movwf   LCD_Auxiliar2      ; Guarda el valor de entrada.
   andlw   b'11110000'         ; Analiza si el nibble alto es cero.
   btfss   STATUS,Z         ; Si es cero lo apaga.
   goto   LCD_VisualizaAlto   ; No es cero y lo visualiza.
   movlw   ' '               ; Visualiza un espacio en blanco.
   call   LCD_Escribe_Da
   goto   LCD_VisualizaBajo

LCD_ByteCompleto:
   movwf   LCD_Auxiliar2      ; Guarda el valor de entrada.

LCD_VisualizaAlto:
   swapf   LCD_Auxiliar2,W      ; Pone el nibble alto en la parte baja.
   call   LCD_Nibble         ; Lo visualiza.

LCD_VisualizaBajo:
   movf   LCD_Auxiliar2,W      ; Repite el proceso con el nibble bajo.
;   call   LCD_Nibble         ; Lo visualiza.
;   return

; *******************************************************************************   
; Rutinas para manejo y Viuualizacion de NIBBLE Bajo del BYTE sin importar el Alto
; *******************************************************************************

LCD_Nibble:
   andlw   b'00001111'         ; Se queda con la parte baja.
   movwf   LCD_Auxiliar1      ; Lo guarda.
   sublw   0x09            ; Comprueba si hay que representarlo con letra.
   btfss   STATUS,C   
   goto   LCD_EnviaByteLetra
   movf   LCD_Auxiliar1,W
   addlw   '0'               ; El número se pasa a carácter ASCII sumándole
   goto    LCD_FinVisualizaDigito   ; el ASCII del cero y lo visualiza.

LCD_EnviaByteLetra:
   movf   LCD_Auxiliar1,W
   addlw   'A'-0x0A         ; Sí, por tanto, se le suma el ASCII de la 'A'.

LCD_FinVisualizaDigito:
   goto   LCD_Escribe_Da      ; Y visualiza el carácter. Se hace con un "goto"
                        ; para no sobrecargar la pila.
; *******************************************************************************   
; Fin de Libreria de Manejo de LCD 16X2 podria modificarse
; *******************************************************************************

Título: Re:NO funciona el LCD en ASM con el PIC 16F88
Publicado por: akira_ve en 19 de Marzo de 2017, 02:30:26
aqui les dejo el archivo...............lo usan igual que la libreria original, yo le puse LCD_4BITX.INC