# Problemas con Display LCD en CCS



## AFEPE (Ene 19, 2011)

Tengo dos lcd uno de referencia: YJ-162A (fondo verde) y otro QY1602A (fondo azul). Trabajando con la libreria del ccs c, solo consigo que me funcione con el YJ-162A pero al colocar el otro lcd no sale nada, QY1602A nada. Estoy trabajando a cuatro bits.

Siempre habia usado el YJ-162A sin problemas, pero necesito otros y por ahorrar dinero compre de los de fondeo azul y tengo este problema. ¿Alquien le ha pasado lo mismo?.

Gracias.


----------



## Vegetal Digital (Ene 20, 2011)

El color del led del backlight no deberia influir en lo más minimo...fijate que los pines sean los mismos para ambos, quiza te confiaste hay un pin distinto y es ese el que molesta. No tenes a mano los datasheet?
Saludos


----------



## AFEPE (Ene 20, 2011)

Nada, el data sheet no lo he encontrado (el del LCD que  no me funciona), igual estoy tomando como guia la numeracion de pins que esta en la parte de atras del LCD.

¿Todos los LCDs funcionan igual, indiferente a la referencia, fabricante o compilador?


----------



## 1024 (Ene 21, 2011)

AFEPE dijo:


> ¿Todos los LCDs funcionan igual, indiferente a la referencia, fabricante o compilador?


No todos los LCD tienen el mismo driver hitachi que es el mas común, podría ser que el lcd que tienes contenga otro driver, si fuera ese el caso lo que puede estar sucediendo es que, como mínimo, la inicialización del LCD cambia y otros comandos tambien pueden cambiar.


----------



## gzaloprgm (Ene 22, 2011)

Agregale una demora de 25ms al principio de iniciar el programa (antes de inicializar el lcd)... Algunos tardan ese tiempo en prenderse... Además podrías agrandar el delay entre instrucciones, para descartarlo. 

Si tiene las patas estándar y en el órden típico es muy seguro que tenga el controlador HD44780.


----------



## CISR (Ago 24, 2012)

Hola a todos !

tengo una duda , estoy comenzando a manejar LCD en un pic 18f452 realice el siguiente programa y no me aparece nada en la pantalla



```
#include <18f452.h>                 
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP       
#use delay (clock=4000000)         //Fosc=4Mhz
#define use_portb_lcd TRUE         //definir portb lcd
#include <lcd.c>                  //libreria lcd
      
///PROGRAMA
void main(void)
{
while (TRUE)
{
   lcd_init();         //inicializar lcd
   printf(lcd_putc,"hola mundo ;)\prueba 1");   //muestra por pantalla el mensaje   
}
}
```

estoy trabajando en CCS , he leido algo sobre poner retardos , pero no sé si esa sea la solucion y si la es , alguien que me pueda explicar porfavor 

el LCDC lo conecto al puerto B y uso un cristal de 4MHz


----------



## D@rkbytes (Ago 24, 2012)

¿Ya revisaste bien tus conexiones?
Para una simple prueba este código funciona.

```
void main(void)
{
lcd_init();
lcd_putc("HOLA MUNDO");
lcd_gotoxy(1,2);
lcd_putc("HELLO WORLD");
}
```
Con el código que usaste, se vería algo como esto en la primer línea de la pantalla...
*hola mundo ; )pru*
Y parpadeando rápidamente.
Si no haz modificado la librería LCD.C adjunto un esquema de como debe estar conectado el LCD.

PD. Al usar lcd_init(); ya no necesitas usar retardos antes de escribir.
En esa función se hacen los necesarios para inicializar la pantalla.

Suerte.


----------



## CISR (Ago 24, 2012)

el diagrama de pines es el generico , el lcd es el JHD 162A ,estoy usando la configuracion de 4 pines y agregue un retardo pero sigue sin funcionar


```
#include <18f452.h>                 
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP       
#use delay (clock=4000000)         //Fosc=4Mhz
#define use_portb_lcd TRUE         //definir portb lcd
#include <lcd.c>                  //libreria lcd
      
///PROGRAMA
void main(void)
{
while (TRUE)
{
   delay_ms(25);
   lcd_init();         //inicializar lcd
   printf(lcd_putc,"hola mundo ;)\prueba 1");   //muestra por pantalla el mensaje   
}
}
```

alguna observacion ???


----------



## D@rkbytes (Ago 24, 2012)

CISR dijo:


> el diagrama de pines es el generico , el lcd es el JHD 162A ,estoy usando la configuracion de 4 pines y agregue un retardo pero sigue sin funcionar
> 
> alguna observacion ???


OK. Ese mismo modelo de LCD tengo yo en azul y verde.
Quita el while(true)
No tiene caso que repitas la escritura.
Si puedes, adjunta un diagrama de tus conexiones.


----------



## CISR (Ago 24, 2012)

Hola D@rkbyte gracias por la ayuda ,modifque el programa con el codigo que pusiste y sigue sin funcionar

#include <18f452.h>                 
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP       
#use delay (clock=4000000)         //Fosc=4Mhz
#define use_portb_lcd TRUE         //definir portb lcd
#include <lcd.c>                  //libreria lcd

///PROGRAMA
void main(void)
{
lcd_init();
lcd_putc("HOLA MUNDO");
lcd_gotoxy(1,2);
lcd_putc("HELLO WORLD");
}

las conexiones son como las de tu diagrama , agregando el cristal de oscilacion con sus 2 capacitores y no se ve nada ,alguna sugerencia ???


----------



## D@rkbytes (Ago 24, 2012)

CISR dijo:


> las conexiones son como las de tu diagrama , agregando el cristal de oscilación con sus 2 capacitores y no se ve nada ,alguna sugerencia ???


Pues si, ahora que recuerdo, si tengo una sugerencia, ya que tuve ese mismo problema hace tiempo.
Por más que busque por donde podía estar la falla, no encontraba que estaba mal.
Leyendo varios temas por aquí y por allá, vi que alguien actualizo la librería LCD.C
Entonces realice la actualización del programa y si.  Con eso funciono.

Suerte.


----------



## CISR (Ago 28, 2012)

tienes esa actualizacion ???

me la puedes pasar ???

sigue sin verse nada ...


----------



## aparco inga (Ago 28, 2012)

trabajo ccs y en  hay 
esta lcd.c ya  esta configrd para puerto d
si encaso quieres otra cambiar   la lcd.c


----------



## D@rkbytes (Ago 28, 2012)

CISR dijo:


> tienes esa actualizacion ???
> 
> me la puedes pasar ???
> 
> sigue sin verse nada ...


La actualización se realiza a través del mismo programa.
Pero necesitas ser usuario registrado.
Cabe resaltar que cuando la librería LCD.C no funciona, tampoco funcionan las simulaciones.
Así que puedes probar la simulación del amigo aparco inga, para que salgas de dudas.

Suerte.


----------



## CISR (Ago 28, 2012)

hola gracias por los archivos

les comento que no me simula el proteus si cambio al puerto B , este es mi programa:


//   Conexiones: B0 -> E            
//               B1 -> RS         
//               B2 -> RW      
//               B4 -> D4        
//               B5 -> D5            
//               B6 -> D6   
//               B7 -> D7                   
//////////////////////////////////////////////////////////////////////////////////

#include <18f452.h>    
#fuses NOWDT,WDT128,HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV42, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB       
#use delay (clock=4000000)         //Fosc=4Mhz
#define use_portb_lcd TRUE         //definir portb lcd
#include <lcd.c>                  //libreria lcd

///PROGRAMA
void main(void)
{
lcd_init();
lcd_putc("HOLA MUNDO");
lcd_gotoxy(1,2);
lcd_putc("HELLO WORLD");
} // si funciono OK !!!

simulo el que me mandaste y si funciona , si pongo el mismo programma y agrego al linea para cambiar al puerto B no simula, pero ya en el circuito si se despliega el mensaje en el LCD


----------



## maytzuc (Sep 2, 2012)

disculpen me gustaría que me ayuden tengo un problema que me ha tenido dando vueltas la cabeza todo el fin de semana, estoy comenzando a programar CCS y deseaba aprender a iniciar un LCD, encontre algunos codigos en videos de youtube y los copie. Al momento de compilar mi codigo me dice que no hay errores pero cuando lo trato de simular en proteus la LCD se mantiene en blanco y me sale la alerta de _attempt to read after writing a single nibble_. La verdad no se que hacer estoy desesperado, por ai lei que podria ser una incompatibilidad del proteus con el W7. espero que puedan aclarar mi duda. 



```
#INCLUDE <16F877A.h> //incluimos el pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador 
#use delay (clock=4M)  //establecemos la frecuencia
#include <lcd.c>  // abrimos la libreria del lcd

void main() // inciamos el programa
{
while(true){
delay_ms(20);
lcd_init(); //iniciamos la lcd
delay_ms(20);
 printf(lcd_putc,"LCD"); // escribimos texto en la lcd
}
}
```


----------



## D@rkbytes (Sep 2, 2012)

El programa en CCS no es el problema.
Como nada más vas a escribir una sola vez la palabra LCD, no tiene caso el while(true)
Eso hará que se repita la escritura muchas veces y muy rápido, por lo tanto veras un parpadeo en la pantalla.

El código que adjuntas, no tiene porque provocar errores en proteus, y debe funcionar físicamente.
Así que el problema si puede ser como mencionas, por incompatibilidad con W7.

Para que salgas de dudas, adjunto una simulación con el código que usaste.
La cual a mi no me genera ningún tipo de error sobre proteus 7.8 en XP.

Nota:
Solo omito el bucle para evitar el parpadeo en la pantalla.

Saludos.


----------



## maytzuc (Sep 2, 2012)

hola, disculpa tengo la novedad que el archivo que me pasaste en rar si me funciona, pero lo copio y pego para hacer un nuevo archivo en CCS y cuando ejecuto el .hex que yo creo no me funciona :´(


----------



## D@rkbytes (Sep 2, 2012)

maytzuc dijo:


> hola, disculpa tengo la novedad que el archivo que me pasaste en rar si me funciona, pero lo copio y pego para hacer un nuevo archivo en CCS y cuando ejecuto el .hex que yo creo no me funciona :´(


OK. Moví aquí tu tema por tratarse del mismo problema, y para tener la información agrupada.
Mira desde el post #10. Posiblemente encuentres la solución a tu problema.


----------



## CISR (Sep 2, 2012)

Estas usando el pic 16f877A o el 16f877 ???

probablemente ahi este el problema


----------



## maytzuc (Sep 2, 2012)

por lo visto es la librería de lcd.c, que necesita actualizarse, ya que los dos ejemplos , tanto el tuyo como el del otro chavo, funcionan de maravilla,  me podrias sugerir que debo hacer para actualizarla


----------



## D@rkbytes (Sep 3, 2012)

CISR dijo:


> Estas usando el pic 16f877A o el 16f877 ???
> 
> probablemente ahi este el problema


Nop. Por ahí no está el problema...
​




maytzuc dijo:


> me podrias sugerir que debo hacer para actualizarla


Claro.


D@rkbytes dijo:


> La actualización se realiza a través del mismo programa.
> Pero necesitas ser usuario registrado.



También puedes probar con la librería Flex_LCD416 que funciona muy bien.

Suerte.


----------



## maytzuc (Sep 3, 2012)

Probare la libreria que anexaste pero por pura curiosidad como me convierto en usuario registro para que se actualicen mis librerias


----------



## D@rkbytes (Sep 3, 2012)

Directamente en la pagina de CCS http://www.ccsinfo.com/register.php
Compras tu licencia y listo.
No trates de pedir cracks o licencias, ya que esta prohibido, e incurres en faltar a la norma 2.9 del foro.


----------



## fenix129 (Sep 24, 2012)

hola que tal, tengo un problema con el pic 16f887 y una pantalla lcd 2x16 y espero y me puedan ayudar. El problema es que no logro que el lcd muestre lo que deseo y he llegado al punto de tratar que muestre el tradicional mensaje de HOLA pero no pasa nada, espero y me puedan ayudar a ver que estoy haciendo mal. Pongo los programas y las imagenes de la simulacion.

programa 1 de prueba:

```
#include <16F887.h>
#fuses XT, NOWDT, NOPROTECT, PUT
#use delay(clock=4000000)
#include <lcd.c>
#use fast_io(D)

void main(void)
{
   lcd_init();
   printf(lcd_putc,"HOLA");
}
```

programa que tengo que lograr que muestre:


```
#include <16f887.h>
#fuses XT, NOWDT, NOPROTECT, PUT
#use delay(clock=4000000)
#include <lcd.c>
#use fast_io(D)
int x;

main() 
{
       lcd_init();
       while(TRUE)
       {
                  for(x=0;x<16;x++)
                  {
                  lcd_gotoxy(x,1);
                  printf(lcd_putc,"  Hola");
                  delay_ms(500);
                  lcd_getc(x,2);
                  printf(lcd_putc,"  Como estas?");
                  }
         }
}
```


----------



## D@rkbytes (Sep 25, 2012)

fenix129 dijo:


> El problema es que no logro que el lcd muestre lo que deseo y he llegado al punto de tratar que muestre el tradicional mensaje de HOLA pero no pasa nada, espero y me puedan ayudar a ver que estoy haciendo mal.


Saludos.


D@rkbytes dijo:


> Moví aquí tu tema por tratarse del mismo problema, y para tener la información agrupada.
> Mira desde el post #10. Posiblemente encuentres la solución a tu problema.



Si no encuentras la solución a tu problema en este tema, coméntanos por favor.

Suerte.


----------



## marcelo2112 (Sep 27, 2012)

Tenia un problema similar que no pude solucionar con las respuestas de este post, pero leyendo mucho encontré que hay un problema del archivo LCD.C, por lo que busque una versión anterior y funciono. Saludos


----------



## erickmarcelo (Oct 1, 2012)

Hola a todos, tengo un problema con el pic 16f887... lo que sucede es que hice un programa en CCS para que salga un mensaje en un LCD, pero cuando conecto el LCD a los puertos D, del microcontrolador,  no pasa nada... . Vi con el voltimetro si el pic mandaba señal y tampoco manda nada... . En el mismo programa tengo un led que parpadea y lo hace de forma normal... 

Adjunto mi programa, quisas ahí esté el problema...


----------



## josemaX (Oct 1, 2012)

Tendrías que definir en algún sitio los pines a los que conectas el LCD.

#define use_portb_lcd TRUE

Además te sobra el espacio antes de ( en: (aunque no se si esto es importante o no)
lcd_gotoxy (1,1);


----------



## erickmarcelo (Oct 1, 2012)

Josemax ya le aumente el #define use_portb_lcd TRUE y le arregle lo del lcd_gotoxy(1,1) , pero aun nada... el pic sigue sin mandar señal al LCD.... cual podría ser la razón??... mi circuito funciona normal... los leds prenden como deberían... pero el LCD  no muestra nada y el PIC no manda señales.  Mi programa lo estoy haciendo con PIC-C compiler... el programa podría ser el problema??


----------



## josemaX (Oct 1, 2012)

Te falta ver si lo tienes bien conectado. Lo esta? El circuito de contraste esta bien? No sea que no veas nada pero sea por ese motivo.


----------



## erickmarcelo (Oct 1, 2012)

Sí está bien conectado, El Vss a tierra, Vdd a 5v, Vee con el potenciometro, de D0 a D3 a tierra y de D4 a D7 a los pines del PIC del puerto D...  . Con el voltimetro veo si el PIC manda señal por el Puerto D pero no manda nada... . En otro blog lei que quisas sea porque la libreria del LCD.C de mi programa no está actualizada... podría ser por eso?


----------



## josemaX (Oct 1, 2012)

Te quiero avisar que no soy experto en C, aprendiendo. Pero ese enable que te he puesto es para el puerto B, no el D

La conexión es: (CCS C)

PORT.D0 -> enable
PORT.D1 -> rs
PORT.D2 -> rw
PORT.D4 -> D4
PORT.D5 -> D5
PORT.D6 -> D6
PORT.D7 -> D7

No se yo si un voltímetro reaccionara suficientemente rápido a estos pulsos. Esto se mira con un analizador lógico. Uno bien barato http://jwasys.home.xs4all.nl/old/diy2.html


----------



## erickmarcelo (Oct 1, 2012)

También lo estoy viendo con una punta lógica pero nada. El enable que me mandaste lo pase a #define use_portd_lcd TRUE... creo que así se refiere al puerto D, pero el PIC no manda nada aún... . Vi si funcinaba con el Puerto B, pero igual el PIC no manda nada


----------



## josemaX (Oct 1, 2012)

Pues ya no se me ocurre nada mas, quizá deberías publicar el esquema.


----------



## albertoxx (Oct 1, 2012)

A mi me pasaba lo mismo busca en ves del lcd.c busca en internet el flex_lcd.c ademas tambien antes del include le tienes que decir que pines vas a usar para la transmision algo asi

#define LCD_DB4   PIN_A0
#define LCD_DB5   PIN_A1
#define LCD_DB6   PIN_A2
#define LCD_DB7   PIN_A3
#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_C2


----------



## erickmarcelo (Oct 1, 2012)

Gracias albertoxx, el pic ya manda señales ... pero igual no sale nada en el LCD, creo que el LCD es genérico y no es hitachi... ese podría ser un problema también verdad?


----------



## albertoxx (Oct 1, 2012)

si te funciona en proteus lo mas seguro es el contraste pone un potenciómetro en vez de una r fija


----------



## erickmarcelo (Oct 2, 2012)

Le puse un potenciometro pero nada aun :S , quisas haya puesto algo mal en mi código... lo adjunto para que lo veas... quisas algo esté mal


----------



## D@rkbytes (Oct 2, 2012)

erickmarcelo dijo:


> Le puse un potenciometro pero nada aun :S , quisas haya puesto algo mal en mi código... lo adjunto para que lo veas... quisas algo esté mal


Antes de que continues haciendo pruebas fallidas...
¿Ya te tomaste la molestia de leer todo el contenido del tema?
Lo más seguro es que encuentres la solución a tu problema.
También te recomiendo que adjuntes un esquema de las conexiones de tu pantalla al PIC.





erickmarcelo dijo:


> creo que el LCD es genérico y no es hitachi... ese podría ser un problema también verdad?


Cuando se habla de pantallas genericas por lo regular se trata de pantallas basadas en el controlador Hitachi HD44780


----------



## erickmarcelo (Oct 2, 2012)

Ahí está el esquema de mi circuito con el LCD conectado... . Leí todos los temas y hasta ahora no tengo solución con lo del LCD... el PIC manda las señales pero no aparece nada en la pantalla... cuando lo simulo en el proteus todo sale normal


----------



## D@rkbytes (Oct 2, 2012)

erickmarcelo dijo:


> Leí todos los temas y hasta ahora no tengo solución con lo del LCD.
> El PIC manda las señales pero no aparece nada en la pantalla


Saludos.
Prueba con este sencillo programa y nos comentas.

Suerte.


----------



## erickmarcelo (Oct 2, 2012)

Gracias D@rkbytes!!! el LCD  ya prendio y me muestra el mensaje y todo


----------



## Francirius (Dic 28, 2012)

Hola compañeros!
Bueno hace algun tiempo comencé un proyecto de una fuente de poder, de doble polaridad, controlada por un F877A a 20 Mhz,
hasta esa parte todo bien, se puede ajustar el voltaje con un encoder desde +/-1,4 a +/-12 V, y tiene 3 pulsadores para 3 voltajes 
fijos (3,3V, 5V y 12 V).
El control del encoder lo hace con la interrupcion por cambio externa en rb0, y el seteo de los voltajes con la interrupcion de cambio de estado
de los pines rb4 al rb7. Hasta ahi todo bien...
PEro a la hora de conectarle el lcd 16x2 HITACHI, no lo inicializa, si llevo el contraste a GND, se ven las 2 lineas negras, y si lo vario, se apaga una y queda la otra en negro, hasta que queda en blanco.
He sido bastante metodico, y la ultima prueba que hice fue sacarle todas las interrupciones y aun asi no funciona...
Ah! en el proteus me funciona de maravillas! 
Adjunto el codigo:


```
#include <16F877A.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_portd.c>
#ZERO_RAM
//#byte porta = 0x05        // Asignamos PortA (No lo usamos).
#byte portb = 0x06        // Asignamos PortB (Usamos RB0 y RB1).
//#byte portc = 0x07        // Asignamos PortC (8 salidas a LED).
// ------ Variable Global ------
long   x=1;               //Declaramos el valor de X 10 bits
// x=88d-->5[V]
// x=48d-->3,3[V]
// x=255-->12 [V]
// ---------- Interrupción ----------
#INT_EXT 
void IntRB0() 
{
     if (bit_test(portb,0))       // Si RB0 se ha puesto a 1 (flanco de subida),
     {  
         ext_int_edge(H_TO_L);    // entonces activar la siguiente interrupción por flanco de bajada.
         if (bit_test(portb,1))   // Si RB1 está 1,
         {
            x++;                  // entonces incrementar el contador X.
            if((x==0xFF)){
            x=0xFE;
            }
         }
     }
     else                         // Si RB0 se ha puesto a 0 (flanco de bajada),
     {  
         ext_int_edge(L_TO_H);    // entonces activar la siguiente interrupción por flanco de subida.
         if (bit_test(portb,1))   // Si RB1 está 1,
         {
            x--;                  // entonces decrementar el contador X.
            if((x==0)){
            x=1;
            }
         }
     }
}
//Interrupcion por cambio de estado en puerto B.
/*#int_RB 
void RB_isr(void) //función de interrupción 
{ 
   if(bit_test(portb,4)) x=88;
   if(bit_test(portb,5)) x=48;
   if(bit_test(portb,6)) x=255;
} */
// ---------- Programa Principial ----------
void main()
{
   port_b_pullups(FALSE);
   setup_adc_ports(NO_ANALOGS);        //activar para leer voltaje.
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,63,1);       //segun tabla 78 khz @ 8 bits
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_ccp1(CCP_PWM);
   lcd_init(); 
   //---- Fin de la configuración del 16F876A ----
   
   enable_interrupts(int_ext);    //Activar Interrupcion Externa. 
   ext_int_edge(L_TO_H);          //Inicialmente Interrupción por Flaco de Subida. 
   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);     //Interrupciones Generales Activadas. 


   While (true)
   {

   lcd_gotoxy(1,1);
   set_pwm1_duty(x);             //x= 0 a 255 -->0 a 100%.
   printf(lcd_putc,"hola");
   }       
}
```

Muchas Gracias!!


----------



## Francirius (Dic 29, 2012)

Estuve revisando los delay de la libreria, pensando en que al cambiar cristal de 20 Mhz, lo estaba afectando. 
Me parecio logico que a 4 MHz, la linea

```
delay_cycles(1)
```
era de 1 us, en cambio a 20 Mhz, este retardo seria
de 0,2 us, por lo tanto lo cambié por

```
delay_cycles(5)
```
Resultado: NADA...
Cuando estaba a punto de volver a cambiar el codigo (y prenderle fuego al protoboard), recordé que entre todas las cosas que iba
probando, le habia puesto unos capacitores del cristal de 4 Mhz de 0,22 pF, se los quité y voilá! ahi comenzó a funcar!!
Le volví a poner el retardo de 1 ciclo, para ver si le habia ayudado en algo, y fue lo mismo...
Ahi dejo un videito para que vean como va el proyecto:

http://www.youtube.com/embed/IQbxlDka7e0


----------



## 1024 (Dic 31, 2012)

Francirius dijo:


> Estuve revisando los delay de la libreria, pensando en que al cambiar cristal de 20 Mhz, lo estaba afectando.
> Me parecio logico que a 4 MHz, la linea
> 
> ```
> ...





Hola, al parecer tienes un problema de ruido, en el video que muestras no se distingue bien el armado del circuito, te sugiero colocar capacitores de 33pf para tu cristal y tambien colocar capacitores de desacoplo de valor 0.1uf en el pic


----------



## gladiadortuc (Mar 4, 2013)

Hola! 
Es primera vez que pregunto. Mi circuito es para un lavarropas, hecho con PIC 16F877A con un xtal de 4Mhz, con capacitores de 22pF, tal como dice el manual. 
La aplicación está hecha con el C de CCS y al menos en el PROTEUS funciona perfecto. Tiene un display WinStar 1602 del azul, de 2 líneas 16 caracteres. Aquí el problema.

No escribe bien los mensajes que escribí y además agrega o cambia caracteres diferentes. Pareciera errático y aleatorio pero, muestra casi siempre lo mismo. No pude tomarle fotos, pero, creo que me entenderán.. 

Alguien sabe si es el display que funciona mal o es el ruido eléctrico. En el último caso, dónde filtro la señal para las patillas del display?

*1024* dijo antes: "Hola, al parecer tienes un problema de ruido, en el video que muestras no se distingue bien el armado del circuito, te sugiero colocar capacitores de 33pf para tu cristal y tambien colocar capacitores de desacoplo de valor 0.1uf en el pic"

Creo que mi problema también reside en el ruido eléctrico, dónde hay que colocar el "*capacitor de desacoplo*"? Y en el mensaje anterior también menciona que "sacó los capacitores del cristal", voy a probar sacarlos, pero creo que así no va a funcionar... 

Gracias


----------



## gladiadortuc (Mar 4, 2013)

Desconecté los capacitores de 22nF del cristal y todo sigue igual. El sector de rutina:

```
void MostrarPrograma(int programa){
   lcd_gotoxy(1,2);
   if (programa==1)
         printf(lcd_putc, "%u-Ropa algodon  ",programa); // El string debe ser tan largo como el mas largo de todos.
   if (programa==2)
         printf(lcd_putc, "%u-Ropa delicada ",programa);
   if (programa==3)
         printf(lcd_putc, "%u-Ropa muy sucia",programa);
   if (programa==4)
         printf(lcd_putc, "%u-Modo agresivo ",programa);
   if (programa==5)
         printf(lcd_putc, "%u-Desagote      ",programa);
   if (programa==6)
         printf(lcd_putc, "%u-Centrifugado  ",programa);
//   if (programa==7)
//         printf(lcd_putc, "%u-[CONFIGURAR]  ",programa);
   generate_tone(800, 100);
   while (input(BUT_IZQ)==0 || input(BUT_DER)==0) restart_wdt();
}

 //#org 0x800  // Se coloca en el segundo segmento porq no entra en el primer segmento
          // y ademas usando la directiva #separate hace q cuando se llame a la directiva rtos_terminate()
          // el programa salta a cualquier posicion de memoria q no tiene nada q ver... No se porq es.
#SEPARATE
void menu(){
   int programa=1;
   int i;
   ldiv_t time; // Para cargar la funcion de espera
   short prelavado=0;
   int temperatura=0;

   lcd_gotoxy(1,1);
   printf(lcd_putc, "*Menu Programas*");
   MostrarPrograma(programa);
   while (input(BUT_MID)==1){

         if( input(BUT_IZQ)==0 && input(BUT_DER)==1){ // Solo entra si se aprieta un solo boton
            if (programa>1)
               MostrarPrograma(--programa);
            else {
               generate_tone(800, 600);//PITIDO ERROR
            };
```

El display muestra: * Menÿ programas^k"
y debajo a veces aparece bien la opción de Ropa algodon y otros... Los botones funcionan bien, pero también sucede que el display muestra cuadritos negros en determinados momentos. 
Ya cambié los tiempos en la rutina LCD.c como dice en otro post. Ya no se qué hacerle!!!!

Saludos. Gracias


----------



## gladiadortuc (Mar 5, 2013)

El problema es el Display! Cambié por uno que tenía el led quemado y funciona perfecto. Eso era todo!!!


----------



## SabonJuan (Mar 25, 2013)

Buenas tardes, estoy intentando configurar un display FDCC1602P con el controlador SPLC780D, hasta donde pude revisar en las hojas de datos es igual al hitachi, pero no logro hacerlo funcionar, probe con la lcd.c (la nueva) el flex_lcd.c y no anda, sera por el controlador o me estoy comiendo algo. 
mis conecciones son 

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7
//
#define LCD_RS    PIN_A1
#define LCD_RW    PIN_A2
#define LCD_E     PIN_A0

todos los pines estan conectados y hay un trimpot de 10K conectado a V0, no se que mas hacer, estoy pensando en cambiar el pinout, pero dudo que lo solucione



No me di cuenta de aclarar que 
1 - Uso un pic 16f628a
2 - me esta  volviendo loco y me estoy quedando sin ideas
3 - tengo el display funcinoando en un RCM2100 (procesador rabbit 2000) pero aun copiando y editando el codigo del rabbit (es dynamic c) no funciona. Sinceramente no se que mas hacer. Gracias


----------



## D@rkbytes (Mar 25, 2013)

SabonJuan dijo:


> Buenas tardes, estoy intentando configurar un display FDCC1602P con el controlador SPLC780D, hasta donde pude revisar en las hojas de datos es igual al hitachi, pero no logro hacerlo funcionar, probe con la lcd.c (la nueva) el flex_lcd.c y no anda, sera por el controlador o me estoy comiendo algo.


Olvidaste adjuntar tu código y el esquema de las conexiones para ver si por ahí está el problema.
Para que realices algunas pruebas con tu pantalla, adjunto dos ejemplos que funcionan.
Con ellos podrás comprobar el funcionamiento de tu pantalla con el PIC16F628A.
En un ejemplo se uso la librería LCD.C  de CCS, y en el otro la librería Flex_LCD416.c.
En ambos utilice la misma disposición de pines para la pantalla,
pero en el ejemplo usando la librería Flex_LCD416.c, la modifique para no usar el pin R/W.

Nota: Utiliza los archivos *.hex incluidos, no recompiles los programas.

Suerte.


----------



## SabonJuan (Mar 26, 2013)

Ahi pruebo y te aviso, desde ya muchisimas gracias!


----------



## johandanielcuellar (Abr 3, 2013)

hola a todos soy nuevo y estoy aprendiendo a programar en c con pic y estoy estudiando del libro compilador CCS con proteus para realizar practicas y ver como funcionan los microcontroladores hasta el momento voy bien pero me ha surgido un error en un código que he estado creando para practicar con el lcd y veo que el problema persiste agradecería a los que puedan ver este mensaje para saber cual es mi error para poder corregirlo y seguir aprendiendo sobre este tema tan importante como lo es la programación de pics.
Bueno para empezar el programa se basa de que quiero mostrar por el lcd el abecedario y los números pero para eso debo tengo dos entradas digitales una para indicar que me muestre el abecedario y la otra los números pero tengo un error en el código que no entiendo agradezco su colaboración este es el código.

```
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <16f877a.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use  fast_io (A)
#use  fast_io (B)

#include <lcd.c>               // libreria lcd//
#define use_portb_lcd==TRUE   //defino puerto b para usarlo//


 
 char  abecedario [26]={'a','b','c','d','e','f','g','h','i','j',
                              'k','l','m','n','o','p','q','r','s',
                              't','u','v',"'w','x','y','z'};
 int  numeros[10]=          {0,1,2,3,4,5,6,7,8,9};                 


void main()
{
     set_tris_a(0x3);
     int x,y;
     lcd_init();
     lcd_putc('\f');// borrar lcd
   
   while(true)
   {
        x,y=0;
    if  (input(pin_A0))     //cuando pulso esta entrada veo el abc en el lcd//
       {
        for(x;x<26;x++)
                      { 
        lcd_gotoxy(1,1);
        printf(lcd_putc,"car=%c,abecedario");
        delay_ms(300);
        
        abecedario[x];
        delay_ms(300);
        lcd_putc('\f');// borrar lcd
                      }
       }
    if  (input(pin_A1))    // muestra los numeros al pulsar la entrada//
       {
        for(y;y<10;x++)
                      {
                
        printf(lcd_putc," Num=%u",numeros);
        lcd_gotoxy(1,1);
        delay_ms(300);
        
        numeros[y];
        delay_ms(300);
        lcd_putc('\f);// borrar lcd
                      }
       }  
       

   }

}
////////////////////////////////////////////////////////////////////////////////////////////////////////
```


----------



## D@rkbytes (Abr 3, 2013)

Prueba así, y ve en donde tenias los errores...

```
#include <16f877a.h>
#fuses NOBROWNOUT
#use delay(crystal=4MHz)

#include <lcd.c>               // libreria lcd
// #define use_portb_lcd=TRUE   // Ésto se define en la librería lcd.c
// Por default para el PIC16F877A se usará el puerto D


char abecedario [26] = {'a','b','c','d','e','f','g','h','i','j','k',
                        'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
                              
int  numeros[10] = {0,1,2,3,4,5,6,7,8,9};              


void main()
{
   setup_adc_ports(NO_ANALOGS);
   lcd_init();
   lcd_putc("\fCaracter = a\nNumero = 0");   // escribir en la dos líneas del LCD
   
   int x,y=0;
   
   while(true)
   {
   if(input(pin_a0))      // cuando pulso esta entrada veo el abc en el lcd
    {
      for(x=0;x<=25;x++)
      {
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Caracter = %c",abecedario[x]);
         delay_ms(300);
      }
    }
   if(input(pin_A1))    // muestra los numeros al pulsar la entrada
   {
      for(y=0;y<=9;y++)
      {      
         printf(lcd_putc,"\nNumero = %u",numeros[y]);
         delay_ms(300); 
      }
   }
 }
}
```
Adjunto la simulación.

Suerte.


----------



## johandanielcuellar (Abr 3, 2013)

gracias por corregir mis errores sere mas cuidadoso y seguire estudiando mas para poder subir de nivel pero tengo ciertas dudas con esto porque quitaste el set_tris el cual indicaba quienes eran entradas y al colocar 
setup_adc_ports(NO_ANALOGS); es para indicar que? gracias por tu ayuda  D@rkbytes.


----------



## D@rkbytes (Abr 3, 2013)

johandanielcuellar dijo:


> tengo ciertas dudas con esto porque quitaste el set_tris
> el cual indicaba quienes eran entradas


Porque no vas a utilizar ningún pin como salida en el puerto A
Y conforme a lo que muchos piensan, que los pines que no se usan hay que dejarlos como salida...
Existe mucha controversia y mala información al respecto.
Los pines que no se usan simplemente no pasan a formar parte del programa.
Por lo tanto no alteran el funcionamiento del programa ni generan oscilaciones como muchos creen.
Cuando un puerto no es configurado con la instrucción TRISX todo el puerto son entradas.
En lo personal los pines que no voy a usar los dejo como entradas solo por motivos de seguridad.
Pero cada quien sus gustos, y si te pones a buscar verás opiniones de todos colores y sabores. 


johandanielcuellar dijo:


> y al colocar setup_adc_ports(NO_ANALOGS); es para indicar que?


El puerto A y el puerto E del PIC16F877A tienen conversores AD, y éstos por default están activos.
Si vas a realizar comparaciones de estado (0 y 1) para el uso de pulsadores como en este caso,
la instrucción setup_adc_ports(NO_ANALOGS) los convierte en puertos con entradas de lógica digital.
Es importante tener en cuenta este detalle, ya que muchos olvidan establecer la configuración del ADC,
y obtienen resultados inesperados en sus programas. 

Saludos.


----------



## mario1577 (May 9, 2013)

Hola, quiera que me ayuder porque tengo un problema al simular en el proteus el 16f887 con lcd, la lcd no muestra ningun dato, pues arme el cicuito en protoboard y si me me hace lo que le programe, mi duda es el porque no me lo simula el proteus, aqui les dejo el programa y el circuito


----------



## D@rkbytes (May 9, 2013)

mario1577 dijo:


> Hola, quiera que me ayuder porque tengo un problema al simular en el proteus el 16f887 con lcd, la lcd no muestra ningun dato, pues arme el cicuito en protoboard y si me me hace lo que le programe, mi duda es el porque no me lo simula el proteus, aqui les dejo el programa y el circuito


Con algunas modificaciones a tu programa, prueba ahora así...

```
#include <16f887.h>     
#fuses NOWDT,NOMCLR,NOLVP
#use delay(internal = 8MHz) 
#include <lcd.c>             

unsigned int dato1=0;

void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_oscillator(OSC_8MHZ|OSC_STATE_STABLE);
   lcd_init();
  
  while (true)
     {
   while (input(pin_a0)){
         lcd_putc("\fPRESIONE TECLA");
         printf(lcd_putc,"\nDATO=%d",dato1);
   while (input(pin_a0));
   }
   
   while (!input(pin_a0)){
      dato1++;
      lcd_putc("\fPULSADOR EN 0");
      printf(lcd_putc,"\nDATO=%d",dato1);
   while (!input(pin_a0));
   }
  }
}
```
Nota que también se estableció el oscilador interno a 8MHz, y se configuraron los puertos como digitales.

Suerte.


----------



## mario1577 (May 9, 2013)

mm perdon crei que no se habia subido mi pregunta jaja, gracias por responder.Pues utilize esas modificaciones que hiciste y me sigue fallando, de hecho ese programa que escribí es de un libro y pues en el libro hay imágenes que asi funciona, que raro que en mi proteus no funcione :s


----------



## D@rkbytes (May 9, 2013)

mario1577 dijo:


> Pues utilize esas modificaciones que hiciste y me sigue fallando, de hecho ese programa que escribí es de un libro y pues en el libro hay imágenes que asi funciona, que raro que en mi proteus no funcione :s


De seguro el código que usaste, es para otro PIC, pues no tenía las instrucciones para un 16F887.
Pero ahora ya las tiene, y si es cuestión de la configuración de tu diseño,
adjunto las simulaciones para proteus v7.10 y v8.0 funcionando.
Si no te funciona, entonces tienes un problema con la instalación de tu programa.

PD:
Si no puedes abrir los archivos, me avisas para cambiarlo de versión a la v7.0

Suerte.


----------



## MrCarlos (May 9, 2013)

Hola mario1577

Armé el circuito en el ISIS de Proteus y compilé el código que adjuntaste en formato .TXT.
Curiosamente funciona el circuito y el programa.

Si el nombre del archivo de tu código es LCD.C probablemente ese sea el problema por lo que no funciona.

saludos
a sus ordenes


----------



## mario1577 (May 9, 2013)

mmm que raro me descargue sus archivos y si jala, pero lo hago con el circuito que hice y ya no jala con el mismo codigo que escribieron.


----------



## MrCarlos (May 10, 2013)

Hola mario1577

Si, verdaderamente es curioso.
Me gustaría tener ese archivo .DSN para analizarlo. Me refiero al que no funciona.

Tal vez quieras comprimirlo con WinZip o WinRar y adjuntarlo aquí.

saludos
a sus ordenes


----------



## mario1577 (May 10, 2013)

Aqui estaivo el archivo


----------



## D@rkbytes (May 10, 2013)

mario1577 dijo:


> Aqui está el archivo


Pues a mi si me funciona, aún teniendo el PIC la frecuencia de trabajo a 1MHz.
Cosa que tienes que corregir, y es importante que uses la frecuencia de trabajo del programa.

Me supongo que a MrCarlos también le funciona.
Quizás tengas que reinstalar el programa, o actualizarlo.


----------



## MrCarlos (May 10, 2013)

Hola mario1577

Creo que no vamos a descubrir qué está pasando.
Probé el circuito que adjuntaste pero no tengo el archivo LCD.COF que le asignas al PIC. El que tu realizaste.

Si le asigno el que se generó con el código que adjuntaste en tu mensaje original si funciona.

Qué te parece si lo dejamos de ese tamaño ?? 

La diferencia que tenemos es que yo los nombré *TheCode.xxx* y Tú *LCD.xxx*; es por eso que creo que falla en la simulación.

En el código que adjuntaste haces referencia en la 4Ta línea: *#include <lcd.c>*
Así que como tu Código tiene el mismo nombre es ahí, creo, donde falla. Se confunde el ISIS de Proteus.

saludos
a sus ordenes


----------



## D@rkbytes (May 10, 2013)

No MrCarlos, ese no es el problema.
El programa asume cual es el código fuente, y cuales son las librerías.
El programa se puede llamar igual que alguna librería, incluso tener la misma extensión.
Y ésto se logra ya que código fuente y librería no residen en la misma carpeta.
Es bien sabido que dos archivos con el mismo nombre y extensión, no se pueden tener en la misma carpeta.

Los archivos *.cof solo son para hacer debug al programa, pero genéricamente hacen lo mismo que el *.hex.

Debe ser otro problema.


----------



## MrCarlos (May 10, 2013)

Hola D@rkbytes

Efectivamente así es.

Hablé (Escribí) si haber estudiado antes el manual que tengo.
Vi también que es diferente cuando se hace un *#include* con <. . .> que con “. . . ”
En fin yo lo dejo de ese tamaño no sé que estará pasando.

saludos
a sus ordenes


----------



## mario1577 (May 10, 2013)

pues esta raro, mejor volvere a instalar el proteus


----------



## D@rkbytes (May 10, 2013)

MrCarlos dijo:


> Hola D@rkbytes
> 
> Efectivamente así es.
> 
> ...


Pues si, se supone que al escribir #include *"*mi_lib.h*"* se refiere a cuando la librería está en la carpeta del proyecto.
Y cuando se escribe #include *<*mi_lib.h*>* se refiere a archivos en las carpetas destinadas a las librerías.
Sin embargo en el PCWHD Compiler también se puede escribir #include *"*mi_lib.h*"
*y hacer referencia a un archivo de una carpeta remota. (Por default Devices/Drivers) ó las que definamos.
Así con esto, se puede ver que el programa hace mucho por nosotros, ya que busca los archivos.

Saludos.


----------



## mario1577 (May 10, 2013)

Creo que es el compilador porque me instale el proteus 8, ya que tenia el 7.7 y puse el programa que me mandaste Hola D@rkbytes y si jalo ya, pero copie ese mismo programa e hice uno nuevo y lo simule en proteus y no jala, que podra ser??



lo extraño es que en protoboard si fi funciona el programa que me enviaste D@rkbytes y tambien el mio


----------



## D@rkbytes (May 10, 2013)

mario1577 dijo:


> Creo que es el compilador porque me instale el proteus 8, ya que tenia el 7.7 y puse el programa que me mandaste Hola D@rkbytes y si jalo ya, pero copie ese mismo programa e hice uno nuevo y lo simule en proteus y no jala, que podra ser??
> 
> 
> 
> lo extraño es que en protoboard si fi funciona el programa que me enviaste D@rkbytes y tambien el mio


Existía un problema anteriormente con respecto a la librería LCD.C en alguna versión del PCWHD
No recuerdo cual, motivo por el cual  me olvide de programar en C con ese compilador.
Luego un día por ahí leí, que se corregía actualizando el programa. Fue lo que hice y funciono.
Sin embargo aún sigue teniendo problemas en otras cosas, y por eso no lo considero muy bueno.
Tiene muchas cosas que no me agradan con respecto a otros programas, que en varios aspectos lo superan.

Pero también recuerdo que el error no solo era en simulación, también era físicamente.
No se mostraba nada en la pantalla. Y se soluciono hasta que actualice la versión del PCWHD.

PD:
Proteus no se queda atrás, y también tiene muchas malas historias que contar.

Saludos.


----------



## mario1577 (May 10, 2013)

Tambien lo mas extraño esque comenzo a fallar desde ayer, porque en la mañan si me simulaba ese programa, despues empece a simular con lcd y teclado pero no funcionaba, habia investigado que era un bug del proteus pero pues apartir de ahi ya no me funciono nada


----------



## D@rkbytes (May 10, 2013)

Usa el Revo Uninstaller y le das a Advanced, seleccionando todos los registros que te muestre, y los borras.
Así te dejará el sistema libre de rastros de la instalación de proteus. (No es muy confiable, pero suele serlo)
Yo en esos casos de desinstalar programas sin dejar rastro, lo hago manualmente, pero se requiere conocimiento.
Luego reinicias y vuelves a instalar, por lo regular funciona todo otra vez.


----------



## mario1577 (May 10, 2013)

ya funciono toda ya hice un programa de hola mundo (ya que ni ese mostraba) y el programa que hice anteriormente y ya los muestra el lcd, lo que hice fue volver a instalar el compilador la version 4.13 y ya jalo, gracias por la ayuda


----------



## D@rkbytes (May 10, 2013)

Lo ves, ahora que ya resolviste tu problema, tienes más por aprender, y verás que existen muchas cosas nuevas.
Así es esto, y siempre se aprende algo nuevo.

Te deseo mucha suerte.


----------



## brotherjulk89 (May 29, 2013)

Buen día para todos. tengo un problema en la visualización de la LCD 2X16 mediante micro 16f877A.
resulta que el programa que esta echo en PCW funciona a la perfección en el simulador Proteus. pero cuando pruebo físicamente en la protoboard con todos los elementos del montaje en la visualización aparecen saltos y los valores no se ven estables, parece como si la visualización estuviera alocada.

despliego el programa.


```
#include <16f877a.h> 
#device adc=10                    // Set ADC resolution a 10Bit
#fuses NOWDT,HS
#use delay(clock=20M) 
#include <lcd.c>
#include <math.h>

void main (void){
int16 q;
float h,HR,x,d;

   setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
   setup_adc(ADC_CLOCK_INTERNAL);       // Inicialización ADC con una rate de Crystal/20MHz  
   delay_us(10);                  // El modulo ADC es lento, necesita algo de tiempopara el ajuste.    
   lcd_init();                            // Enciende LCD
   delay_ms(100);

for(;;){  
      set_adc_channel(0);              // Activa canal ADC 0
      delay_us(20);                    // Espera 20 milisegundos
      q = read_adc();                  // Captura la corriente y la lee ADC
      h = 5.0*q/1024.0;                // Valor en tención del ADC
      x = h-3.05;                      // Resta el valor de tención al 100% establecido
      d = (100*x)/0.55;          // Se multiplica la resta*100 y se divide por 0.55 que es el 100%
      HR = 100-d;  

printf(lcd_putc,"\fVol = %2.3f",h); 
printf(lcd_putc,"\nHR = %01.2f%%     ",HR); // Imprime el valor en LCD
      delay_ms(100);
  }         
}
```


----------



## D@rkbytes (May 29, 2013)

Prueba quitando el "\f" para evitar que la pantalla se esté limpiando cada 100Ms.
Deja la instrucción así...
printf(lcd_putc,"Vol = %2.3f",h);

Suerte.


----------



## XSGAV (Jun 20, 2013)

hola, había tenido muchos problemas para utilizar mi display con un pic16f628a hasta el momento, me ah ayudado el archivo de prueba que adjunto D@rkbytes es el único archivo el cual me a funcionado a la perfeccion y pude descartar que no sirvieran mis display, el problema es que cuando utilizo mi librería LCD.C aun que habilite el puerto b no puedo lograr alguna visualización agradecería su ayuda eh bajado librerías actualizadas como la flex420 sin resultados


----------



## D@rkbytes (Jun 21, 2013)

XSGAV dijo:


> hola, había tenido muchos problemas para utilizar mi display con un pic16f628a hasta el momento, me ah ayudado el archivo de prueba que adjunto D@rkbytes es el único archivo el cual me a funcionado a la perfeccion y pude descartar que no sirvieran mis display, el problema es que cuando utilizo mi librería LCD.C aun que habilite el puerto b no puedo lograr alguna visualización agradecería su ayuda eh bajado librerías actualizadas como la flex420 sin resultados


Sube dentro de un archivo comprimido el programa que no te funciona, incluyendo tu librería.

Saludos.


----------



## XSGAV (Jun 21, 2013)

hola, gracias por responder aquí te dejo el archivo adjunto


----------



## D@rkbytes (Jun 21, 2013)

Prueba cambiando estas partes de la cabecera en tu programa por esto...
#use delay (internal = 4000000)
#define use_portb_lcd true
#include <lcd.c>

Suerte.


----------



## XSGAV (Jun 21, 2013)

D@rkbytes dijo:


> Prueba cambiando estas partes de la cabecera en tu programa por esto...
> #use delay (internal = 4000000)
> #define use_portb_lcd true
> #include <lcd.c>
> ...



D@rkbytes problema solucionado, al parecer la librería CCS de la versión inferior a 4 causa problemas, la librería que te adjunte venia en una nueva versión de CCS la cual no había probado además me reconoció sin problemas la instrucción #use delay (internal = 4000000) 

Gracias


----------



## AleSergi (Jun 21, 2013)

Tengo una duda respecto a lo desarrollado en este tema, por ahí nombran la librería "flex_lcd.c", estaban hablando de la "lcd.c" de esta última sé que tiene algunas limitaciones, no se puede elegir libremente la asignación de los pines del micro con las líneas del LCD, si o si deben ir todas las líneas a un mísmo puerto, además las líneas datos 4 bit's, deben ser los bits más significativo del puerto.
Será que en "flex_lcd.c" esta limitación, no existe, y que tambien podría emplear pines de diversos puertos para conectar con el LCD, ¿es asi?, alguien me aclara...


----------



## D@rkbytes (Jun 21, 2013)

Si se pueden modificar en la librería los pines de control y los de datos.
Léela un poco y verás que existen comentarios en ella mencionando lo que se tiene que hacer.

Personalmente yo la he modificado para usar la pantalla por el puerto A y con los pines que yo elija.

Y si, los pines que se usan en configuración de 4 Bits, son los bits más significativos del puerto,
pero también se puede usar por ejemplo RA3, RA2, RA1 y RA0 cómo el bus de datos de 4 Bits.

Saludos.


----------



## IxMagoxI (Ene 16, 2014)

Hola buen dia a todos, como verán acá vuelvo con otro problema con mis queridos pics 

   Esta vez me toco con un pic 16f877a, aclaro que el pic funciona joya, siempre y cuando sea una rutina normal ej prender leds ..., ahora el problema es cuando quiero utilizar un Display de 16x2, declaro todo para el manejo del display.

#include <lcd.c>

#define LCD_DATA_PORT getenv("SFRORTD") 

#define LCD_ENABLE_PIN  PIN_D0                                    ////
#define LCD_RS_PIN      PIN_D1                                    ////
#define LCD_RW_PIN      PIN_D2                                    ////
#define LCD_DATA4       PIN_D4                                    ////
#define LCD_DATA5       PIN_D5                                    ////
#define LCD_DATA6       PIN_D6                                    ////
#define LCD_DATA7       PIN_D7 

    Compila, todo bien, en proteus aclaro que anda, pero al grabar el PIC y querer hacerlo andar, ahí ni siquiera arranca. El display anda porque lo probé con un 16f84a, asi que de a poco fui borrando lineas para ver que onda, y me encontré que al compilar alguna instrucción de la librería del LCD el PIC no arrancaba ej: 

void main()
{
  lcd_gotoxy(1,1);                         
  printf(lcd_putc,"hola");

   while(true)
   {
      output_low(LED);
      delay_ms(DELAY);
      output_high(LED);
      delay_ms(DELAY);
   }

}

si pongo eso en el programa no arranca directamente, pero si borro las lineas que utilizan el lcd " lcd_gotoxy(1,1);  printf(lcd_putc,"hola"); ", el pic arranca y hace parpadear el led 

   El compilador que uso es el CCS " pic c compiler v4.130" y para grabar tengo un pickit2 clone.

   Espero que alguien me pueda dar una mano con esto, mañana voy a seguir probando hasta que ande .... muchas gracias, Saludos a todos .


----------



## D@rkbytes (Ene 17, 2014)

IxMagoxI dijo:


> Hola buen dia a todos, como verán acá vuelvo con otro problema con mis queridos pics
> 
> Esta vez me toco con un pic 16f877a, aclaro que el pic funciona joya, siempre y cuando sea una rutina normal ej prender leds ..., ahora el problema es cuando quiero utilizar un Display de 16x2, *declaro todo para el manejo del display*.


Te falta inicializar la pantalla.
Tampoco es necesario que declares el puerto D y los pines para la pantalla.
Esa configuración es la que usa por defecto el compilador para el 16F877A
En el código tampoco se ven los fuses, el periodo para DELAY, ni que pin escogiste para el LED.

Quizás obviaste esos detalles al subir tu programa, y sólo por probar tu librería compilé tu programa, pero simplificado.

Le cambié el nombre al archivo que subiste por lcd_prueba.c y lo coloqué dentro de la carpeta del proyecto.

```
#include <16f877a.h>
#fuses   NOBROWNOUT
#use     delay(crystal = 4MHz)

#include "[B]lcd_prueba.c[/B]" // [B]Librería bajo prueba[/B]

#define LED PIN_B7
#define DELAY 500

void main()
{
   lcd_init();
      lcd_putc("\fhola");

   while(true)
   {
      output_toggle(LED);
         delay_ms(DELAY);
      }
   }
```
Y físicamente funciona todo sin ningún problema.
Agrega la instrucción *lcd_init();* en el main del código para que funcione tu programa.

Suerte.


----------



## IxMagoxI (Ene 17, 2014)

D@rkbytes dijo:


> Te falta inicializar la pantalla.
> Tampoco es necesario que declares el puerto D y los pines para la pantalla.
> Esa configuración es la que usa por defecto el compilador para el 16F877A
> En el código tampoco se ven los fuses, el periodo para DELAY, ni que pin escogiste para el LED.
> ...



    Hola buen dia D@rkbytes, gracias por contestar, ahi compiler el codigo que me pasaste y solo le fataba arriba de #include <lcd.c> esta linea " #define use_portD_lcd_TRUE " sino me tiraba error, lei por ahi y faltaba esa declaracion, lo programe y salio andando ... igual raro ayer estaba todo y no funcionaba jaja, medio raro pero bue ... 
    Dejo el codigo de como esta funcionando ahora:

-------------main.c--------------------------------------------------------------------


```
#include <main.h>

#define use_portD_lcd_TRUE
#include <lcd.c> // Librería bajo prueba


void main()
{

      lcd_init();
      lcd_gotoxy(1,1);
      printf(lcd_putc,"hola");

   while(true)
   {
      output_toggle(pin_b1);
         delay_ms(200);
      }
   }
```

------------------------main.h--------------------------------------------------

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

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=4000000)
```

Muchas gracias a todos, Saludos.


----------



## juaann (Mar 19, 2014)

Hola estoy haciendo un programita en el cual quiero grabar unas cadenas en variables y luego estas variables sacarlas por la pantalla de LCD pero no puedo lograrlo. Estoy usando CCS

esto es lo que estoy haciendo y no funciona:

unsigned char cadena;

cadena="Texto LCD";

printf(LCD_PUTC, "%s",cadena);


----------



## TRILO-BYTE (Mar 19, 2014)

aver aver aver

deja me desenpolvo en C

tu programa deberia ser asi:

char cadena[10]="un perro"; // darle una longitud a la cadena

printf(lcd_putc,"%s",cadena); //hacer uso de lcd e imprimir la cadena


te explicare como hacer uso del PRINTF en CCS

*PRINTF*

el printf en CCS esta dado del siguiete modo

printf(*funcion con char*,"_cadena con formato_"); 

donde en realidad lo que hace este formato es meter el formato dentro de una funcion que escribe caracter por caracter.

en este caso la funcion sera:* lcd_putc();*
lo que hace esta funcion es imprimir solo 1 caracter
¿que es lo que hace el printf?
solo da formato a la cadena y caracter a caracter lo envia a la funcion *lcd_putc()*

¿como darle formato a una cadena entera?
usando *SPRINTF* como su nombre lo indica es un string printf, lo que hace a diferencia del printf es que da formato a una cadena entera y no caracter a caracter 

¿como la uso?
debo declarar una cadena de caracteres y el sprintf lo que hace es darle formato a mi cadena pero no la imprime en la pantalla por que no estoy mandando llamar * lcd_putc();*

ejemplo:

char cadena[20];
int numero=10;

sprintf(cadena,"Trilobyte = %d",numero);

ahora la cadena de caracteres contiene todo el formato que seria
Trilobyte =10

y si queremos imprimirla en una LCD usariamos el *printf *con su funcion* lcd_putc*

quedaria asi:

printf(lcd_putc,"%s",cadena);
ahora lo que veriamos en la LCD seria :Trilobyte =10

*¿por que saber esto?* 

por que muchos se confunden y creen que el printf sirve para imprimir en la LCD o en el UART
pero en realidad NO en realidad imprimen una cadena con formato o una serie de caracteres con formato.

que se mande llamar una funcion dentro del printf es diferente.

bueno esto es util cuando no usamos CCS y queremos usar la LCD en otro compilador de otro microcontrolador


----------



## juaann (Mar 19, 2014)

Gracias por tu respuesta, pero me pareces que me falto explicar una cosa o no lo explique bien.
Esto es lo que tengo yo:


```
void escLCDProg(pos){
char texto[5];

texto[1]="1-texto1";
texto[2]="2-texto2";
texto[3]="3-texto3";
texto[4]="4-texto4";


             lcd_init();
             lcd_gotoxy(1,1);         //Visualiza en el lcd
             lcd_putc("\f");
             printf(LCD_PUTC, "%s", texto[pos]);
             
   
}
```

Es decir, dependiendo del valor de "pos" que imprima el texto correspondiente en el LCD


----------



## jvk85321 (Mar 19, 2014)

```
printf(LCD_PUTC, "%s", texto[pos]);
```
LCD_PUTC va en minusculas



Adjunto un mini codigo y circuito com sample


```
#include <16F877A.h> 
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT,NODEBUG,NOBROWNOUT,NOCPD,NOWRT 
#use delay(clock=20000000) 
 
#include <LCD.C> 
 
#byte TRISA = 0x85 
#byte PORTA = 0x05 
#byte TRISB = 0x86 
#byte PORTB = 0x06 
 
INT FLAG=0, MEN=0x01, FLAG1=0; 
 
void presentacion() 
{ 
  printf(lcd_putc,"\f CLASE ROBOTICA"); 
  printf(lcd_putc,"\n SEXTO  CONTROL"); 
} 
 
void menu() 
{ 
    switch(MEN) 
    { 
        case 0x01:           //1234567890123456 
            printf(lcd_putc,"\f      MENU      "); 
            printf(lcd_putc,"\n%c   1 LED D4    ",0x7E); 
            if (FLAG1==2) 
            { 
                PORTB=0b00001000; 
                FLAG1=0; 
            } 
            else FLAG1=1; 
      break; 
        case 0x02:           //1234567890123456 
            printf(lcd_putc,"\f    1 LED D4   "); 
            printf(lcd_putc,"\n%c   2 LED D3    ",0x7E); 
            if (FLAG1==2) 
            { 
                PORTB=0b00000100; 
                FLAG1=0; 
            } 
            else FLAG1=1; 
      break; 
        case 0x03:           //1234567890123456 
            printf(lcd_putc,"\f    2 LED D3   "); 
            printf(lcd_putc,"\n%c   3 LED D2    ",0x7E); 
            if (FLAG1==2) 
            { 
                PORTB=0b00000010; 
                FLAG1=0; 
            } 
            else FLAG1=1; 
      break; 
        case 0x04:           //1234567890123456 
            printf(lcd_putc,"\f    3 LED D2   "); 
            printf(lcd_putc,"\n%c   4 LED D1    ",0x7E); 
            if (FLAG1==2) 
            { 
                PORTB=0b00000001; 
                FLAG1=0; 
            } 
            else FLAG1=1; 
      break; 
    }     
} 
 
void teclado(void) 
{ 
  switch((PORTA & 0x3C)) 
  { 
    case 0x20: 
      if (FLAG==1) 
      { 
          FLAG=0; 
          if (FLAG1==1) FLAG1=2; 
          menu(); 
      } 
      else FLAG=1; 
      break; 
    case 0x10: 
      if (FLAG==1) 
      { 
          FLAG=0; 
          if (MEN<5) MEN++; 
          else MEN=0x04; 
          menu(); 
      } 
      else FLAG=1; 
      break; 
    case 0x08: 
      if (FLAG==1)  
      { 
          FLAG=0; 
          if (MEN<5) MEN--; 
          else MEN=0x01; 
          menu(); 
      } 
      else FLAG=1; 
      break; 
    case 0x04: 
      if (FLAG==1) 
      { 
          FLAG=0; 
          presentacion(); 
          PORTB=0b00000000; 
      } 
      else FLAG=1; 
      break; 
  } 
  if (FLAG==1) delay_ms(500); 
} 
 
void main(void) 
{ 
  lcd_init(); 
  TRISA = 0b00111100; 
  TRISB = 0x00; 
  PORTB = 0b00000000; 
  presentacion(); 
  WHILE(TRUE) 
  { 
      teclado(); 
    } 
}
```


----------



## sukakaw (Abr 10, 2014)

hola companeros
tengo problemas con un lcd 20x4 para controlarlo con un pic16f877A, lo que sucede es lo siguiente 
el programa lo compilo con el CCS compiler y lo simulo con proteus hasta este punto se simula y se compila bien, pero cuando lo graba al pic y lo conecto en el protoboard no me muestra ningun mensaje solo se ven las lineas 1 y 3 todos los caracteres en negro.
 para grabar el pic utilizo el master-prog+ (hasta ahora no me habia dado fallas)
adjunto la simulacion y el codigo



aqui estas los archivos


----------



## TRILO-BYTE (Abr 11, 2014)

¿y estas seguro que el protoboard esta bien armado?
luego ese es un factor

el segundo factor 

¿el controlador del LCD es compatible con el que usa el CCS?


----------



## sukakaw (Abr 11, 2014)

el controlador no se si afecte el lcd que utilzo es un AZ DISPLAYS modelo ACM2004D tambien probe un lcd AMPIRE modelo 204A-QW e hizo lo mismo, d aqui me salio otra duda si afecta que lo estoy manejando a 4bitsn adjuto los datos de lcd que manejo
el pic lo conecto como en la imagen del post 93 y el lcd esta configurado en el puerto D tal como esta en la simulacion con proteus

este es el datasheet del lcd


----------



## D@rkbytes (Abr 12, 2014)

sukakaw dijo:


> El controlador no sé si afecte el lcd que utilizo, es un AZ DISPLAYS modelo ACM2004D
> También probé un lcd AMPIRE modelo 204A-QW e hizo lo mismo


La pantalla que estás usando, según la hoja de datos usa el controlador ST7066U-0A y el fabricante del controlador dice que es pin por pin compatible con el HD44780, el KS0066 y el SED1278.
Así que debe tener compatibilidad para trabajar con las librerías 4x20 que existen.

No tengo pantallas de ese tipo para hacer una prueba, pero mira si este ejemplo que adjunto con la librería LCD420.C de CCS modificada para trabajar con el puerto D, te funciona.
Esta librería se tiene que modificar directamente porque viene definida para usar el puerto B por defecto.

Nota que cambia la disposición de los pines de control. Espero te funcione.

Suerte.


----------



## luis1234567890 (May 9, 2014)

Hola a todos,tengo un problema al simular en proteus , no me muestra ningún carácter que envió   en la pantalla lcd 2x16  cuando trabajo con el pic 18f2550 ,pero con otros micros como el 16f877a si se muestra los caracteres que envío . 
No se cual sera el problema .

#include <18f2550.h>
#fuses HSPLL,NOWDT,NOMCLR
#use delay (clock=48000000)
#define use_portb_lcd TRUE
#include <lcd.c>


void main()
{
 lcd_init();
 setup_adc_ports(AN0_ANALOG );//pines digitales
while(true)
{lcd_gotoxy(1,1);
printf(lcd_putc,"PIC18F2550");


}
}


----------



## D@rkbytes (May 9, 2014)

luis1234567890 dijo:


> Hola a todos,tengo un problema al simular en proteus , no me muestra ningún carácter que envió   en la pantalla lcd 2x16  cuando trabajo con el pic 18f2550 ,pero con otros micros como el 16f877a si se muestra los caracteres que envío .
> No se cual sera el problema .
> 
> #include <18f2550.h>
> ...


Debes tener un problema con la palabra de configuración.
¿Estás usando directamente un cristal de 48MHz, u otro?

Como comentario, si únicamente quieres realizar una prueba de escritura, no lo hagas dentro del bucle while.
Puedes empezar a escribir "PIC18F2550" después de lcd_init(); y en el bucle while hacer parpadear un LED a un tiempo conocido para que te des cuenta si el PIC está trabajando a la frecuencia correcta.

Por ejemplo, así:

void main ()
{
lcd_init ();
lcd_putc ("\fPIC18F2550");

while (true)
{
output_toggle (pin_xx);
delay_ms (500);
}
}


----------



## TRILO-BYTE (May 9, 2014)

yo tuve el mismo problema hace años
prueba estas lineas de codigo

#use delay(clock=48M)
#fuses XT,NOWDT,PLL5
#define LCD_DATA_PORT getenv("SFRORTB")
#include <lcd.c>


----------



## luis1234567890 (May 9, 2014)

Hola D@rkbytes ,bueno la programación anterior ya me salio ahorra si me aparece los caracteres que envió ,recién estoy trabajando con el pic18f2550 y estaba pasándo algunos  ejemplos que había hecho con el  pic16.
Bueno cambie el cristal a 20Mhz ya que cuando estaba a 48Mhz no aperecía una letra ("P C18F2550"),pero ahorra para probar con retardos como dices D@rkbytes,cuando quiero hacer un contador de cada un segundo con lcd se demora  y hasta también cuando quiero parpadear un led se demora como 3s  en vez que sea 1s. l


----------



## D@rkbytes (May 9, 2014)

luis1234567890 dijo:


> cuando quiero hacer un contador de cada un segundo con lcd se demora  y hasta también cuando quiero parpadear un led se demora como 3s  en vez que sea 1s.


Sip, por eso te mencioné lo de la palabra de configuración.
Te daré estas para que pruebes, son para subir a 48MHz.:

// Con cristal de 4MHz.
#include <18f2550.h>
#fuses   xtpll,cpudiv1,pll1,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 8MHz.
#include <18f2550.h>
#fuses   hspll,cpudiv1,pll2,nopbaden,nolvp,nofcmen,noieso
#use delay(clock = 48MHz)

// Con cristal de 12MHz.
#include <18f2550.h>
#fuses   hspll,cpudiv1,pll3,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 16MHz.
#include <18f2550.h>
#fuses   hspll,cpudiv1,pll4,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 20MHz.
#include <18f2550.h>
#fuses   hspll,cpudiv1,pll5,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

Eso que te pasa es normal, pues al estar mal la palabra de configuración y estar activo el fuse FCMEN y el fuse IESO, entra automáticamente en funcionamiento el oscilador interno.
Entonces el PIC funciona, pero a la frecuencia que tome OSCCON en el Power On Reset.

Suerte.


----------



## luis1234567890 (May 10, 2014)

Ahora si ya está bien, el led parpadea el tiempo debido y hasta la pantalla lcd anda normal (en simulación no es así ,no se por que?  , ya no le di mucha importancia  ) entonces los fusibles de configuración era el problemas,  bueno muchas gracias .

---------- Actualizado después de 3 horas ----------


Se me presentó otro problema  que recién me he dado cuenta y ni tengo idea por que pasa.
Bueno, como comenté el led parpadea normal, osea el tiempo que le doy, pero ese es solo cuando está alimentado con el programador,  o sea de la  alimentación de la   pc, pero cuando le pongo una fuente DC  a 5v, el  led se queda prendido nada más y no parpadea nada (a veces hace que el  tiempo se demore más).


----------



## D@rkbytes (May 10, 2014)

Lo de la simulación en proteus, es porque al microcontrolador se le pone una frecuencia y a esa corre.
Si la configuración en el programa es para trabajar a 48MHz y en el simulador se ponen 4MHz, si se notan cambios.
En la pantalla LCD las letras aparecen con una secuencia lenta, pero aparecen y los tiempos serán más lentos.

Sobre lo de la alimentación por el puerto USB, debería funcionar de la misma forma que con fuente externa.
Revisa el voltaje del pin 20 VDD (+5V) y que el pin 8 y el 19 estén conectados a VSS (GND).
No se me ocurre otra cosa por la cual funcione de diferente forma.


----------



## juanma2468 (Jun 15, 2014)

Hola gente realice un programa con PIC C Compiler, el cual simulado en proteus funciona de maravillas, pero cuando lo arme en una placa no funciona el LCD, lo simule con otro programa (PIC Simulador IDE) y descubri que si pongo el LCD en modo de 4 bits activo alto funciona, por lo que mi LCD debe ser activo bajo, como hago en PIC C Compiler para hacer que los datos por el puerto B sean activos bajo?. Desde ya muchas gracias.

```
#include <16F88.h> // Declaro el microcontrolador que voy a utilizar
#device ADC=10
#fuses intRC_io,nowdt,nobrownout,noprotect,noput,nolvp,nomclr // Declaro la palabra de configuración del microcontrolador: 
                                                              // Osc. Interno, NoWatchDog, NoBrownOut, NoProtect, NoPowerUpTime, 
                                                              // NoLowVoltageProgramming, NoMasterClear
#use delay(int=4000000)
#include <lcd.c> // Incluyo la libreria LCD para manejar la pantalla
#define use_portB_lcd TRUE // Defino el puerto B para utilizar el LCD
#use fast_io(a) // Optimiza el código que genera para programar los puertos
#byte ADCON0 = 0x1F // Declaro el registro ADCON0
#byte ADCON1 = 0x9F // Declaro el registro ADCON1
#byte ADRESH = 0x1E // Declaro el registro ADRESH
#byte ADRESL = 0x9E // Declaro el registro ADRESL

// Variables

float Conversion,Distancia, ValMin = 0;

void Inicializacion(void)
{
   setup_adc_ports(sAN0|vss_vdd);
   setup_adc(adc_clock_internal);
   set_tris_a(0b10000001); // Como entrada A0 y el resto como salidas
   //set_tris_b(0b00000000); // Todo el puerto como salidas
   //ADCON1 = 0b10000000;
   //ADCON0 = 0b11000001;
   
}

void main()
{
   delay_ms(100); // Delay de 100 mseg
   Inicializacion(); // Inicializo el microcontrolador
   lcd_init(); // Inicializo el LCD
   delay_ms(50); // Delay de 50 mseg.
   printf(lcd_putc, "\f - SIMULICAR - ");
   printf(lcd_putc, "\nMEDIDOR CALIBUR");
   delay_ms(2000);
   set_adc_channel(0);
   for(;;)
   {
   Conversion = read_adc();
   Distancia = (5*Conversion)/1023;
   if (ValMin<Distancia)
   {
      ValMin = Distancia;
   }
   lcd_gotoxy(1,1);
   printf(lcd_putc, "VA ACT = %fcm", Distancia);
   lcd_gotoxy(1,0);
   printf(lcd_putc, "VA MIN = %fcm", ValMin);
   if ((input(PIN_A7)==TRUE))
   {
      if (Distancia==0.00)
      {
         ValMin = 0;
      }
   }
   }
}
```
--------------------------------Actualización-------------------------------
Ya resolvi el problema y creo que esto puede ser una ayuda para otras personas a las que le haya pasado lo mismo que a mi. El problema estaba en que la pata R/W de mi LCD yo la había puesto a masa ya que pensaba que solo realizaría escrituras, pero me di cuenta que las rutinas no solo escriben, si no que además luego leen lo que escriben ya que por un instante los pines que estaban puestos como salida se hacen entradas y luego se vuelven a hacer salidas. En mi caso tambien descubrí que el micro se colgaba, eso era seguramente porque intentaría leer lo que escribió para hacer algun tipo de comparación. Simplemente con mandar la pata R/W del LCD al pin RB2 del micro el LCD salió andando sin problemas. Este problema no se manifiesta en el simulador, que es quizas lo que le pudo haber pasado a varias personas. saludos.


----------



## jaochoam (Dic 18, 2014)

buen dia ojala alguien puediara apoyarme con mi proyecto, tengo un problema uno o varios problemas, este proyecto me iva bien con el 16f877a pero se me termino la memoria, y me vi en la necesidad de migrarlo a un pic18f4550. pero no logro hacerlo arrancar, siempre he tenido problemas con la lcd20x4, aqui en este foro me la pasaron y es la que anexo en el proyecto. quiero suponer que las frecuencias son las que me estan mantando.


----------



## D@rkbytes (Dic 18, 2014)

jaochoam dijo:


> Quiero suponer que las frecuencias son las que me estan mantando.


Sip, porque estás usando la librería modificada para trabajar a 48MHz.
Debiste usar la original o la que te mencioné anteriormente para usar el puerto D. Librería lcd420.c en puerto D

También debes cambiar la palabra de configuración, pues para trabajar a 4MHz, no estás usando la adecuada.
Usa esta:

```
#fuses NOBROWNOUT,NOIESO,NOFCMEN,NOLVP,NOVREGEN

#use delay(crystal = 4 MHz)
```
Prueba reemplazando la librería por la del enlace y cambia la palabra de configuración.


----------



## jaochoam (Dic 18, 2014)

ya hice lo que me comentaste y no funciona D@rkbytes, me aparece lo mismo, no aparece nada en la lcd y la información que envía por la rs232 no corresponden a los adc, en uno de los intentos que realice me percate que al no usar las directivas    setup_adc_ports(all_analog); setup_adc(ADC_CLOCK_INTERNAL); si enciende la lcd. no se si el tiempo de conversión de los adc no sea compatible con la frecuencia.


----------



## D@rkbytes (Dic 18, 2014)

Algo hiciste mal entonces, porque acabo de reemplazar la librería y la palabra de configuración, y si funciona.
La pantalla muestra valores en 0, no sé por qué, y la salida RS-232 muestra algunos valores, no se logra saber bien que valores por lo rápido que aparecen, pero si se ve algo.

Aquí adjunto el proyecto con los cambios mencionados.

Al menos ya con con esos cambios podrás determinar los problemas.


----------



## jaochoam (Dic 18, 2014)

muchas gracias D@rkbytes, una vez mas te lo agradezco. voy a estudiar a fondo los fuses y frecuencias en general. y para comenzar me podrias resolver una duda. en este mismo foro colocaste sintaxis en la palabra de configuracion para diferentes frecuencias al trabajar con una u otra frecuencia en los fuses y cristales tambien tengo que modificar la libreria de la lcd o ni al caso. 
me refiero a estas configuraciones
// Con cristal de 4MHz.
#include <18f2550.h>
#fuses xtpll,cpudiv1,pll1,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 8MHz.
#include <18f2550.h>
#fuses hspll,cpudiv1,pll2,nopbaden,nolvp,nofcmen,noieso
#use delay(clock = 48MHz)

// Con cristal de 12MHz.
#include <18f2550.h>
#fuses hspll,cpudiv1,pll3,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 16MHz.
#include <18f2550.h>
#fuses hspll,cpudiv1,pll4,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)

// Con cristal de 20MHz.
#include <18f2550.h>
#fuses hspll,cpudiv1,pll5,nobrownout,nopbaden,nolvp
#use delay(clock = 48MHz)


----------



## D@rkbytes (Dic 19, 2014)

jaochoam dijo:


> Muchas gracias D@rkbytes, una vez mas te lo agradezco. Voy a estudiar a fondo los fuses y frecuencias en general.


De nada. 


jaochoam dijo:


> Y para comenzar, ¿me podrías resolver una duda?
> En este mismo foro colocaste sintaxis en la palabra de configuración para diferentes frecuencias.
> ¿Al trabajar con una u otra frecuencia en los fuses y cristales también tengo que modificar la librería de la lcd o ni al caso?


La librería original puede trabajar bien hasta 20MHz, para frecuencias mayores, ya debes usar la librería modificada.


----------



## jaochoam (Dic 22, 2014)

buen dia D@rkbytes tengo un problema referente a este mismo proyecto, me funciona ala perfeccion el .hex que viene en el proyecto que me enviaste funcionando pero al siquiera compilarlo sin ninguna modificacion me devuelve todo el problema inicial.


----------



## D@rkbytes (Dic 22, 2014)

jaochoam dijo:


> Me funciona ala perfección el .hex que viene en el proyecto que me enviaste funcionando pero al siquiera compilarlo sin ninguna modificación me devuelve todo el problema inicial.


OK. Entonces si al compilar el programa ya no se muestra nada en la pantalla, tienes que actualizar PIC C Compiler. (Algunas versiones, no recuerdo bien cuales pero alrededor de "v4.13X" tuvieron éste problema.)
Actualmente existe un problema con las nuevas versiones 5.02X.
El problema surge cuando se hace uso de la instrucción port_x_pullups();
Si ésta instrucción se coloca antes de inicializar la pantalla "lcd_init();", ya no se ve nada después en la pantalla.
Entonces se tiene que colocar port_x_pullups(); después de ésta instrucción.

Si es alguno de éstos casos, eso puede ser la solución.


----------



## jaochoam (Dic 22, 2014)

si no es mucha indiscrecion cual version de picc me recomiendas


----------



## D@rkbytes (Dic 23, 2014)

jaochoam dijo:


> Si no es mucha indiscreción, ¿cuál versión de picc me recomiendas?


Siempre es bueno tener las nuevas versiones ya que se van mejorando cosas y corrigiendo errores.
Ahora va por la 5.034, pero necesitas ser _usuario registrado_ para acceder a las actualizaciones.


----------



## jaochoam (Dic 23, 2014)

buen dia D@rkbytes, ya actualice el pic c compiler y todo bien, pero ahora estoy estudiando los fuses y probando con el pic18f452 los fusibles cambian. de los que tenia configurado el 18f4550 los fuses FCMEN, IESO,VREGEN no los soporta, lo compilo con los que si soporta y no funciona.



ya resolvi mi problema D@rkbytes, ya me da pena de estar moleste y moleste, gracias por todo


----------



## Fabio Rengifo (Feb 7, 2015)

Buen dia;
Estoy haciendo un proyecto en el cual uso 5 lcd´s (16x2) cada uno con su pic (16f873A), los pic's tienen todos el mismo programa y el mismo circuito de conexión, el problema es que para el proyecto tenia 2 lcd's en stock y compre los otros 3, al probarlos los 2 antiguos son más tenues que los nuevos (son todos azules), y al momento de conectarlos al circuito funcionan bien luego de un rato y luego empiezan a desvanecerse las letras pero solo en los lcd's nuevos, los viejos funcionan muy bien, intercambio de circuitos, de pic's pero pasa igual (los nuevos  y los viejos  ) para el contraste les puse una resistencia fija de 3.3Kohm, para todos los circuitos y como dije anteriormente todos inicialmente funcionan bien, pero solo los nuevos se desvanecen. Agradezco su colaboración.


----------



## juanma2468 (Feb 7, 2015)

Se me hace que estan flojas las gomas conductoras de los LCD y por eso se desvanecen. Para solucionarlo pides desajustar las travitas negras que apretan el marco contra la placa, volver a presionar la pantalla ejerciendo algo de presion sin dañarla y volver a ajustarlas. Si persiste tendras que desarmarla por completo y limpiar los contactos donde apoyan las gomas conductoras y las gomas conductoras tambien con alcohol isopropilico, volver armar y probar.


----------



## yenz (Feb 22, 2015)

Hola comunidad foros de electrónica.
Me gustaría que me ayudaran a visualizar el estado off/on de 8 led que es lo me a hace falta ami código a y tengo algunos errores de visualización.
su ayuda me sería de gran aprecio  ya que no se mucho de programación.
les adjunto la simulación en proteus y la programación en c.

Este es el programa en c disculpen por lo extenso del código.




```
#include <16f877a.h>
#use     delay(crystal = 4MHz)

#define use_portb_kbd TRUE
#include <KBD96.c>
#include <LCD420.c>
#include <stdlib.h>

#define  LED_1  PIN_D0
#define  LED_2  PIN_D1
#define  LED_3  PIN_D2
#define  LED_4  PIN_D3
#define  LED_5  PIN_D4
#define  LED_6  PIN_D5
#define  LED_7  PIN_D6
#define  LED_8  PIN_D7

#define ENTRADA1 PIN_C0
#define ENTRADA2 PIN_C1
#define ENTRADA3 PIN_C2
#define ENTRADA4 PIN_C3
#define ENTRADA5 PIN_C4
#define ENTRADA6 PIN_C5

void mostrar_menu(){
lcd_gotoxy(3,1);
printf(lcd_putc,"\fMENU PRINCIPAL\r");
lcd_gotoxy(1,2);
printf(lcd_putc," 0 Estado Entradas");
lcd_gotoxy(1,3);
printf(lcd_putc," * Control Salidas");
}

void funcion_led_1()
{
   output_toggle(LED_1);
}

void funcion_led_2()
{
   output_toggle(LED_2);
}

void funcion_led_3()
{
   output_toggle(LED_3);
}

void funcion_led_4()
{
   output_toggle(LED_4);
}

void funcion_led_5()
{
   output_toggle(LED_5);
}

void funcion_led_6()
{
   output_toggle(LED_6);
}

void funcion_led_7()
{
   output_toggle(LED_7);
}

void funcion_led_8()
{
   output_toggle(LED_8);
}

void funcion_lectura_entradas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"INPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}

void main () 
{
CHAR k;

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);
 
   output_low(LED_1),(LED_2),(LED_3),(LED_4),(LED_5),(LED_6),(LED_7),(LED_8);
   printf(lcd_putc,"\fBienvenidos (^^,)\r\rPulsa # para ir menu");

   while (true)
   {
      k = kbd_getc();
      
      if (k!=0)
         switch(k)
         {
         case '0':
            funcion_lectura_entradas();
            break;
         case '1':
            funcion_led_1();
            break;    // Brake ya no se coloca al final de la selección.
         case '2':
            funcion_led_2();
            break;
            case '3':
            funcion_led_3();
            break;
            case '4':
            funcion_led_4();
            break;
            case '5':
            funcion_led_5();
            break;
            case '6':
            funcion_led_6();
            break;
            case '7':
            funcion_led_7();
            break;
            case '8':
            funcion_led_8();
            break;
            case '#':
            mostrar_menu();
            break;  
         }
   }
}
```


----------



## anderson torres (Feb 22, 2015)

En si, que es lo que no trabaja?


----------



## yenz (Feb 22, 2015)

gracias anderson por preguntar
la visualización de los 8 led en la lcd
me gustaría ver cuando estén encendidos o apagados


----------



## anderson torres (Feb 22, 2015)

En una LCD 4X20, debes construir tus propios caracteres e importarlos a la GRAM de la lcd.

Para generar caracteres puedes utilizar este programa, que es totalmente gratuito
Solo debes construir el caracter, que quieres que se muestra cuando esta encendido,y  se va generar un codigo  en c, este lo debes copiar y pegar en tu codigo.





Y este es otro que trabaja de la misma manera


----------



## yenz (Feb 23, 2015)

Muchas gracias, Anderson.
Voy hacer un mensaje de bienvenida y cuando ejecute el programa salga la imagen de Microchip y Xbee q*ue* son los dispositivos que estoy trabajando.



También modifiqu*é *un poco mi código*.*
*I*nicia un saludo dentro al menú con # y muestra que con cero miramos el estado de las entradas puerto c y del 1 al 8 control prende y apaga los led.
*P*ero me parece muy ineficiente*.* *M*e gustaría organizarlo mejor con la ayuda de ustedes.


----------



## anderson torres (Feb 23, 2015)

yenz dijo:


> Muchas gracias, Anderson.
> Voy hacer un mensaje de bienvenida y cuando ejecute el programa salga la imagen de Microchip y Xbee q*ue* son los dispositivos que estoy trabajando.
> 
> 
> ...


No tienes una simulación de tu proyecto para yo probarlo en mi PC!


----------



## yenz (Mar 5, 2015)

Si que pena tuve algunos inconvenientes con mi torpeza pero ojala no los vuelva a cometer, mis disculpas al foro y a todos ustedes.
Trabaje toda la semana en mi proyecto y tengo un problema con un while (TRUE) que le adicione a mi código para que se estuviera preguntando por el estado de la entrada cuando se oprimiera el pulsador mostrara el cambio en la lcd en el mismo instante eso creo un bucle infinito en el cual no pudo salir para poder regresar a menú o encenderlos led que tengo en el (port D) las entradas las tengo por el (port C).
Les adjunto el código y la simulación en proteus.

```
#include <16f877a.h>
#use     delay(crystal = 4MHz)

#define use_portb_kbd TRUE
#include <KBD96.c>
#include <LCD420.c>
#include <stdlib.h>

#define  LED_1  PIN_D0
#define  LED_2  PIN_D1
#define  LED_3  PIN_D2
#define  LED_4  PIN_D3
#define  LED_5  PIN_D4
#define  LED_6  PIN_D5
#define  LED_7  PIN_D6
#define  LED_8  PIN_D7

#define ENTRADA1 PIN_C0
#define ENTRADA2 PIN_C1
#define ENTRADA3 PIN_C2
#define ENTRADA4 PIN_C3
#define ENTRADA5 PIN_C4
#define ENTRADA6 PIN_C5

void mostrar_menu(){
lcd_gotoxy(3,1);
printf(lcd_putc,"\fMENU PRINCIPAL\r");
lcd_gotoxy(1,2);
printf(lcd_putc,"0 ESTADO PUERTO C ");
lcd_gotoxy(1,3);
printf(lcd_putc,"1,2,3,4,5,6,7,8");
lcd_gotoxy(1,4);
printf(lcd_putc,"CONTROL OFF/ON DE LED");
}

void funcion_led_1(){
output_toggle(LED_1);
   if (input_state(LED_1))
 printf(lcd_putc,"\fLed 1 encendido");
   else
 printf(lcd_putc,"\fLed 1 apagado");
}

void funcion_led_2(){
output_toggle(LED_2);
   if (input_state(LED_2))
printf(lcd_putc,"\fLed 2 encendido");
   else
printf(lcd_putc,"\fLed 2 apagado");
}
void funcion_led_3(){
output_toggle(LED_3);
   if (input_state(LED_3))
printf(lcd_putc,"\fLed 3 encendido");
   else
printf(lcd_putc,"\fLed 3 apagado");
}


void funcion_led_4(){
output_toggle(LED_4);
   if (input_state(LED_1))
printf(lcd_putc,"\fLed 4 encendido");
   else
printf(lcd_putc,"\fLed 4 apagado");
}

void funcion_led_5(){
output_toggle(LED_5);
   if (input_state(LED_5))
printf(lcd_putc,"\fLed 5 encendido");
   else
printf(lcd_putc,"\fLed 5 apagado");
}

void funcion_led_6(){
output_toggle(LED_6);
   if (input_state(LED_6))
printf(lcd_putc,"\fLed 6 encendido");
   else
printf(lcd_putc,"\fLed 6 apagado");
}

void funcion_led_7(){
output_toggle(LED_7);
   if (input_state(LED_7))
printf(lcd_putc,"\fLed 7 encendido");
   else
printf(lcd_putc,"\fLed 7 apagado");
}

void funcion_led_8(){
output_toggle(LED_8);
   if (input_state(LED_8))
printf(lcd_putc,"\fLed 8 encendido");
   else
printf(lcd_putc,"\fLed 8 apagado");
}

void funcion_lectura_entradas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}

void main () 
{
CHAR k;

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);
 
   output_low(LED_1),(LED_2),(LED_3),(LED_4),(LED_5),(LED_6),(LED_7),(LED_8);
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Bienvenidos (^^,)");
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Pulsa # para ir menu");
   
   while (kbd_getc()!='#'){};
   mostrar_menu();

   while (true)
   {
      k = kbd_getc();
      
      if (k!=0)
         switch(k)
         {
         case '0':
   while (TRUE){
            delay_ms(500);
            funcion_lectura_entradas();
            k = kbd_getc();
            if (k!=0)
            break;
   }
         case '1':
            funcion_led_1();
            break;    // Brake ya no se coloca al final de la selección.
         case '2':
            funcion_led_2();
            break;
            case '3':
            funcion_led_3();
            break;
            case '4':
            funcion_led_4();
            break;
            case '5':
            funcion_led_5();
            break;
            case '6':
            funcion_led_6();
            break;
            case '7':
            funcion_led_7();
            break;
            case '8':
            funcion_led_8();
            break; 
            case '#':
            mostrar_menu();
            break;
         }
   }
}
```


----------



## juanma2468 (Mar 6, 2015)

Pues no lo chusmie a fondo, pero creo que el segundo while(TRUE) esta de mas, ya que con la funcion swich te quedas esperando para ver a que caso saltar, en todo caso si quieres volver al sensado tendrias que ponerlo mas arriba, otra opcion seria hacer uso del repeat.


----------



## yenz (Mar 6, 2015)

juanma2468 dijo:


> Pues no lo chusmie a fondo, pero creo que el segundo while(TRUE) esta de mas, ya que con la funcion swich te quedas esperando para ver a que caso saltar, en todo caso si quieres volver al sensado tendrias que ponerlo mas arriba, otra opcion seria hacer uso del repeat.



gracias juanma por explicarme el error, entonces la solución estaría en poner el repeat en el void funcion_lectura_entradas() que puse para revisar las entradas las actualizaría en milisegundos para ver el cambio cuando se pulse.


```
void funcion_lectura_entradas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}
```
Me podarías dar un ejemplo es que no pude solucionarlo.


----------



## yenz (Mar 12, 2015)

Hola  gracias por su ayuda e avanzado enormemente pero algo no me funciona bien que no pude solucionar.

Resulta que en mi código cuando oprimo 'C' reviso las entradas con visualización su estado si están en 0 y 1 normalmente funciona pero me di cuenta que no se actualizaba el estado de la entrada hasta que se volviera a oprimir 'C'. Comencé a
buscar la solución pero se me complico generando errores.

Con un while (TRUE) que le adicione en el case 'C' para que se estuviera preguntando por el estado de la entrada y cuando se oprimiera el pulsador mostrara el cambio al instante en la lcd, pero eso creo un bucle infinito en el cual no pude salir para poder regresar a menú o encender los led que tengo en el (port D).
Esto le adicione pero lo elimine.

```
switch(k)
         {
         case 'C':
   while (TRUE){
            delay_ms(500);
            funcion_lectura_entradas();
            k = kbd_getc();
            if (k!=0)
            break;
   }
```

Después me recomendaron poner un REPEAT mas arriba del void pero la verdad no encontré ningún ejemplo para esa función.
Estoy realizando un menú y sub menú e llegado a este punto gracias a todos ustedes gracias por su ayuda. 


```
#include <16f877a.h>
#use     delay(crystal = 4MHz)

#define  LCD_ENABLE_PIN PIN_A0
#define  LCD_RS_PIN     PIN_A1
#define  LCD_RW_PIN     PIN_A2
#define  LCD_DATA4      PIN_B4
#define  LCD_DATA5      PIN_B5
#define  LCD_DATA6      PIN_B6
#define  LCD_DATA7      PIN_B7

#include "lcd420ap.c"
#include <kbd_lib.c>

#define  LED_1  PIN_D0
#define  LED_2  PIN_D1
#define  LED_3  PIN_D2
#define  LED_4  PIN_D3
#define  LED_5  PIN_D4
#define  LED_6  PIN_D5
#define  LED_7  PIN_D6
#define  LED_8  PIN_D7

#define ENTRADA1 PIN_C0
#define ENTRADA2 PIN_C1
#define ENTRADA3 PIN_C2
#define ENTRADA4 PIN_C3
#define ENTRADA5 PIN_C4
#define ENTRADA6 PIN_C5

void mostrar_menu(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\f>A ENTRADA ANALOGICA\r");
lcd_gotoxy(1,2);
printf(lcd_putc,">B CONTROL PWM");
lcd_gotoxy(1,3);
printf(lcd_putc,">C ENTRADAS DIGITALES");
lcd_gotoxy(1,4);
printf(lcd_putc,">D SALIDAS DIGITALES");
}

void funcion_lectura_entradas_analogas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fpendiente entradas");
lcd_gotoxy(1,2);
printf(lcd_putc,"analoga y visualizar");
}

void funcion_pwm(){
printf(lcd_putc,"\fpendiente el PWM");
}

void funcion_control_salidas_digitales(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fFalta panel de");
lcd_gotoxy(1,2);
printf(lcd_putc,"Control para los led");
}

void funcion_led_1(){
output_toggle(LED_1);
   if (input_state(LED_1))
 printf(lcd_putc,"\fLed 1 encendido");
   else
 printf(lcd_putc,"\fLed 1 apagado");
}

void funcion_led_2(){
output_toggle(LED_2);
   if (input_state(LED_2))
printf(lcd_putc,"\fLed 2 encendido");
   else
printf(lcd_putc,"\fLed 2 apagado");
}

void funcion_led_3(){
output_toggle(LED_3);
   if (input_state(LED_3))
printf(lcd_putc,"\fLed 3 encendido");
   else
printf(lcd_putc,"\fLed 3 apagado");
}

void funcion_led_4(){
output_toggle(LED_4);
   if (input_state(LED_1))
printf(lcd_putc,"\fLed 4 encendido");
   else
printf(lcd_putc,"\fLed 4 apagado");
}

void funcion_led_5(){
output_toggle(LED_5);
   if (input_state(LED_5))
printf(lcd_putc,"\fLed 5 encendido");
   else
printf(lcd_putc,"\fLed 5 apagado");
}

void funcion_led_6(){
output_toggle(LED_6);
   if (input_state(LED_6))
printf(lcd_putc,"\fLed 6 encendido");
   else
printf(lcd_putc,"\fLed 6 apagado");
}

void funcion_led_7(){
output_toggle(LED_7);
   if (input_state(LED_7))
printf(lcd_putc,"\fLed 7 encendido");
   else
printf(lcd_putc,"\fLed 7 apagado");
}

void funcion_led_8(){
output_toggle(LED_8);
   if (input_state(LED_8))
printf(lcd_putc,"\fLed 8 encendido");
   else
printf(lcd_putc,"\fLed 8 apagado");
}

void funcion_lectura_entradas_digitales(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}

void main () 
{
CHAR k;

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);
   output_low(LED_1),(LED_2),(LED_3),(LED_4),(LED_5),(LED_6),(LED_7),(LED_8);
   lcd_gotoxy(2,2);
   printf(lcd_putc,"Bienvenidos  (^^,)");
   lcd_gotoxy(1,3);
   printf(lcd_putc,"Pulsa # para ir menu");
   
   while (kbd_getc()!='#'){};
   mostrar_menu();

   while (true)
   {
      k = kbd_getc();
      
      if (k!=0)
         switch(k)
         {
         case 'A':
            funcion_lectura_entradas_analogas();
           break;
         case 'B':
            funcion_pwm();
            break;
         case 'C':
            funcion_lectura_entradas_digitales();
           break;
         case 'D':
            funcion_control_salidas_digitales();
           break;
         case '1':
            funcion_led_1();
            break;
         case '2':
            funcion_led_2();
           break;
         case '3':
            funcion_led_3();
           break;
         case '4':
            funcion_led_4();
            break;
         case '5':
            funcion_led_5();
           break;
         case '6':
            funcion_led_6();
           break;
         case '7':
            funcion_led_7();
           break;
         case '8':
            funcion_led_8();
           break; 
         case '#':
            mostrar_menu();
           break;
         }
   }
}
```


----------



## D@rkbytes (Mar 12, 2015)

yenz dijo:


> Resulta que en mi código cuando oprimo 'C' reviso las entradas con visualización su estado si están en 0 y 1 normalmente funciona pero me di cuenta que no se actualizaba el estado de la entrada hasta que se volviera a oprimir 'C'.
> Comencé a buscar la solución pero se me complico generando errores.


¿Y si lo haces por medio de interrupciones?
Por ejemplo, las del puerto B por cambio de estado en RB4:RB7.

Adjunto un ejemplo que no realiza exactamente lo de tu programa, pero es similar y te puede dar ideas.


----------



## yenz (Mar 13, 2015)

Gracias D@rkbytes este ejemplo es exactamente el giro que necesita mi programa mil gracias


----------



## faberfree (Abr 4, 2015)

hola amigos, tengo un problema con la libreria FLEX_LCD.c  como hago para limpiar la pantalla del LCD despues de haber escrito unas lineas  o como borrar una de las lineas y escribir algo nuevo, porque lo intento hacerlo y se escribe encima .... uso pic ccs , que comando tengo que usar ???? o que codigo me permite borrar esas lineas escritas??.... gracias


----------



## D@rkbytes (Abr 4, 2015)

Si vas a mostrar una valor numérico, puedes usar *%0x* donde x es la cantidad de dígitos a mostrar.
Pero no escribas *%x*, porque eso no define la cantidad de dígitos.

Por ejemplo: *printf(lcd_putc,"Valor: %04lu",cantidad);* // Muestra una cifra de 4 dígitos.

PD:
Por defecto todos los puertos son entradas, así que los set_tris_x(0b11111111); salen sobrando.

Esto no tiene caso:


```
set_tris_b(0b11111111);        //Todo el puerto B como entradas.
   set_tris_c(0b11111111);        //Todo el puerto C como entradas.
```

Y toda esta configuración inicial tampoco sirve de nada, pues no estás usando esos módulos.


```
port_b_pullups(FALSE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   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);
```

Todo eso no es necesario que lo tengas en tu proyecto.

Si después piensas usar alguno de eso módulos, ya lo puedes usar y configurar.
Y te conviene usar las resistencias pull-up del puerto B para los encoders, y no deshabilitarlas.

Suerte.


----------



## faberfree (Abr 6, 2015)

D@rkbytes hola digame por favor si puede decirme como limpiar las lineas en un lcd cuando estas ya han sido escritas??? osea quiero que siga saliendo nuevos mensajes en las lineas pero las anteriores no se como limpiarlas o borrarlas 

uso como libreria el archivo c flex_lcd.c 
alguna sugerencia por favor ? le adjunto el archivo flex_lcd  y parte del codigo como ejemplo que estoy desarrollando.


```
include <16f877a.h>
#include <flex_lcd.c>

#fuses XT, NOWDT , NOPROTECT,NOPUT,BROWNOUT,NOLVP,NOCPD,NOWRT
#use delay (clock=4000000)
//#use fast_io(B)// usa el puerto B no define en la posicion de memoria 
//#use standard_io(b)// confi el micro dela mejor manera
//#use standard_io(a) 

void main(){

  lcd_init();
  delay_ms(10);
while(1){
   lcd_gotoxy(1,1);
   lcd_putc("RENZO LCD");
   lcd_gotoxy(1,2);
   lcd_putc("Prueba de CoD");
   delay_ms(2000);
   printf(lcd_putc,"f " ) ;
   lcd_gotoxy(1,1);
   delay_ms(10);
   lcd_putc("Upp....Tronic");

}


}
```


----------



## D@rkbytes (Abr 6, 2015)

Para limpiar la pantalla se usa: *"\f"*

Esto viene explicado el la librería "*lcd.c*" de PIC C Compiler:
*lcd_init() *  Must be called before any other function.
*\a*  Set cursor position to upper left
*\f*  Clear display, set cursor to upper left
*\n*  Go to start of second line
*\b*  Move back one position
*lcd_gotoxy(x,y)* Set write position on LCD (upper left is 1,1)
*lcd_getc(x,y)*   Returns character at position x,y on LCD
*lcd_cursor_on(int1 on) *  Turn the cursor on (on=TRUE) or off (on = FALSE)
*lcd_set_cgram_char(w, *p)*   Write a custom character to the CGRAM.

Y algunos de esos comandos como: (*\f*) también sirven para la librería "*flex_lcd.c*"


			
				flex_lcd.c dijo:
			
		

> void lcd_putc(char c)
> {
> switch(c)
> {
> ...


----------



## faberfree (Abr 6, 2015)

D@rkbytes MUCHAS  gracias amigo... yo vengo del codigo Ansi C y con el compilador HITECH alli era poner LCD_CLEAR() O LCD_puts("    ") Y LISTO , entonces se me hacia algo difícil ahora entender y aprender los mandos en PIC CCS , había visto lo que me indicabas pero no sabia como ponerlo para que me de resultado, bueno haciendo pruebas con el código ejemplo que puse y tus indicaciones entendí mejor como usarlo para pic ccs ,

 reitero mis agradecimientos y si cause alguna molestia disculpa pues pense que habia puesto mi aviso en el foro indicado no me percate que decia arduino en esa seccion  , disculpas nuevamente, y gracias por todo (Y)


----------



## ArturoRR2D2 (Jun 29, 2015)

Hola buenos dias n.n, soy nuevo en esto de programar y mi programa si compila pero al momento que lo simulo en proteus no realiza nada, no se si me podrian ayudar de ante mano gracias,( el programa esta a la mitad solo quiero que el valor medido sea visible en el lcd)

```
#include <16f877a.h>
#use delay(clock=4000000)
#include <LCD.C>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use standard_io(b)


int valor=0x00;

void toma_adc(void){

// Lectura del canal 0
set_adc_channel(0);
delay_ms(1);
valor=read_adc();
delay_ms(1); //para que se estabilice
}



void main()
{
float x;

setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(RA0_analog); //entrada 0 como analogica

   while(true);
   {
   toma_adc();
   output_b(valor);
   
   lcd_init();
   
   for (;;) {
   set_adc_channel(0);  
    delay_us(400);
    x = read_adc();                 
   delay_us(400);
  lcd_gotoxy(1,1);
  printf(lcd_putc, "\\f Voltaje= %6ld",x);
  delay_ms(100);
   }
}
}
```







 ...


----------



## TRILO-BYTE (Jun 29, 2015)

muy facil


```
#include <16f877a.h>
#use delay(clock=4000000)
#include <LCD.C>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use standard_io(b)


int16 valor=0;

void toma_adc(void){

// Lectura del canal 0
//set_adc_channel(0);
delay_us(20);
valor=read_adc();
//delay_ms(1); //para que se estabilice
}



void main()
{
float x;

setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(RA0_analog); //entrada 0 como analogica
set_adc_channel(0);  

lcd_init();

   while(true);
   {
   toma_adc();
   output_b(valor);
   
   
   
   //for (;;) {   // este bucle infinito no va ya fue declarado en el while true 
   //set_adc_channel(0);  
   // delay_us(400);
    x = read_adc();                 
   delay_us(400);
  lcd_gotoxy(1,1);
  printf(lcd_putc,"\f Voltaje= %6ld",x);
  delay_ms(100);
   //}
}
}
```


----------



## D@rkbytes (Jun 29, 2015)

ArturoRR2D2 dijo:


> mi programa si compila, pero al momento que lo simulo en proteus, no realiza nada


Ese programa está muy mal, parte ya lo corrigió TRILO-BYTE, pero aún tiene un problema por el cual nunca llegará a mostrarse nada en la pantalla.

En esta parte se genera un bucle que no permitirá que el programa continúe:

```
while(true);
   {
   toma_adc();
   ...
```
Ten en cuenta que si la instrucción *while (true);* termina con punto y coma, se genera un bucle sin fin en si misma.
Ese es el problema principal de tu programa, los otros, es la forma en que estás usando las variables.

*int* equivale a  una variable de 16 bits y el puerto B tan sólo es de 8 bits.
*x* es una variable del tipo Float y se debe mostrar por ejemplo, así para dos decimales a la derecha: *%0.2f*

También debes especificar con cuantos bits va a funcionar el ADC, ya que por defecto el compilador establece 8 bits.
Esto se hace en la cabecera del programa, escribiendo por ejemplo: *#device ADC **= 10* // 10 Bits

El programa que realizaste es básico, pero aquí te lo dejo funcional y de forma simplificada.

```
#include <16f877a.h>
#device  adc = 8
#use     delay(crystal = 4MHz)
#include <lcd.c>

void main()
{
   int8 valor;
   float x;

   setup_adc(ADC_CLOCK_INTERNAL);   // Usar el reloj interno para el ADC
   setup_adc_ports(AN0);            // Establecer el canal 0
   set_adc_channel(0);              // Seleccionar el canal 0
   delay_us(50);                    // Retardo de 50 us.

   lcd_init();                      // Inicializar la pantalla.
   
   while(true)                      // Iniciar el bucle principal.
   {
      valor = read_adc();           // Leer el canal 0 (Canal seleccionado anteriormente)
      
      output_b(valor);              // Puerto B = valor de "valor" (8 Bits)

      x = (valor * 5.0 / 256);      // Realizar una conversión para determinar el voltaje de entrada.        
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Voltaje = %0.2f",x);
      delay_ms(100);
   }
}
```
Suerte.


----------



## TRILO-BYTE (Jun 29, 2015)

si vi los errores pero como andaba algo ocupado dije ya se va asi sin corregir pero si hay que quitar todas esas redundancias de el programa


----------



## BELTRANCESAR (Oct 14, 2015)

Saludos a todos.
Estoy tratando de visualizar unas variables en un LCD de 2x8 utilizando un PIC16F88.
Por ahora quiero probar con palabras.

He usado el compilador PIC C de CCS y una librería llamada flex_lcd, pero no me funciona, no sé si es problema de la librería (Quizá sea sólo para LCD2x16) o no sé qué será.

Me gustaría que me pudieran ayudar.
Muchas gracias de antemano.

Código principal:
```
#include <16F88.h>
#fuseS XT,NOWDT //HS
#use delay (clock=31000)//31k 0x00


#include <flex_lcd.c>
void main()
{
lcd_init();  
   while(true) 
   {
   
    lcd_putc("linea1");
    lcd_gotoxy(1,2);
    lcd_putc("linea2");
   }
 }
```
Librería  flex_lcd:
```
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7
//
#define LCD_RS    PIN_B3
#define LCD_RW    PIN_B1
#define LCD_E     PIN_B2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1

//===========================
#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif

void lcd_setcursor_vb(short visible, short blink) { 
  lcd_send_byte(0, 0xC|(visible<<1)|blink); 
}
```
PD: Los pines que configuré al inicio para el LCD coinciden con la conexión en la protoboard.

Atte. Cesar Beltrán.


----------



## juanma2468 (Oct 14, 2015)

Creo que la libreria flex_lcd es para LCD de 16x2. Intentaste con la libreria #include <lcd.c>?


----------



## BELTRANCESAR (Oct 14, 2015)

Hola juanma2468 si probé con lcd.c pero no me funciono tampoco.
Gracias


----------



## electrofoton (Feb 24, 2017)

Hola, llevo semanas intentando mostrar mensajes en una lcd de 16x02.
Me he leido un monton de temas en este foro y otros foros en varios idiomas.
He probado un monton de codigos, algunas librerias.
He revisado el circuito que tengo montado en la protoboard varias veces, tambien he probado con otros microcontroladores.
No consigo hacer que la lcd muestre mensajes en CCS.
He probado en MikroC hoy mismo y me ha funcionado a la primera.
Pero mi intención es usar CCS de Pic C Compiler.
He probado muchos fuses, tantos que me parece que muchos no son necesarios para lo que tengo que hacer.
Mi codigo es lo mas basico que pueda haber, no se en que estoy fallando.

```
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,NOPUT,NOCPD,NODEBUG 
#use delay(crystal = 20Mhz)


#include <flex_lcd.c>
#use fast_io(D)
#use fast_io(c)
#use fast_io(b)

void main(){
 set_tris_c(0b00000000);
  set_tris_b(0b00000000);
  lcd_init();                                 // Inicializa el lcd
  
  
  lcd_putc('\f');                            // Borra el lcd
   
  while(TRUE){
  
delay_ms(100);
   
   
        lcd_gotoxy(6, 1);                     // Va a la columna 5, fila 1
        
   printf(lcd_putc,"Hola");
     
  }
  }
```

En MikroC a la primera funcionando, en CCs no encuentro manera y llevo semanas haciendo pruebas.
El pic, cristal, condensadores estan bien, lo se porque funciona haciendo parpadear leds y funciona el programa en Mikroc.


----------



## juanma2468 (Feb 24, 2017)

Podrías subir el esquema de conexiones que estas usando? Por otro lado, que puerto de salida de datos estas usando?


----------



## dcsalg (Feb 24, 2017)

No probaste usar la librería de CCS en vez de esa que dice flex_lcd? La de CCS programas los pines de Datos, RW, RS y E y funciona yo los hice funcionar.


----------



## D@rkbytes (Feb 24, 2017)

electrofoton dijo:


> En MikroC a la primera funcionando, en CCs no encuentro manera y llevo semanas haciendo pruebas.


Actualiza el compilador de CCS.
Algunas versiones 4.XX tienen ese problema que se corrigió con las posteriores versiones.
Actualmente salió la versión 5.070 para usuarios registrados.


----------



## TRILO-BYTE (Feb 25, 2017)

aver intenta asi:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,NOPUT,NOCPD,NODEBUG 
#use delay(crystal = 20Mhz)
#include <flex_lcd.c>

void main(){
  lcd_init();                                 // Inicializa el lcd


  lcd_putc('\f');                            // Borra el lcd


  lcd_gotoxy(1, 1);                    
  printf(lcd_putc,"Hola");

  while(TRUE){





  }
  }


----------



## electrofoton (Feb 25, 2017)

Las conexiones se ven en el siguiente esquema. Lo he configurado en el archivo flex_lcd.c
#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7
//
#define LCD_RS    PIN_B1
#define LCD_RW    PIN_B2
#define LCD_E     PIN_B3

He probado la libreria lcd.c, flex_lcd y otras que he encontrado.
Uso la version 5.015




TRILO-BYTE dijo:


> aver intenta asi:
> 
> #include <16F877A.h>
> #fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,NOPUT,NOCPD,NODEBUG
> ...



Lo que me sale en el código de arriba es lo que se ve en la foto de abajo.
Uso una lcd keypad shield Df Robot.
No se si habra que modificar algo más en la libreria flex_lcd para que funcione esta lcd.
Con el codigo de arriba tambien he probado a ponerle una pausa, pero el resultado en igualmente no positivo.
Seré uno de los pocos que no son capaces de hacer funcionar una simple lcd!!!
He puesto una foto del circuito.


----------



## D@rkbytes (Feb 25, 2017)

A  mi no me gusta usar la librería flex_lcd, siempre he usado las que vienen con el compilador y si requiero una función especial, edito la librería.

Pero usando la librería por defecto, (lcd.c) sale andando a la primera, mira:
​
A éstas horas del cumpleaños ya no hace falta preguntar de qué sabor es el pastel.


----------



## TRILO-BYTE (Feb 25, 2017)

ami no me gusta la libreria de CCS hise la mia 


bueno veo que usas un crsital por que no intentas usar el oscilador interno y quitas el master reset y vez que pasa intentalo asi:



> #include <16F877A.h>
> 
> #fuses INTRC_IO,NOWDT,NOMCLR
> #Use delay (clock=8M)
> ...



ahora omite el boton reset y omite el cristal en la simulacion configuralo a 8Mhz aver que sucede


----------



## electrofoton (Feb 25, 2017)

TRILO-BYTE dijo:


> ami no me gusta la libreria de CCS hise la mia
> 
> 
> bueno veo que usas un crsital por que no intentas usar el oscilador interno y quitas el master reset y vez que pasa intentalo asi:
> ...



Me parece que el 16f877a no tiene oscilador interno.
Me da error el Pic C Compiler si le pongo el fuse NOMCLR.
D@rkbytes, que microcontrolador usas en la imagen, veo que no usas condensadores, los lleva internos el cristal?
Puedes poner el código que has usado?


----------



## D@rkbytes (Feb 25, 2017)

electrofoton dijo:


> Me parece que el 16f877a no tiene oscilador interno.


Así es, el PIC16F877A no tiene oscilador interno.


electrofoton dijo:


> Me da error el Pic C Compiler si le pongo el fuse NOMCLR.


Eso es normal, porque en el PIC16F877A el pin de reset no puede ser usado como entrada.
Es únicamente reset.
Y tampoco es necesario configurar todos los fuses.
Al usar: *#use delay (crystal = x frecuencia)* automáticamente se establecen los fuses requeridos, que en los casos básicos son los adecuados.
Y ésto también lo hace el compilador con varios registros para garantizar una inicialización estándar.


electrofoton dijo:


> D@rkbytes, ¿Qué microcontrolador usas en la imagen?


Es un PIC16F877A
Y aunque en la imagen no se alcanzó a ver la resistencia del pin 1, MCLR, hacia VCC, si la tiene. (4.7 KΩ)


electrofoton dijo:


> Veo que no usas condensadores. ¿Los lleva internos el cristal?


Posiblemente, pero no lo creo. La capacitancia parásita del protoboard, los hace innecesarios.
Es raro que los ponga en el protoboard, a menos que requiera ajustar la frecuencia a un valor exacto.


electrofoton dijo:


> ¿Puedes poner el código que has usado?


Claro. Adjunto programa y esquema.
Aunque casi estoy seguro que ya lo he publicado, posiblemente dentro de éste mismo tema, o en algún otro similar.
También se incluye la simulación en proteus 7.10 y 8.5 SP1 (No necesarias)

Notas importantes:
No compilar, usar el archivo hex incluido.
Conectar como se muestra en el esquema y probar. (Debe funcionar correctamente)
Después compilar, volver a grabar el PIC y probar, para determinar problemas del compilador.


----------



## electrofoton (Feb 25, 2017)

No me funciona. 
No muestra nada la pantalla.
Voy a probar en MikroC, a configurar la lcd para funcionar en el puerto D, para comprobar si funciona.


----------



## D@rkbytes (Feb 25, 2017)

electrofoton dijo:


> No me funciona.
> No muestra nada la pantalla.
> Voy a probar en MikroC, a configurar la lcd para funcionar en el puerto D, para comprobar si funciona.


Revisa bien tus conexiones. Algunos protoboard muchas veces suelen tener falsos contactos.
Como la configuración de pines es diferente debido a cada librería, prueba usando la misma disposición de pines en tus pruebas.
Ya que puede ser que algunas líneas del protoboard estén dañadas.
Verifica la continuidad de las líneas, cambia todo de lugar y prueba nuevamente, o usa otro protoboard.


----------



## electrofoton (Feb 25, 2017)

Ya he comprobado la continuidad, acaba ahora mismo de probar en MikroC un programa usando los mismos pines del puerto D y si que funciona en MikroC.

En el programa en MikroC, no se declara el pin RW, sin embargo funciona.


```
sbit LCD_RS at RD1_bit;
sbit LCD_EN at RD0_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD1_bit;
sbit LCD_EN_Direction at TRISD0_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// Fin de declaración de variables de conexión.

char contador=0,estado=1,texto1[]="Hola", texto2[4];

void main(){



Lcd_Init();                //Inicializa el LCD.
Lcd_Cmd(_LCD_CLEAR);       //Borra el display.
Lcd_Cmd(_LCD_CURSOR_OFF);  //Apaga el cursor.
Lcd_Out(1,6,texto1);       //Escribe el texto1.

{
 if (Button(&PORTA,4,1,0)) estado=0;    //Si se pulsa.
 if (estado==0 && Button(&PORTA,4,1,1)) //Si se pulsa y se libera.
 {
  contador++;  //"contador" contiene el número de pulsaciones.
  if (contador>100) contador=0;
  estado=1;
 }
 ByteToStr(contador,texto2); //Convierte a texto el contenido de la variable contador
                             //y lo guarda en texto2.
 Lcd_Out(2,6,"MikroC");        //Muestra el texto2.
}
}
```

¿Hago lo mismo en CCs?
¿Dejo sin declarar RW?
¿Lo conecto a masa, como he visto que algunos hacen?

Edito:
He configurado el pin RW y también  funciona.
Me esta seduciendo mucho la idea de pasarme a MikroC y enviar a la m.... CCS


----------



## roberttorres (Feb 25, 2017)

No se si viene al caso, pero alguna vez tuve un problema similar cuando utilizaba un crystal de 20 mhz(salia caracteres raros en el lcd), prueba con uno de 4 mhz.
PD: Nunca supe del porque funcionaba con el de 4mhz y no con el 20 mhz (solo soy un hobbista  ).


----------



## electrofoton (Feb 25, 2017)

roberttorres dijo:


> No se si viene al caso, pero alguna vez tuve un problema similar cuando utilizaba un crystal de 20 mhz(salia caracteres raros en el lcd), prueba con uno de 4 mhz.
> PD: Nunca supe del porque funcionaba con el de 4mhz y no con el 20 mhz (solo soy un hobbista  ).



He probado con cristal de  4,8,12 y 20 Mhz. Las ultimas pruebas con cristal de 4 Mhz.
El ultimo codigo que he probado debería de funcionar, pero no me funciona. No se si hay que modificar algo en la libreria *lcd.c* para que funcione con mi lcd.


```
/*******************************************************************************
* Programa: LCD16x2 Test.c
* Versión: 1.0
* Autor: D@rkbytes
* Compañia: Digitek
* Notas: 
* Prueba simple de un LCD 16x2
*******************************************************************************/
#include <16F877A.H>
#use     delay(crystal = 4 MHz)

#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
//
#define LCD_RS PIN_D1
#define LCD_RW PIN_D2
#define LCD_E PIN_D0
 #define LCD_DATA_PORT getenv("SFR:PORTD")  
#include <lcd.c>

void main (void)
{
   lcd_init();                   // Inicializar la pantalla.
   lcd_putc("\fHola Mundo");     // Escribe en la primer línea.
   lcd_putc("\nHello World");    // Escribe en la segunda línea.
   
   while (true);
}
```

He revisado muchas veces la continuidad en el circuito. No se me ocurre que más puedo hacer, no quiero rendirme, no se que estoy haciendo mal y quiero descubrirlo.
Debe de haber más gente que haya tenido el mismo problema que yo y haya dado con la solución.


----------



## dcsalg (Feb 25, 2017)

Pregunta básica son con el procesador ese Hitachi no el LCD no tiene otro no? 



Pregunta básica son con el procesador ese Hitachi no el LCD no tiene otro no? Osea el HD44780 digo! Porque hay otros 





Pregunta básica son con el procesador ese Hitachi no el LCD no tiene otro no? Osea el HD44780 digo! Porque hay otros.


----------



## electrofoton (Feb 25, 2017)

dcsalg dijo:


> Pregunta básica son con el procesador ese Hitachi no el LCD no tiene otro no? Osea el HD44780 digo! Porque hay otros



He buscado informacion sobre mi pantalla y usa el HD44780.
Es una Lcd keypad shield Df Robot, la he conseguido hacer funcionar en arduino y MikroC.
Tanto en arduino como con MikroC, funcionando a la primera.
¿Hay "otras" librerias de confianza para probar con esta lcd?
He desinstalado el pic c compiler para reinstalar las librerias por si habia algo mal  pero nada, sigue todo igual de mal.


----------



## D@rkbytes (Feb 25, 2017)

Estoy seguro que debe haber alguna incompatibilidad por los componentes extra que tiene ese tipo de pantalla.
Si usaras una pantalla normal, no tendrías problemas.

Por aquí vi alguna información:
*Warning to users of some vendors LCD keypad shields.*


----------



## electrofoton (Feb 25, 2017)

Es una lastima porque este lcd ya lleva el regulador para el contraste, luz de fondo y los botones.
Voy a buscar si tengo otro lcd de los mas sencillos y pruebo si funciona.


----------



## electrofoton (Feb 25, 2017)

D@rkbytes dijo:


> Estoy seguro que debe haber alguna incompatibilidad por los componentes extra que tiene ese tipo de pantalla.
> Si usaras una pantalla normal, no tendrías problemas.
> 
> Por aquí vi alguna información:
> *Warning to users of some vendors LCD keypad shields.*



D@rkbytes, has dado con la solución. El problema esta en la lcd, que tiene alguna incompatibilidad con la librería lcd.c
Tendre que desoldar la lcd de la shield para hacerla funcionar y averiguar que tocar de la shield para que funcione. Me parece que esta lcd estará diseñada para usarse con arduino.
Ahora he probado con otra lcd vieja que tengo de hace años sin usar y funciona bien.
Gracias a ti y a todos por vuestra ayuda.



C


----------



## D@rkbytes (Feb 25, 2017)

electrofoton dijo:


> Con la librería lcd.c sólo puedo usar los pines que he puesto anteriormente.
> He probado con flex_lcd.c y me deja usar otros pines.


Eso es normal, porque aparte de que estás usando definiciones no válidas para la librería lcd.c, tampoco estás usando el orden correcto que debe comprender el compilador.
Esto es algo muy básico en C para que el compilador redefina las sentencias que declara el usuario.

Ejemplo (PCWHD Compiler):

```
// Primero se debe definir el puerto de datos para la pantalla.
#define LCD_DATA_PORT getenv("SFR:PORTD") // Por defecto, en el 16F877A, será el puerto D

// Después se definen los pines de conexión a elección del usuario.
#define LCD_ENABLE_PIN  PIN_D3
#define LCD_RS_PIN      PIN_D1
#define LCD_RW_PIN      PIN_D2
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7

// A continuación, se debe incluir la librería que se usará para la pantalla.
#include <lcd.c>
```


----------



## electrofoton (Feb 25, 2017)

Lo he hecho así ahora y la librería lcd.c me deja cambiar el pin enable D0 a D3.


----------



## aguevara (Mar 26, 2017)

Hola a todos les planteo la siguiente duda que tengo a ver si alguien me puede dar un tip.
Tengo una funcion de la siguiente forma: 

sendfloatlcd(a,b,c){
lcd_gotoxy(a,b);
printf(lcd_putc,"%01.2f",c);}

y dentro del desarrollo del programa tengo la llamada a esa funcion de la siguiente manera

 float dato=12.30;
|
|
sendfloatlcd(1,1,dato);

El detalle es que el compilador marca error indicando que no es un formato invalido, lo he hecho con numeros enteros y funciona, la pregunta es Que cambio habra que hacer para aceptar numeros float?

Saludos  a todos


----------



## TRILO-BYTE (Mar 26, 2017)

es que esta mal el esquema que planteas

algo asi:

funcion(int ,int , float)
{

}

no me gusta la manera en que lo intepretas.

pudieras hacer ago asi:

char x=1;
char y=1;
float c;

float funcion(dato)
{
lcd_gotoxy(x,y);
printf(lcd_putc,"%01.2f",c);
}

float valor=12.30;

sendfloatlcd(valor);


----------



## aguevara (Mar 26, 2017)

Gracias por tu respuesta TRILO-BYTE de hecho me falto indicar que a y b son  del tipo INT y c del tipo FLOAT. Fijate que resolvi el problema y este era mas bien una cuestion (muy rara por cierto) de compilacion o software o windows que se yo, reinicie la PC y genere en CCS otro proyecto nuevo, copie el programa anterior en este nuevo proyecto compile y funciono. no me preguntes que era porque desconozco pero funciona.
Saludos


----------



## TRILO-BYTE (Mar 27, 2017)

mmm tambien el IDE de CCS luego falla y debes cerrar y abrir nuevamente , creo que no era necesario reiniciar


----------



## D@rkbytes (Mar 29, 2017)

Eso pasaba con las versiones antiguas del compilador.
Actualmente han habido muchas mejoras en el compilador.
Y por defecto, se debe cerrar cualquier proyecto abierto para poder compilar otro. (Eso es algo básico)

Al mirar los archivos .lst, se puede saber la versión que se usó para compilar, y a pesar de estar en el 2017, muchos usuarios siguen usando versiones antiguas del compilador.
Las versiones 4. <140 tenían bastantes problemas, fue hasta la 4.148 que se resolvieron muchos detalles.

Al pasar a la versión 5.00, CCS decidió darle otro ambiente al IDE y así mismo mejorar muchas cosas.
No lo han adaptado a Windows 10 x64, en el aspecto de poder usar el PICkit 3 directamente como se podía hasta Windows 7, pero no es algo muy relevante.

Actualmente para los usuarios registrados, tenemos la versión 5.071 con CCSLoad 5.040
Al ser usuario registrado, se obtiene mucha información y apoyo por parte de la empresa.

Cabe aclarar que CCS no es un lenguaje de programación.
Son las siglas de la empresa que desarrolla el compilador para el lenguaje C en microcontroladores PIC.
CCS = *C*ustom *C*omputer *S*ervices.


----------



## Guiditox (Oct 27, 2017)

A pesar de que busqué y busqué en el foro, no encuentro la solución.
El problema es que al compilar el código, me tira este error.

Compilador: CCS 5.07

*** Error 112 "C:\Program Files\PICC\Drivers\LCD.C" Line 327(1,1): Function used but not defined:  ... delay_ms 380  SCR=1008

Al probar y probar me dí cuenta que no me marca el error cuando NO pongo lcd_init();

El código es el siguiente:


```
#INCLUDE <16F877A.H>
#INCLUDE <LCD.C>
#FUSES HS,NOLVP,NOBROWNOUT,NOWDT,NOPROTECT
#USE DELAY(CLOCK=20M)

/*****************************************************************************/
#BYTE PORTA=0x05
#BYTE PORTB=0x06
#BYTE PORTC=0x07
#BYTE PORTD=0x08
#BYTE PORTE=0X09
#BYTE TRISA=0x85
#BYTE TRISB=0x86
#BYTE TRISC=0X87
#BYTE TRISD=0X88
#BYTE TRISE=0X89

/*****************************************************************************/

#DEFINE LCD_ENABLE_PIN PIN_B0
#DEFINE LCD_RS_PIN PIN_B1
#DEFINE LCD_RW_PIN PIN_B2

#define LCD_DATA_PORT getenv("SFR:PORTB")
/*****************************************************************************/
#DEFINE XV PIN_E0
#DEFINE PR PIN_E2

/*****************************************************************************/
#USE RS232(BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7,BITS=8,PARITY=N,FORCE_SW)
/*****************************************************************************/

///////////// //////////////////////////////////////////////////////////////////
/****************************VARIABLES GLOBALES*******************************/
///////////////////////////////////////////////////////////////////////////////
INT8 MUX,CONT,STEP,DY,XOUT;
CHAR DATA,KEY;
BYTE CONST GIRO1[5]={0B1100,0B0110,0B0011,0B1001,0B1100};
BYTE CONST GIRO01[5]={0B11000000,0B01100000,0B00110000,0B10010000,0B11000000};
/*****************************************************************************/
//0=SALIDA Y 1=ENTRADA EL VALOR DE LA VARIABLE DEBE SER LEIDO EN ASCCI
///////////////////////////////////////////////////////////////////////////////
/***************************CONFIGURACIÓN INICIAL*****************************/
///////////////////////////////////////////////////////////////////////////////
VOID MAIN(){
   TRISA = 0XFF;
   TRISB = 0X00;
   TRISC = 0X80;
   TRISD = 0X0;
   TRISE = 0X3;
   PORTA = 0X0;
   PORTB = 0X0;
   PORTC = 0X0;
   PORTD = 0X0;
   PORTE = 0X0;
   PORTA = MUX;
   XOUT = INPUT (XV) ;
   LCD_INIT();
   
   WHILE (TRUE)  {
      DATA = GETC ();
      IF (DATA == 100) {
         
         SWITCH (DATA)  {
            
            CASE 1:
            OUTPUT_HIGH (PR);
            DELAY_MS (500);
            FOR (CONT = 0; CONT < 30; CONT++) {
               FOR (STEP = 0; STEP < 4; STEP++) {
               OUTPUT_D (GIRO1[CONT]);
               DELAY_MS (10);
               }}

            BREAK;

            CASE 2:
            CASE 3:
            CASE 4:
            CASE 5:
            CASE 6:
            CASE 7:
            CASE 8:
            CASE 9:
            CASE 10:
            CASE 11:
            CASE 12:
            CASE 13:
            CASE 14:
            CASE 15:
            CASE 16:
            CASE 17:
            CASE 18:
            CASE 19:
            CASE 20:
            CASE 21:
            CASE 22:
            CASE 23:
            CASE 24:
            CASE 25:
            CASE 26:
            CASE 27:
            CASE 28:
            CASE 29:
            CASE 30:
            CASE 31:
            CASE 32:
            CASE 33:
            CASE 34:
            CASE 35:
            CASE 36:
            CASE 37:
            CASE 38:
            CASE 39:
            CASE 40:
            CASE 41:
            CASE 42:
            CASE 43:
            CASE 44:
            CASE 45:
            CASE 46:
            CASE 47:
            CASE 48:
            CASE 49:
            CASE 50:
            CASE 51:
            CASE 52:
            CASE 53:
            CASE 54:
            CASE 55:
            CASE 56:
            CASE 57:
            CASE 58:
            CASE 59:
            CASE 60:
            CASE 61:
            CASE 62:
            BREAK;
            }

IF (DATA == 200) {
   
IF (MUX + XOUT == 1)
{OUTPUT_HIGH (PR);
DELAY_MS (500);
FOR (CONT = 0; CONT < 30; CONT++) {
FOR (STEP = 0; STEP < 4; STEP++) {
OUTPUT_D (GIRO1[CONT]);
DELAY_MS (10);}}}

IF (MUX + XOUT == 2)
{OUTPUT_HIGH(PR);
DELAY_MS (500);
FOR (CONT = 0; CONT < 15; CONT++) {
FOR (STEP = 0; STEP < 4; STEP++) {
OUTPUT_D (GIRO01[CONT]);
DELAY_MS (10);}}
OUTPUT_HIGH(PR);
DELAY_MS(500);
FOR (CONT = 0; CONT < 15; CONT++) {
FOR (STEP = 0; STEP < 4; STEP--) {
OUTPUT_D (GIRO01[CONT]);
DELAY_MS (10);}}
FOR (CONT = 0; CONT < 30; CONT++) {
FOR (STEP = 0; STEP <4; STEP++) {
OUTPUT_D (GIRO1[CONT]);
DELAY_MS (10);}}
}}}}}
```
Esta es la sección de la librería a la que refiere el error. (Me marca el error al inicio delay_ms(15);


```
#endif
   lcd_enable_tris();
   lcd_rs_tris();
   lcd_rw_tris();
 #endif
    
   delay_ms(15);
   for(i=1;i<=3;++i)
   {
       lcd_send_nibble(3);
       delay_ms(5);
   }
   
   lcd_send_nibble(2);
   delay_ms(5);
   for(i=0;i<=3;++i)
      lcd_send_byte(0,LCD_INIT_STRING[i]);
```


----------



## D@rkbytes (Oct 27, 2017)

Coloca el *#include* *<lcd.c>* después de *#use* *delay* (*clock = 20M*)
Así la librería lcd.c sabrá a qué velocidad va el reloj.

Siempre se deben definir o declarar los parámetros requeridos, antes de incluir las librerías.
Esto es válido para cualquier librería que dependa de otros parámetros definidos por el usuario.

Nota:


```
#define LCD_DATA_PORT getenv("SFR:PORTB")
```
También debe declararse antes de incluir la librería, si es que esta predefine un puerto diferente al que deseamos.


----------



## Guiditox (Mar 11, 2018)

Hola.

El problema que estoy teniendo es que no sé cómo declarar que el pin rw sea conectado a masa.
Según lo que leí en la librería flex_lcd, es que tengo que poner como comentario #define USE_LCD_RW   1
Así defino en la librería que ese pin no se usa.
El problema que tengo es que no se guarda como comentario y al desconectar el pin rw en el circuito físico, el lcd se cuelga y me pone signos de interrogación y la verdad ya no sé qué hacer.

Desde ya, cualquier ayuda es bien recibida.

Compilador: CCS 5.070
Libreria lcd: <flex_lcd.c>
Conocimientos: Estudiante de secundaria 4°Año Técnico Electrónico

```
#include <16f883.h>
#use    delay(clock=10M)
#fuses  nobrownout,nolvp,noprotect,nowdt,hs

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||//

#byte   porta=0x05
#byte   portb=0x06                                              

#byte   trisa=0x85
#byte   trisb=0x86                                            

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_b1                                                      
#define LCD_RW    PIN_b2
#define LCD_E     PIN_b3
                         
#include <flex_lcd.c>                                              
                         
int a;

void main(){

lcd_init();
trisa=0x00;
trisb=0x00;
porta=0x00;
portb=0x00;

while(true){

output_toggle(pin_a0);                
                                     
a++;
delay_ms(100);

lcd_gotoxy(1,1);
printf(lcd_putc,"Contador: %i",a);

}
}
```


----------



## D@rkbytes (Mar 12, 2018)

Guiditox dijo:


> El problema que estoy teniendo es que no sé cómo declarar que el pin rw sea conectado a masa.
> Según lo que leí en la librería flex_lcd, es que tengo que poner como comentario #define USE_LCD_RW 1
> Así defino en la librería que ese pin no se usa.
> 
> El problema que tengo es que no se guarda como comentario y al desconectar el pin rw en el circuito físico, el lcd se cuelga y me pone signos de interrogación y la verdad ya no sé qué hacer.


No sé cómo sea para ti comentar en C, pero es de esta forma: // "comentario" o /* "comentario" */
Entonces si comentas esa definición, quedaría así: // #define USE_LCD_RW 1

Y dentro del código debe haber partes como esta:
#ifdef USE_LCD_RW // Si está definido USE_LCD_RW
// Instrucciones
#else if sentencia
// Instrucciones
#else
// Instrucciones
#endif

También podría estar #ifndef, que actúa inversamente, pero el caso es que al estar comentado USE_LCD_RW o sin existir, se debe poder compilar.
Como no adjuntas la librería flex_lcd, (Existen varias versiones) no podemos saber si no puedes compilar debido a otra causa.

La que yo tengo, se llama Flex_LCD416.c y desde un principio aproveché esa opción, quedando así:

```
// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.  Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD.  It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit.  Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
// #define USE_RW_PIN   1    // Lo comenté para no usar el pin R/W
```
Ahora ya no la uso porque las que incluye el compilador me sirven perfectamente.

Ya te han mencionado que estudies C y debes hacerlo, porque se te complican cosas muy básicas por desconocimiento del lenguaje.


----------



## miglo (Mar 12, 2018)

Yo la tengo como has indicado tu D@rkbytes y me va de lujo, // #define LCD_RW    PIN_B1. El pin RW de la LCD lo tengo conectado a masa.


----------



## Guiditox (Mar 13, 2018)

*Libreria*

```
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.
                                                                     
/*#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7
//
#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_C2
*/
// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

[COLOR=rgb(250, 197, 28)]//#define USE_LCD_RW   1[/COLOR]

//========================================      

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc,                    // Display on
1,                      // Clear display
6                       // Increment cursor
};


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));

delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif

void lcd_setcursor_vb(short visible, short blink) {
  lcd_send_byte(0, 0xC|(visible<<1)|blink);
}
```

Como se puede observar comente la línea pero a pesar de esto no me funciona en la realidad. Las conexiones fueron revisadas y se encuentran bien.

Les quería informar que lo logré solucionar. Resulta que el archivo que llamaba había otro igual en la carpeta de drivers, cuando lo descubrí lo elimine inmediatamente, volví a compilar, cargar el archivo e increíblemente funcionó.
Gracias por su atención, saludos.


----------



## roberto_rgc (Abr 3, 2018)

Buenas noches, me encuentro realizando un posicionador solar con dspic30f4013, ya tengo el código, solo que al querer simularlo en forma física para comprobar si esta bien mi lcd no muestra nada y no lo puedo simular en proteus ya que el dsp no se encuentra en los componentes del programa, con lo cual estoy buscando ayuda para saber si alguien sabe de alguna otra librería para la lcd ya que e buscado en otras paginas y e visto que varios dicen que la librería de la lcd de CCS no funciona en dsp.

Aquí adjunto mi programa por si alguien puede ayudarme.

PS. Muchas gracias.


----------



## pandacba (Abr 3, 2018)

Has buscado en la web de microchip? has buscado en el foro de Microchip? por último has echo alguna consulta a microchip?
Si es para posicionamiento es un desperdicio total, hay posicionadores de paneles solares que funcionan perfectamente con otros micros y funcionan perfectamente

Fijate aquí LCD lib


----------



## D@rkbytes (Abr 3, 2018)

roberto_rgc dijo:


> Buenas noches. Me encuentro realizando un posicionador solar con *dspic30f4013*


Tal vez te equivocaste de programa, porque el que adjuntas es para un PIC16F877A.
Aparte, no incluye las librerías que se están usando. (lcd_portb.c y kbd4x4.c)


----------



## roberto_rgc (Abr 4, 2018)

perdon


----------



## D@rkbytes (Abr 4, 2018)

Realiza una prueba únicamente con el código para escribir en la pantalla.
Comprueba bien las conexiones, el voltaje y que el potenciómetro de contraste esté conectado a tierra.
Si aún no se ven los caracteres, usa un cristal de 4 MHz. o el oscilador interno.
Las librerías no modificadas presentan problemas arriba de 20 MHz.
Esto se soluciona aumentando un poco los retardos, principalmente los de inicialización.

No tengo ese dsPIC, pero adjunto un sencillo ejemplo que puedes probar y modificar.


----------



## roberto_rgc (Abr 4, 2018)

Muchas gracias 
[B]D@rkbytes[/B]*, realizare los pruebas necesarias para ver si me funciona, te lo agradezco.*


----------



## roberto_rgc (Abr 5, 2018)

Ya he probado el código que me pasaste* D@rkbytes*, sólo que sigue sin mostrar nada mi LCD.
Ya chequé los pines de mi dsPIC y funcionan bien, ya que si tienen salida.
Lo que vi es que la LCD utiliza un controlador HD44780
Ya busqué en el foro acerca de este controlador y he encontrado algunos, pero cuando los pruebo me salen errores.
Estoy usando el puerto D para los datos y el F para E, RS y RW.

Esta es la librería que encontré.

```
// Definición de Puertos Pantalla LCD 40x20 Hitachi 44780

#bit lcd_db4 = PORTD.4

#bit tris_lcd_db4 = TRISD.4

#bit lcd_db5 = PORTD.5

#bit tris_lcd_db5 = TRISD.5

#bit lcd_db6 = PORTD.6

#bit tris_lcd_db6 = TRISD.6

#bit lcd_db7 = PORTD.7

#bit tris_lcd_db7 = TRISD.7

#bit lcd_en = PORTD .0

#bit tris_lcd_en = TRISD.0

#bit lcd_rw = PORTD.2

#bit tris_lcd_rw = TRISD.2

#bit lcd_rs = PORTD.1

#bit tris_lcd_rs = TRISD.1



// lcd_init() Inicialización del LCD (debe utilizarse al principio,

// antes de trabajar con el LCD).

//

// lcd_putc(c) Imprime un caracter en el LCD.

//

// lcd_gotoxy(x,y) Selecciona la nueva posicion de escritura en el LCD.

// (la esquina superior izquierda es 1,1)

//

// lcd_getc(x,y) Devuelve el caracter de la posicion x,y del LCD.

//

// void lcd_erase_line(x) Borra una cantidad de caracter hacia la derecha


// Conexion a la pantalla LCD 40x4

// RB0 <---> LCD DB4

// RB1 <---> LCD DB5

// RB2 <---> LCD DB6

// RB3 <---> LCD DB7

// RA0 <---> LCD ENEABLE

// RA1 <---> LCD R/W

// RA2 <---> LCD RS

//


#define LCD_DATO 1

#define LCD_INST 0


#define LCD_LINEA1 0x80 // Direccion de memoria para la 1 linea

#define LCD_LINEA2 0xc0 // Direccion de memoria para la 2 linea

#define LCD_LINEA3 0x94 // Direccion de memoria para la 3 linea

#define LCD_LINEA4 0xd4 // Direccion de memoria para la 4 linea


#define chr_1 0x00

#define chr_2 0x01

#define chr_3 0x02

#define chr_4 0x03

#define chr_5 0x04

#define chr_6 0x05

#define chr_7 0x06


// 7 6 5 4 3 2 1 0

// Function Set 0b 0 0 1 B L F 0 0

// Bus size, B:0=4 bits, B:1=8 bits

// Line Number, L:0=1 Line, L:1=2 Lines

// Font size F:0=5x8, F:1=5x10

#define LCD_FUNCTION_SET 0b00101000 // Bus=4bit, Line=2 & Font=5x8


// 7 6 5 4 3 2 1 0

// Display/Cursor 0b 0 0 0 0 1 D U B

// Set Display on/off, D:0=off, D:1=on

// Underline cursor, U:0=off, U:1=on

// Blinking cursor, B:0=off, B:1=on

#define LCD_DISPLAY_CURSOR 0b00001100 // Display=on, Scroll=off, Blinkin=off


// 7 6 5 4 3 2 1 0

// Entry Mode 0b 0 0 0 0 0 1 M S

// Cursor direction, M:0=left, 1=right

// Display Scroll, S:0=no scroll, S:1=scroll

#define LCD_ENTRY_MODE 0b00000110 // Increment cursor, no disp shift


void lcd_set_write() {

tris_lcd_db4 = 0; //

tris_lcd_db5 = 0; //

tris_lcd_db6 = 0; //

tris_lcd_db7 = 0; //---> Set portb RB0-RB3 mode output

}


void lcd_set_read() {

tris_lcd_db4 = 1; //

tris_lcd_db5 = 1; //

tris_lcd_db6 = 1; //

tris_lcd_db7 = 1; //---> Set portb RB0-RB3 mode input

}


int8 lcd_read() {

int8 valor=0; // Crea e inicializa una variable de 8 Bits

lcd_set_read(); // Prepara el puerto DB4-DB7 como entrada

lcd_rw = 1; // Habilita modo de lectura

delay_cycles(1); // nop

lcd_en = 1; // Habilita LCD Enable

delay_cycles(1); // nop

if (lcd_db4) // Lectura de DB4

bit_set(valor,4); //

if (lcd_db5) // Lectura de DB5

bit_set(valor,5); //

if (lcd_db6) // Lectura de DB6

bit_set(valor,6); //

if (lcd_db7) // Lectura de DB7

bit_set(valor,7); //---> Recoge los datos MSB

lcd_en = 0; // Deshabilita LCD Enable

delay_cycles(1); // nop

lcd_en = 1; // Habilita LCD Enable

delay_us(2); // Espera 2 uSeg.

if (lcd_db4) //

bit_set(valor,0); //

if (lcd_db5) //

bit_set(valor,1); //

if (lcd_db6) //

bit_set(valor,2); //

if (lcd_db7) //

bit_set(valor,3); //---> Recoge los datos LSB

lcd_en = 0; // Deshabilita LCD Enable

delay_cycles(1); // nop

lcd_set_write(); // Prepara el puerto DB4-DB7 como salida

return (valor);

}


void lcd_send_nibble(int8 n) {

if (bit_test(n,0)) //

lcd_db4 = 1; //

else //

lcd_db4 = 0; //


if (bit_test(n,1)) //

lcd_db5 = 1; //

else //

lcd_db5 = 0; //


if (bit_test(n,2)) //

lcd_db6 = 1; //

else //

lcd_db6 = 0; //


if (bit_test(n,3)) //

lcd_db7 = 1; //

else //

lcd_db7 = 0; //---> Set data nibble

delay_cycles(1); // nop

lcd_en = 1; // Habilita LCD Eneable __

delay_us(2); // Espera 2 uSeg. | |

lcd_en = 0; // Desabilita LCD Eneable __| |__

}


void lcd_send_byte (int1 select, int8 n) {

lcd_rs = 0; // Modo de instruccion

while (bit_test(lcd_read(),7)); // Espera que la pantalla se desabilite

lcd_rs = select; // Escoje entre RS=0 : Instruccion & RS=1 : Data

delay_cycles(1); // nop

lcd_rw = 0; // Habilita modo de escritura

delay_cycles(1); // nop

lcd_en = 0; // Desabilita LCD Eneable

lcd_send_nibble(n >> 4); // Envia los datos superiores MSB

lcd_send_nibble(n); // Envia los datos inferiores LSB

}



// Opcional por si quieres crear caracteres especiales, puedes crear hasta 8

void lcd_cgram() {

int8 i;

const int8 chr[56] = {0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x15, // chr_1

0x15,0x00,0x10,0x10,0x10,0x10,0x00,0x15, // chr_2

0x15,0x00,0x14,0x14,0x14,0x14,0x00,0x15, // chr_3

0x15,0x00,0x15,0x15,0x15,0x15,0x00,0x15, // chr_4

0x00,0x00,0x00,0x00,0x1F,0x0E,0x04,0x00, // chr_5

0x00,0x04,0x0E,0x1F,0x04,0x04,0x04,0x00, // chr_6

0x00,0x04,0x04,0x04,0x1F,0x0E,0x04,0x00}; // chr_7


lcd_send_byte(LCD_INST, 0x40);

for(i=0;i<=55;++i) {

lcd_send_byte(LCD_DATO, chr);

}

lcd_send_byte(LCD_INST,0x01); // Clear LCD

}


void lcd_init() {

int8 i, count=0;

lcd_set_write(); // Prepara el puerto DB4-DB7 como salida

tris_lcd_en = 0; //

tris_lcd_rw = 0; //

tris_lcd_rs = 0; //---> Set porta RA0, RA1 & RA2 mode output

lcd_en = 0; //

lcd_rw = 0; //

lcd_rs = 0; //---> Clear LCD_EN, LCD_RW & LCD_RS

delay_ms(25);

retry:

for(i=1; i<=3; ++i) {

lcd_send_nibble(0b0011); // 8 bit mode 3 times

delay_ms(5);

}

lcd_send_nibble(0b0010); // 4 bit mode

while (bit_test(lcd_read(),7)) { // Espera que la pantalla se desabilite

delay_us(100);

count++;

if (count>=200) {

count=0;

goto retry;

}

}

lcd_send_byte(LCD_INST, LCD_FUNCTION_SET); // Function Set

lcd_send_byte(LCD_INST, LCD_DISPLAY_CURSOR); // Display Cursor

lcd_send_byte(LCD_INST, LCD_ENTRY_MODE); // Entry Mode

}


void lcd_gotoxy(int8 x, int8 y) {

int8 const address[4]={LCD_LINEA1,LCD_LINEA2,LCD_LINEA3,LCD_LINEA4};

int8 pos;

pos=address[y-1]+(x-1);

lcd_send_byte (LCD_INST, pos);

}


char lcd_getc(int8 x, int8 y) {

char valor;

lcd_gotoxy(x,y);

lcd_rs = 1;

valor = lcd_read();

lcd_rs = 0;

return (valor);

}


/*void lcd_putc(char c) {

lcd_send_byte(LCD_DATO,c);

}*/


void lcd_putc( char c) {

   switch (c) {

     case "f"   : lcd_send_byte(0,1);

                   delay_ms(2);

                                           break;

     case "

"   : lcd_gotoxy(1,2);        break;

     case ""   : lcd_send_byte(0,0x10);  break;

     default     : lcd_send_byte(LCD_DATO,c);     break;

   }

}


void lcd_clear() {

lcd_send_byte(LCD_INST,0x01);

}


void lcd_home() {

lcd_send_byte(LCD_INST,0x02);

}


void lcd_erase_line(int8 x) {

int8 i;

for(i=1;i<=x;++i) {

lcd_send_byte(LCD_DATO,32);

}

}
```


----------



## D@rkbytes (Abr 6, 2018)

roberto_rgc dijo:


> Lo que vi es que la LCD utiliza un controlador HD44780


La mayoría de pantallas genéricas usan clones del chip de Hitachi HD44780 y también la mayoría de librerías usan las instrucciones para ese chip.
Lo que no has mostrado es el esquema de cómo estás conectando la pantalla.


roberto_rgc dijo:


> Ya busqué en el foro acerca de este controlador y he encontrado algunos, pero cuando los pruebo me salen errores.


¿Qué errores te muestra el compilador?


----------



## roberto_rgc (Abr 6, 2018)

me manda estos errores cuando lo compilo en mi programa.  es que el  kbd4.c del archivo no lo tengo. yo tengo el kbd4x4.c e intente cambiarlo pero me sale eso.

*** Error 12 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 46(15,20): Undefined identifier   PIN_E0
*** Error 51 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 48(4,8): A numeric expression must appear here
*** Error 28 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 57(17,20): Expecting an identifier  ALL_ROWS
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 57(29,30): Expecting a declaration
*** Error 48 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 64(4,9): Expecting a (
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 64(10,14): Expecting a declaration
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 64(14,15): Expecting a declaration
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 65(4,6): Expecting a declaration
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 65(6,7): Expecting a declaration
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 65(7,9): Expecting a declaration
*** Error 48 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 65(9,23): Expecting a (
*** Error 43 "C:\Program Files (x86)\PICC\Drivers\kbd4.c" Line 65(24,44): Expecting a declaration


----------



## D@rkbytes (Abr 6, 2018)

roberto_rgc dijo:


> es que el kbd4.c del archivo no lo tengo.


Esa librería viene por defecto con PIC C Compiler.
Los errores se deben a la configuración de pines en la librería y se tienen que cambiar por los que usas en el microcontrolador.
Que por cierto, no los muestras en el esquema que subiste.
Eso es importante y debes verificar si los pines que usas son Digital I/O


----------



## roberto_rgc (Abr 7, 2018)

Ya e resuelto el problema, muchas gracias,si era eso, en cuanto los termine lo publicare, esperando y a alguien le pueda servir en el futuro.
Muchas gracias por tu ayuda * D@rkbytes.*


----------



## lolzkilla (May 30, 2018)

Hola, tengo un problema, en la simulación el LCD muestra todo!!!! pero cuando lo implemento en la protoboard nada!!!! 
adjunto el diagrama y el codigo en CCS. 
 
ALGUNA SOLUCION? GRACIAS!! 
Posdata: ya revise las paginas anteriores del foro y no he podido solucionar el problema


----------



## D@rkbytes (May 30, 2018)

El pin de VEE de la pantalla no debe ir a tierra completamente o se verán cuadros negros.
Debes colocar en serie un potenciómetro (Preset) de unos 5 KOhms.

Nota: Es preferible que subas tu proyecto dentro de un archivo comprimido.


----------



## jose Maria (Jul 2, 2018)

Hola amigos,pues eso,que me he cansado de hacer el circuito para mostrar una frase en LCD y no me funciona con el pic 16f648A,ni otro con el pic 16F84A.He comprado un pic 16F877A y me ha funcionado a la primera un esquema de la web de ELECTROALL.Voy a intentar subir el esquema y el código para que me digáis en que he fallado,o si el códifo está mal.


// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la
// frase 'hola mundo ' y en la segunda linea 'VsZeNeR'05'. Para ahorrar un
// pin conectamos RW a tierra(GND) y en nuestro programa generamos un retraso de
// 2ms para poder apreciarse todos los caracteres. La ventaja es que nos ahorramos
// 1 pin pero la desventaja es menor rapidez ya que empaquetamos en bloques de 4 bit.
// Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida.
//
// Conexiones: B0 -> E
// B1 -> RS
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
delay_ms(2); //retardo para apreciarse todos los caracteres
printf(lcd_putc,"hola mundo \nVsZeNeR'05"); //muestra por pantalla el mensaje
}


Este es el código.

Denunciar

	Mensaje automáticamente combinado: Jul 2, 2018

Aquí subo el esquema en rar.


----------



## D@rkbytes (Jul 2, 2018)

La librería nativa lcd.c de CCS, no es apta para funcionar sin el pin RW.
Para que lo compruebes, conecta físicamente el pin RW de la pantalla al pin RB2 del PIC16F648A y verás que debe funcionar.
Para omitir el pin RW usa la librería flex_lcd.c


----------

