# Problema Manejo LCD 2x16 con PIC 16F877A



## fractura (Abr 26, 2009)

Hola estoy aprendiendo a programar el micro y he tenido muchos problemas para poner a funcionar la pantalla LCD. Hasta ahora solo intento que prenda pero no logro inicializarla.
Mi meta es que el lcd encienda con 2 lineas, matriz 5x7, desplazamiento hacia la derecha, cursor on, y blinking on.
Pero cada vez que lo simulo no logro que encienda aunque sea el cursor.

Adjunto dejo el esquematico del circuito y el ASM, a ver quien puede ayudarme y decirme que es lo que estoy haciendo mal.

Gracias de antemano.


----------



## El nombre (Abr 26, 2009)

en algunas versiones de proteus pasa.
Una solución: Coloca una temporización cuando espera el micro la recepcion de que está listo el LCD. Es decir, cuando chequea el estado de RB7. Prueba con 10ms antes de que empiece el bucle de chequeo de estado de esa entrada.
Saludos


----------



## fractura (Abr 26, 2009)

Bueno la verdad es que en rb7 no tengo conectado nada. El bototn esta en rb0, pero el problema no es ese, sino que no logor hacer que inicialize la pantalla.

Los 10mS es para el antirebote, pero aun no estoy chequeando el boton


----------



## JPTZ (May 29, 2010)

Buenas, quería preguntarles acerca del manejo del LCD ITM-1602 (supuestamente compatible con el controlador HD44780). Estoy utilizando el 16F877A y la librería LCD.C del CCS... pero no me está funcionando, aquí les dejo el programita (muy básico) para mostrar algun mensaje... si alguno me puede decir donde está mi error les agradeceríaa



```
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(clock=20000000)

#include <LCD.C>


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();

   while (1){ 
      lcd_putc("\fMENSAJE\n");
      delay_ms(1000);
   }
}
```


----------



## avpc79 (Nov 8, 2010)

Hola JPTZ:

Aunque este post sea un año despues.... lograste resolver el problema? Me esta pasando lo mismo. Revise las conexiones, aparentan estar bien y nada. Abriendo la libreria LCD.C "descomento" la linea que indica al compilador que se usara el Puerto B y la pantalla mas que muerta, ni un destello, nada.

Saludos.

Alejandro


----------



## JPTZ (Nov 8, 2010)

Hola avpc79:

Mira lo resolvi, recuerdo q habian algunas cositas como por ej. q estaba usando un cristal de 20M cuando en realidad ese PIC (16F877A) no funciona con ese cristal (el 16F877 si)... asi q le puse uno de 4M...
Te recomiendo también simularlo en Proteus. Si no es lo que te digo avisame y le seguimos buscando la vuelta. Saludos.


----------



## ByAxel (Nov 8, 2010)

JPTZ dijo:


> Hola avpc79:
> 
> Mira lo resolvi, recuerdo q habian algunas cositas como por ej. q estaba usando un cristal de 20M cuando en realidad ese PIC (16F877A) no funciona con ese cristal (el 16F877 si)... asi q le puse uno de 4M...
> Te recomiendo también simularlo en Proteus. Si no es lo que te digo avisame y le seguimos buscando la vuelta. Saludos.


Solo como dato: 
- Los PIC cuyo nombre terminan en "A" son versiones mejoradas.
- En los PIC16... el nombre impreso en el cuerpo del chip indican la frecuencia máxima de trabajo, por ejemplo:
"PIC16F877A - 4" = frecuencia de trabajo hasta 4Mhz.
"PIC16F877A - 20" = frecuencia de trabajo hasta 20Mhz.

saludos


----------



## avpc79 (Nov 11, 2010)

Uhmm, bueno yo estoy usando un cristal de 4MHz, igual revisare el nombre completo del PIC para verificar el dato del amigo ByAxel.

De verdad estoy optando por pensar que este dañada la pantalla, tendre que comprar otra para ver. Y por ultimo queria preguntarles: tan solo conectando la alimentacion de la pantalla, nada mas, deberia ver algo? que se ponga un pelo mas oscura la primera linea o algun pequeño indicio de que esta viva la lcd??

Gracias.-


----------



## ByAxel (Nov 11, 2010)

avpc79 dijo:


> Y por ultimo queria preguntarles: tan solo conectando la alimentacion de la pantalla, nada mas, deberia ver algo? que se ponga un pelo mas oscura la primera linea o algun pequeño indicio de que esta viva la lcd??



Se nota que vive si aparece la primera línea; si a la pata 3 del LCD le has puesto un potenciómetro lo debes regular ya que eso controla el contraste en el LCD, tal vez por eso no se vea nada.
saludos.


----------



## avpc79 (Nov 11, 2010)

Ok, Gracias, entonces si debe estar dañada por que al alimentarle no pasa absolutamente nada, ni regulando la tension en la pata 3...

Ahora ando peleando con los pic pq se me reinician de forma aleatoria durante su trabajo. Existen metodos estandarizados para proteger al micro de los glitch? Porque lo que he leido por otros foros y paginas web son como recetas de brujeria jejeje.

Saludos.-


----------



## ByAxel (Nov 11, 2010)

En el software se debe procurar configurar bien los fuses y que la lógica del programa esté bien echa (si se sabe que en algún proceso se va a quedar parado para eso existe el watchdog jeje).
En hardware como dices (recetas de brujería), se acostumbra filtrar lo mejor posible la alimentación y no lo sometas al pobre a trabajar en un ambiente ruidoso (mucha estática y otras cosas). -El PIC no es industrial, hablando de los 16F o 18F-.

Con respecto al LCD me olvide decirte que si tiene luz, que lo alimentes (pines 15 y 16).

saludos


----------



## Rodo2012 (Nov 11, 2010)

Disculpen que me salga un poco del tema... Pero referente a la configuración del PIC16F877A tengo un problema:

Estoy haciendo un contador de 15 bits con los puertos C y D (de 0 hasta 32767), la simulación en Proteus me funciona muy bien, pero en la realidad el chip se resetea mas o menos cuando está contando hasta 700 (siempre). El cristal estoy usando de 20 MHz. 

Cuál podría ser el problema?

Yo lo configuré así:           __CONFIG  _BODEN_OFF&_CP_OFF&_WRT_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC&_DEBUG_OFF&_CPD_OFF&_LVP_OFF  

1. Brown out reset.....................  Desactivado
2. Protección de código............... Desactivado
3. Protección de memoria flash...... Desactivado
4. Power up timer....................... Activado
5. Watch dog timer..................... Desactivado
6. Oscilador High speed
7. Depurador en circuito.............. Desactivado
8. Protección de EEPROM interna... Desactivado
9. LVP...................................... Desactivado


----------



## ByAxel (Nov 11, 2010)

Rodo2012 dijo:


> Cuál podría ser el problema?
> 
> Yo lo configuré así:           __CONFIG  _BODEN_OFF&_CP_OFF&_WRT_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC&_DEBUG_OFF&_CPD_OFF&_LVP_OFF
> 
> ...


Está bien, veo que usas assembler... dices que funciona bien en el proteus entonces se debe al hardware; verifica si hay falsos contactos (cristal, condensadores, resistencia del MCLR, alimentación) o ruidos (como dije antes -el PIC no es industrial-)... ha y como es el circuito? usas LEDs, displays.
Al principio manejar variables de más de 8 bits en asm puede ser confuso, puede que algo en la lógica del programa esté mal.
PD: Pregunta en el tema de asm: ASM desde 0 (ASM desde cero).


----------



## Rodo2012 (Nov 12, 2010)

Hola ByAxel,

Adjunto archivo del circuito que estoy utilizando.
No puse los condensadores en el cristal ya que está armado en protoboard y en un proto nunca necesité poner los condensadores, pero haré la prueba poniédolos.

Estos son las posibles fallas que descarté:

1. Chip en mal estado  (cambié de chip y el problema es idéntico)
2. Protoboard en mal estado (cambié de posición el circuito y sigue el problema)
3. Máxima velocidad de trabajo 20MHz (cambié por un cristal de 12MHz, sigue el mismo problema)

Revisé la lógica del programa y me parece que está bien... Qué podrá ser?
gracias y saludos.


----------



## ByAxel (Nov 15, 2010)

Que tal, estuve de viaje...
Sobre el problema PIC16F877A, pues los condensadores no debes... "Tienes que poner los condensadores", el PIC no es algo análogo que tiene cosas raras sin saber, todo está probado y tiene un motivo, es por eso que debes de poner el mínimo hardware que sugiere microchip (la empresa)... y si te funcionaba sin condensadores pues tienes problemas de capacitancias parásitas en tu mesa de trabajo.
saludos


----------



## Rodo2012 (Nov 15, 2010)

Ok! Gracias ByAxel, ya solucioné el problema.

Había un detalle que no percibí en el pograma, los capacitores también los incluí.
Espero también que avpc79 haya logrado solucionar su problema con su LCD; yo lamentablemente no trabajé con LCDs, entonces no puedo recomendarle nada...
Saludos.


----------



## avpc79 (Nov 16, 2010)

Hola, pues nada con la LCD.... Mañana con paciencia verificare si los espadines estan haciendo buen contacto en la protoboard y con otra libreria que vi por ahi que se llama "flex_lcd.c", segun, hay gente que no pudo con la que trae CCS y con esa flex_lcd han logrado la meta... Cuestion que me molestaria ya que me tome la molestia de estudiar cada linea de la libreria para LCD de CCS y no hay nada del otro mundo salvo que hay que estar pendiente si vas a usar el puerto B o el D (o el que quieras, siempre y cuando sea un puerto de 8 bits.


Me gustaria mostrarles como hice para temporizar 1 segundo "exacto" empleando el TIMER0, no se si lo puedo poner en esta discusion o tendria que ser en otra parte, por favor diganme y les copio el codigo.

Saludos y Gracias!


----------



## ByAxel (Nov 16, 2010)

avpc79 dijo:


> Me gustaria mostrarles como hice para temporizar 1 segundo "exacto" empleando el TIMER0, no se si lo puedo poner en esta discusion o tendria que ser en otra parte, por favor diganme y les copio el codigo.


No hay problema, ponlo en un archivo adjunto para el que lo desee ver .


----------



## avpc79 (Nov 16, 2010)

Hola, adjunto esta el codigo de como temporice un segundo "exacto". Coloco exacto entre comillas ya que si tomamos en cuenta el tiempo que demora en ejecutar cada instruccion ya existe un retraso implicito pero si no necesitas una precision suiza funciona perfecto esto. Me gustaria comprobar de alguna manera exacta la frecuencia de ese segundo.

Por si les da lata leer el codigo lo explico aqui rapidito:

1) Inicio el timer con un valor de 6 y preescalador igual a 256, eso me da 64ms por cada interrupcion.

2) cuento 15 interrupciones, ahi van 960ms y ahora cambio el preescalador a 128, le coloco valor de 6 otra vez , asi en una interrupcion añado 32ms, sumando al tiempo anterior irian 992

3) coloco valor de 6 again, preescalador en 256 y asi en una interrupcion mas tengo los 8ms que faltan para completar los 1000ms.


Saludos.-


----------



## avpc79 (Nov 16, 2010)

Hola, ya logre ver texto en la pantalla LCD, hasta me da pena decirles que estaba haciendo mal... Siempre fue un problema de hardware, el contraste. Yo conectaba el pin #3 de la lcd al potenciometro y el potenciometro a VDD.... tenia que ser a VSS... pues ahi mi logica se tiró tres..

Ahora pregunto yo: No es lo mismo (o muy parecido) conectar el pin de contraste a Vss que conectarlo a VDD con una resistencia de un mega ohm??? O sera que a pesar de que la corriente es poequeña con esa resistencia el sentido de la corriente es lo que no me ayudaba....

En fin, muchas gracias a todos, ByAxel gracias tambien, a la orden aqui en Venezuela.

A ver que dicen del Timer de 1000 ms.

Saludos.-


----------



## aroman213 (Dic 9, 2010)

hola yo tengo problemas con el lcd, al compilar me salen estos errores


Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\Documents and Settings\Ariel\Escritorio\tem-1\tem1.mcs".
Clean: Done.
Executing: "C:\Archivos de programa\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F877A "Est met.asm" /l"Est met.lst" /e"Est met.err" /d__DEBUG=1
Error[115]   C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\RUTINALCD.INC 96 : Duplicate label ("RD" or redefining symbol that cannot be redefined)
Message[302] C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\RUTINALCD.INC 101 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Warning[202] C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\RUTINALCD.INC 102 : Argument out of range.  Least significant bits used.
Message[302] C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\RUTINALCD.INC 103 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[305] C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\MUL16X8BIT.INC 53 : Using default destination of 1 (file).
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 252 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 254 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 307 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 313 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 328 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 338 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 340 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 357 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 486 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 497 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 500 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 508 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 523 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 526 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 541 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 543 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 545 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 558 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 562 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 575 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 578 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 587 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 618 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 621 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 624 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 641 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 646 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 663 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 667 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 677 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Halting build on first failure as requested.
----------------------------------------------------------------------
Debug build of project `C:\Documents and Settings\Ariel\Escritorio\tem-1\tem1.mcp' failed.
Preprocessor symbol `__DEBUG' is defined.
Thu Dec 09 12:18:48 2010
----------------------------------------------------------------------
BUILD FAILED




la rutina del lcd es esta, nos e donde estew el errror, me podrian ayudar....


para un LCD de 16x2 para LCD Hitachi HD44780
;Esta rutina es para el 16F87x.
;Comunicación 8 Bit, RS, RW y E.
;
;Configuración del hardware:
;RB0 a DB0; RB1 a DB1;... RB7 a DB7
;RD0 a RS; RD1 a R/W; RD2 a E
;
;*************
;SE NECESITA:
;*************
;
;* Rutina de temporización de 5ms llamada DELAY_5MS. Lo debe definir el usuario para no modificar constantemente la rutina
;                                                    así se puede usar con 8Mhz, 4Mhz, etc.
;* RAM: cursor (ver MOV_DESP)
;*      curdisp (ver CUR_DISP)
;*      poeslcd (ver PO_ES_LCD)
;
;***************
;LO QUE CONSUME
;***************
;- 3 pociciones de la RAM
;- 2 pociciones de la pila más uno desde el programa principal, Total 3 Stack.
;
;*********
;RUTINAS:
;*********
;
;LCD_PORT, para configurar los puerto de comunicación con el LCD. Ver encabezado de la rutina.
;
;LCD_INI, inicializa el LCD para bus de 8 bits, las 2 líneas de LCD y resolución 5x7. Se ejecuta automáticamente, pero se dispone de ella
;         por si el usuario lo necesita.
;
;B_DISPLAY, Borra el display y la memoria del LCD.
;
;MOV_DESP, configura al cursor, tanto el movimiento y desplazamiento. B'000001MS': M 1 Incremento 0 decremento del cursor.
;          S 1 Desplaza la visualización (útil para cuando se exede los 16 caracteres por línea) 0 modo normal.
;          antes de llamar a esta rutina, cargar en la pocición CURSOR la configuración deseada. Predeterminado B'00000110'
;
;CUR_DISP, Se configura si se prende o apaga al cursor y al display, y si el cursor parpadea o no.
;          B'00001DCB' D 1 Display encendido 0 Display apagado. C 1 cursor encendido 0 cursor apagado. B 1 Cursor parpadea 0 cursor no parpadea.
;          antes de llamar a esta rutina, cargar en la pocición CURDISP la configuración deseada. Predeterminado B'00001100'
;
;PO_ES_LCD, Pocición para escribir en LCD. La primer Línea comienza desde H'80' hasta H'8F'
;           y la segunda línea desde H'C0' hasta H'CF' Útil para subir o bajar el cursor y elegir desde dónde se empieza a escribir.
;           antes de llamar a esta rutina, carga en la pocición POESLCD la configuración deseada. Predeterminado B'10000000' (H'80') y B'11000000' (H'C0')
;
;LCD_DATO, Envía los datos a mostrar en la pantalla del LCD.
;
;PRE_LCD, configura al LCD en forma predeterminada con los valores B'00000110' B'00001100' B'10000000'; También borra el Display. Al utilizar esta rutina
;         se ahorran muchos pasos.
;
;***********************************************************
;MODO DE USO
;***********************************************************
;
;Alternativa 1
;*************
;Primero: ejecutar la rutina LCD_PORT
;Segundo: solo si se necesita, ejecutar la rutina B_DISPLAY es recomendable. (ver en rutinas)
;Tercero: cargar en la variable CURSOR la configuración deseada (ver en RUTINAS) y luego ejecutar la rutina MOV_DESP
;Cuarto: cargar en la variable CURDISP la configuración deseada (ver en RUTINAS) y luego ejecutar la rutina CUR_DIP
;Quinto: cargar en la variable POESLCD la configuración deseada (ver en RUTINAS) y luego ejecutar la rutina PO_ES_LCD
;Sexto: el LCD ya está configurado. Se debe cargar en el registro W el código ASCII a mostrar en el LCD y luego ejecutar la rutina LCD_DATO.
;Séptimo: Cuando se cargaron las 16 pociciones de memoria y/o se quiere bajar o subir de línea repetir el quinto paso y luego el sexto.
;
;Alternativa 2.
;**************
;Primero: ejecutar PRE_LCD
;segundo: el LCD ya está configurado. Se debe cargar en el registro W el código ASCII a mostrar en el LCD y luego ejecutar la rutina LCD_DATO.
;tercero: Cuando se cargaron las 16 pociciones de memoria y/o se quiere bajar o subir de línea repetir el quinto paso y luego el sexto 
;         de la alternativa 1.
;
;***********************************************************
;NOTA:
;***********************************************************
;
;Importante: Todas las rutinas se deben ejecutar con la instrucción CALL y las variables se deben escribir en minúscula como está en
;            el apartado senecesita.
;            También es recomendable desactivar las interrupciones antes de ejecutar cualquier rutina.
;
;Esta rutina se puede utilizar tranquilamente en un PIC 16F84, para ello, se deben anular las líneas MOVLW  H'06' y MOVWF ADCON1
;BCF  STATUS,RP1 que se encuentra en la rutina LCD_PORT
;
;*****************************************************************************
;Configura los puertos A y B para la comunicación con el LCD
;Pone al PORTB como salida y a los BITs 0, 1, 2, 5 del puerto A como salidas y
;a los BITs 3 y 4 como entradas.
;*****************************************************************************
;
;*****************************************************************************
;RENOMBRAMOS PUERTOS
;*****************************************************************************
;
RB		EQU	H'06'
RD		EQU	H'08'
;
;
LCD_PORT  	BSF	STATUS,RP0	;Cambio de banco a 1
		BCF	STATUS,RP1	;Idem anterior.
                CLRF    TRISB           ;RB se programa como salida
                MOVLW   d'00011000'     ;RA<4:3> se programan como entradas
                MOVWF   TRISD           ;RA<2:0> se programan como salidas
		MOVLW	H'06'		;Cargo el valor 6 al W y lo paso
		MOVWF	ADCON0		;al registro para hacer a porta salidas digitales.
                BCF     STATUS,RP0      ;Selecciona el banco 0 de datos
                BCF     RD,0            ;Desactiva RS del modulo LCD
                BCF     RD,2            ;Desactiva E del modulo LCD
;
LCD_INI		MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                RETURN
;
LCD_REG         BCF     RD,0            ;Desactiva RS (Modo instruccion)
                MOVWF   RB              ;Saca el codigo de instruccion
                CALL    LCD_BUSY        ;Espera a que se libere el LCD
LCD_E           BSF     RD,2            ;Activa señal E
                NOP                     ;Espera 1uS
                BCF     RD,2            ;Desactiva señal E
                RETURN
;
LCD_BUSY        BSF     RD,1            ;Pone el LCD en modo lectura
                BSF     STATUS,5        ;Selecciona el Banco 1
                MOVLW   0xFF  
                MOVWF   PORTB           ;Puerta B act£a de entrada
                BCF     STATUS,5        ;Selecciona el Banco 0
                BSF     RD,2            ;Activa el LCD (Señal E)
                NOP           
L_BUSY          BTFSC   RB,7            ;Chequea el bit BUSY
                GOTO    L_BUSY          ;Est  a "1" (Ocupado)
                BCF     RD,2            ;Desactiva el LCD (Se¤al E)
                BSF     STATUS,5        ;Selecciona el Banco 1
                CLRF    PORTB           ;Puerta B actua como salida
                BCF     STATUS,5        ;Selecciona el Banco 0
                BCF     RD,1            ;Pone el LCD en modo escritura
                RETURN
;
B_DISPLAY	MOVLW	B'00000001'
		CALL	LCD_REG
		RETURN
;
MOV_DESP	MOVFW	cursor
		CALL	LCD_REG
		RETURN
;
CUR_DISP	MOVFW	curdisp
		CALL	LCD_REG
		RETURN
;
PO_ES_LCD	MOVFW	poeslcd
		CALL	LCD_REG
		RETURN
;
LCD_DATO        BCF     RD,0            ;Desactiva RS (Modo instrucci¢n)
                MOVWF   RB              ;Valor ASCII a sacar por RB
                CALL    LCD_BUSY        ;Espera a que se libere el LCD
                BSF     RD,0            ;Activa RS (Modo dato)  
                GOTO    LCD_E           ;Genera pulso en señal E
;
PRE_LCD		CALL	LCD_PORT
		CALL	B_DISPLAY
		MOVLW	B'00000110'
		MOVWF	cursor
		CALL	MOV_DESP
		MOVLW	B'00001100'
		MOVWF	curdisp
		CALL	CUR_DISP
		MOVLW	B'10000000'
		MOVWF	poeslcd
		CALL	PO_ES_LCD
		RETURN
;
;****************
;NOTA AL MARGEN:
;****************
;Si se tiene limitada la memoria de programa, se puede eliminar la rutina PRE_LCD
;También se puede eliminar las variables y trabajar directamente desde W
;para ello, se debe eliminar la primer línea (no la etiqueta) de las rutinas
;MOV_DESP, CUR_DISP, PO_ES_LCD y antes de ejecutar estas rutinas, se debe cargar en W
;la configuración deseada. Recuerden que, si se hace esta modificación, la rutina PRE_LCD, no funcionará.
;La razón de utilizar las variables, es para que el usuario pueda guardar la configuración
;al principio del programa, hacer otras tareas y luego inicializar el LCD.


gracias


----------



## ByAxel (Dic 9, 2010)

Reemplaza "RD" por otro nombre en la rutina del LCD ya que en el archivo de cabecera del PIC hay un bit con el mismo nombre, por eso dice _Error[115] C:\ARCHIVOS DE PROGRAMA\MICROCHIP\MPASM SUITE\RUTINALCD.INC 96 : Duplicate label (*"RD"* or redefining symbol that cannot be redefined)_.
El resto son solo avisos.


----------



## aroman213 (Dic 9, 2010)

ya lo reemplace, pero los errores estos 

Message[302] C:\DOCUMENTS AND SETTINGS\ARIEL\ESCRITORIO\TEM-1\EST MET.ASM 252 : Register in operand not in bank 0.  Ensure that bank bits are correct.


no afectaran, ya que al armar el circuito, solo me aparecen cuandos negros en el primer renglon del diplay..

saludos y muchas gracias por responder


----------



## ByAxel (Dic 9, 2010)

Son solo mensajes, te avisan que no estás operando en el banco 0... por lo general no se le hace caso ya que siempre aparecen a pesar de hacer bien el traslado entre bancos; esos mensajes se pueden evitar al poner *errorlevel  -302* debajo de la declaración del PIC.

Sobre los cuadros negros en el LCD, es indicio de que no se esta inicializando bien el LCD, se puede deber a que el puerto por donde se controla al LCD no son salidas (selección del banco adecuado) o que los tiempos de escritura para el LCD no son los adecuados, entre otras circunstancias como el mismo hardware. Si lo simulas, asegúrate que ahí funcione bien.

PD: El MPLAB solo avisa errores sobre la sintaxis del código, no te indica el estado del programa, para eso debes de revisar bien la lógica del programa.

saludos.


----------



## avpc79 (Dic 11, 2010)

Hola Aroman:

Por que usar ensamblador? Si en C es tan sencillo. Si es por optimizar memoria, por que no usar un pic con mas memoria?? Costo? Tampoco cuestan un ojo de la cara estos dispositivos. 

Saludos.-

NOTA: En C con mucho gusto te diera una mano.


----------



## ByAxel (Dic 11, 2010)

*avpc79* tienes razón... asm, c, basic o hasta gráfico... por cualquiera se puede pero tal vez sea un trabajo escolar y esté aprendiendo ese mismo lenguaje, así que hay que ayudar en lo que se pueda...

salud2


----------



## aroman213 (Dic 15, 2010)

bueno si me puedieras ayudar en c, como seria?


saludos


----------



## avpc79 (Dic 16, 2010)

Aroman:

En C seria algo asi:

#include <lcd.c>   // tambien sirve una libreria q se llama flex_lcd.c


main()
{
   lcd_init();

   while()
  {
    printf(lcd_putc,"Hola Mundo");

  }
}

Obviamente omití las instrucciones de configuracion del PIC, solo queria mostrarte lo necesario para escribir en la LCD.


Conoces el lenguaje C?

Saludos.-


----------



## eyi (Ene 21, 2011)

Hola como estan??quería contarles que he estado intentando hacer funcionar la pantalla lcd usando el pic 16f877 con un programa simplecito es prácticamente el HOLA MUNDO y es en CCS, solo quiero ver si mi pantalla funciona para luego si pasarle el código del otro programa que estoy haciendo, pero con el HOLA MUNDO he tenido problemas, al encender lo que sale es una línea y se queda ahí no muestra nada luego de 5 segundos empieza a disminuir poco a poco hasta que se desvanece la línea, porque creen que me suceda esto??he revisado la conexión una y otra vez y medido continuidad pero no he visto mi error, xfa si me pueden ayudar??...Saludos!!!


----------



## avpc79 (Ene 21, 2011)

Hola Eyi, que tipo de lcd es? 16x1, 16x2, 20x4..... etc. Sube una foto de tu montaje o un diagrama, codigo fuente.. a ver en q se te puede ayudar


----------



## eyi (Ene 21, 2011)

el lcd es de 16x2 y este es el código en ccs:

#include <16f877.h>
#use delay(clock=4000000)
#use standard_io(A,B,C)
#FUSES XT, NOWDT, NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT


#include<lcd.c>  //Para el lcd
#include<stdio.h>

void main()
 { lcd_init();
  for(;
  {
      lcd_putc("\fHola Mundo");
      delay_ms(300);
  }
 }

En el proteus me funciona pero en "la vida real" me sucede lo de la línea, no tengo como subir una foto pero es mas o menos así, es un paint modificado jaja solo le agregué una línea para que mas o menos vieran que sucede


----------



## avpc79 (Ene 23, 2011)

Eyi, asumiendo que tienes bien conectado el hardware, prueba quitando el \f de lo que mandas a escribir, ese caracter borra la pantalla, estas borrando y escribiendo repetidamente. Vamos a ver que sucede

Cuando usas la libreria LCD.C te obliga a usar el puerto B o el puerto D segun comentes o no una linea de codigo en dicha libreria, estas usando el puerto correcto?


----------



## eyi (Ene 23, 2011)

Estoy usando el puerto D que es el que usa por defecto no??, y ayer probe lo de borrar la parte de "\f" pero igual sigue es apareciendo la línea...crees que haya quemado la pantalla??


----------



## avpc79 (Ene 23, 2011)

Si nunca has modificado el archivo LCD.C, si, es el puerto D el que usa. Yo estuve enrollado con las LCD por que conectaba mal el contraste, no tenia idea de lo que era un divisor de tension y por ello conectaba mal el potenciometro (siempre me decia "por que le sobrara un pin a los potenciometros...??" pues no sobraba. 

Al aplicarle tension a los terminales correspondientes (1 y 2) deberias ver que toda la linea 1 se obscurece, eso es debido a que no se ha inicializado el controlador interno de la lcd. Has esa prueba para descartar que este dañada tu pantalla. Conecta el terminal 3 a tierra para que tengas el maximo contraste.

Y por no dejar usa el puerto B...  tambien existe una libreria que se llama flex_lcd.c que te da la flexibilidad de tu elegir cual pien deseas para cada conexion con la pantalla. Prueba a ver


----------



## Jurty (Ene 24, 2011)

Hola, soy nuevo por aqui, estaba siguiendo el hilo y me he puesto ha hacer unas pruebas con lcd para ir aprendiendo, he escrito frases caracter a caracter y de forma continua, pero como puedo añadir a una frase el valor que tengo en una variable??. 

Por ejemplo, en este trozo de código la referencia al valor de la variable se haría en la posición donde se encuentran los parentesis (()). El código esta en asm, no se si me he explicado muy bien, pero si alguien puede enseñarme como va esto le estaría agradecido.

Mensaje0
		DT	"TEMP: "(()) ,0x00
Mensaje1
		DT	"HUM: " ,0x00

		include	"LCD_xx.inc"
		include	"LCD_MEN1.inc"
		END


----------



## eyi (Ene 25, 2011)

Hola Jurty mira nose como sería en asm porque casi no lo he trabajado pero si sé que en ccs sería:

    printf(lcd_putc,"\nHum: %d ",hum); siendo el %d el valor que se está midiendo porque hum está declarado como un entero, imagino que en asm debe ser similar.....Por cierto veo que estas trabajando con temp y humedad??yo también jeje =)..Suerte...

Por cierto avpc79 aún no me muestra nada mi pantallita sigue con esa línea toda extraña, conecte a tierra el pin 3, he requetechequeado la conexión para ver si por casualidad lo había conectado mal, también cambié al puerto B, pero aún no veo mi falla, he estado leyendo en foros y dicen que si se ve un mal 1 en al menos un pin de datos no se va a mostrar nada, aunque aún me quedan pruebas por hacer espero tener chance esta semana...cuando lo haga funcionar publicaré cuál era mi falla =S...eso espero...


----------



## Jurty (Ene 25, 2011)

Gracias eyi, había pensado que también podía hacerlo en c, pero lo tengo bastante olvidado, el ensamblador lo tengo más reciente, pero bueno, si veo que me da problemas me pondré a mirar c.

Estoy con un sistema para mostrar temperatura y humedad, en principio no es complicado, pero como soy novato....,jeje.


----------



## Jurty (Ene 25, 2011)

Ya está solucionado, lo único que hay que hacer es cargar el valor de la variable en el acumulador (w) antes de usa el lcall. El único problema es que hay que tener en cuenta que el valor que tenemos lo interpretará como ASCII a partir de la tabla CGROM, por lo que tendremos que adecuar el valor de la variable antes de cargarlo si nuestra librería no tiene una instrucción específica para eso.

Yo lo tengo así:

movf	temperatura,w
call	LCD_DATOS

Si en lugar del LCD_DATOS tenemos uno preparado para mostrar valores tal cual sería perfecto.


----------



## skp (Abr 2, 2011)

DEBES INICIAR EL LCD

lcd_init();


----------



## acast (Jun 9, 2011)

Buenas amigos, yo estoy con un proyecto que controla temperatura con 2 sensores diferentes a elegir por el usuario, pero tengo el problema con la LCD. Alimento y lo unico que se ve en la LCD es una linea de cuadros negros. ¿Que puede ser? EN PROTEUS TRABAJA BIEN, EL PROBLEMA ES EN LA VIDA REAL.

Ver el archivo adjunto Codigo ct.txt


----------



## andyt (Ago 15, 2012)

hola muchachos..
tengo un problema con la lcd, pongo mensajes y me salen otras letras y en posicines que nada que ver, en proteus me funciona ala perfeccion, y con aterioridad me funcionaba bien no se por que ahora m salen letras raras

gracoas por su colaboracion


----------



## energyxxi (Ago 17, 2012)

Problemas clásicos del LCD.
No se vé nada o si el lcd es de 2 líneas, está todo negro. --> contraste
El lcd es de 2 líneas --> solo se vé la primera línea y de negros --> el lcd no ha inicializado y la prueba es que está en modo 1 línea. Cada LCD es diferente en tiempos de inicialización.
Sospecha de poco cuidadoso en contactos -->Tener a mano un pic grabado con un programa que haya funcionado antes para chequear los contactos.
El LCD es la herramienta más importante que tienen los micros --> para depurar un software sin hacer uso de Incircuit debugger y cosas de esas. Podeis mostrar el valor que van tomando los registros y visualizarlos, así saber que pasa dentro del pic. Hay veces que un protocolo deja colgado el pic en un punto, pues podréis ver en que línea ha fallado exactamente, y corregilo.

 Si alguien quiere trucos para principiantes que me lo diga. 
SÓLO uso ensamblador, es el más cercano al micro y hay que entenderlo, lo demás es usar una calculadora no la cabeza, con lo cual es más difícil buscar el error. Cuando estudié no entendía esto, porqué tanto esfuerzo. Tu pc se mueve en ensamblador?


----------

