Errores en LCD 16x2

Hola,
Haciendo el diseño de un panel con un LCD 16X2 me encontré con que, al conectar otro LCD imprime la primera línea y al ir a la siguiente una serie de símbolos (no planeados) comienzan a salir, y finalmente termina perdiendo la configuración, estoy seguro que el software esta correcto ya que lo he probado con otros LCD's y funciona bien, sin embargo los nuevos LCD que me han llegado están haciendo esto.

Quisiera saber sí alguien ha tenido este mismo problema, y algún consejo para solucionarlo será muy agradecido.
Saludos.
 
y por que no subes el codigo que usaste?

Algunos Lcd necesitan mas tiempo para inicializarse, me paso algo similar con uno y con otro era por una linea de codigo que no puse (no recuerdo cual) y en algunos lcd funciona bien sin esa linea, pero en otros no. Tambien puede ser por el tiempo de retardo en el envio de datos o comandos. No en todos es igual.

Saludos.
 
Hola, si con gusto lo subo, de todas maneras es un código que se encuentra en la red, en un rato más lo subo, lo que se me hace extraño es esto:
Con LCD antiguo
1 prende la fuente
2 inicializa display
3 imprime primera línea de bienvenida
4 imprime segunda línea, borra e imprime el mensaje que se mantendrá durante todo el proceso

Ahora el problema es que al poner el segundo display ( el nuevo)
En el paso 4 imprime cosas como #%£¥$'ncnje
Empieza a parpadear y se queda en blanco el display
Las funcionalidades de la placa funcionan bien en general aún sin display así que es el display
En un rato subo el código y las fotos de los display

Gracias por el consejo
 
Bien aquí va el código

CODIGO:
Código:
//********************************************************************************//


/*    LCD                    PIC
/* ----------------------------------------------
/*    D4    (11)    -->        RD0   (19)
/*    D5    (12)    -->        RD1   (20)
/*    D6    (13)    -->        RD2   (21)
/*    D7    (14)    -->        RD3   (22)
/*    RS    (4)        -->        RD4   (27)
/*    RW    (5)        -->        RD5   (28)
/*    E    (6)        -->        RD6   (29)
/*    NC            -->        RD7   (30)
/* ---------------------------------------------

/* Lineas de control para LCD */
#define RS                PORTDbits.RD4    // Comando/Dato
#define RW                PORTDbits.RD5    // Escritura/Lectura
#define E                PORTDbits.RD6    // Reloj
#define Puerto            PORTD            // Puerto a utlilizar por LCD
#define Config_Puerto     TRISD=0x80        // Configura bit 6:0 salidas

/*Display ON/OFF Cursor*/
/*Configuración del Display y Cursor*/
#define CLEAR            0b00000001
#define DON                0b00001111
#define DOFF            0b00001011
#define CURSOR_ON        0b00001111
#define CURSOR_OFF        0b00001101
#define BLINK_ON        0b00001111
#define BLINK_OFF        0b00001110
#define CURSOR_HOME        0b00000010

/*Entry Mode Set*/
/*Modo Entrada*/
#define INCREMENT        0x06
#define DECREMENT        0x04

/*Shift_Cursor Display*/
#define SHIFT_CUR_LEFT        0x13
#define SHIFT_CUR_RIGHT     0x17
#define SHIFT_DISP_LEFT     0x1B
#define SHIFT_DISP_RIGHT     0x1F

/*Función Set*/
#define FOUR_BIT    0x2F
#define EIGHT_BIT     0x3F
#define LINE_5x7     0x33
#define LINE_5x10     0x37
#define LINES_5x7     0x2F
#define DDRAM_L1     0x80
#define DDRAM_L2     0xC0
#define DDRAM_L3     0x90
#define DDRAM_L4     0xD0

/* Prototipos de Funciones */
void Comando_LCD(char);
void Dato_LCD(char);
void Inicializa_LCD(void);

/* Funcion Comando */
void Comando_LCD(char dato)
{ 
    char temp;

    temp = dato;        // Respalda dato en temp
    dato = dato >> 4;    // Corrimiento de cuatro lugares a la derecha
    Puerto = dato;        // Nible alto en Puerto
    RW = 0;                // Escribir en LCD
    RS = 0;                // Indica comando para LCD
    E = 1;                // Activa Pulso de reloj
    Delay1KTCYx(5);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // Desactiva Pulso de reloj
    Puerto = temp;        // Nible bajo en Puerto
    RW = 0;                // Escribir en LCD
    RS = 0;                // Indica comando para LCD
    E = 1;                // Activa Pulso de reloj
    Delay1KTCYx(5);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // Desactiva Pulso de reloj
}

/* Funcion Dato */
void Dato_LCD(char dato)
{ 
    char temp;

    temp = dato;        // Respalda dato en temp
    dato = dato >> 4;    // Corrimiento de cuatro lugares a la derecha
    Puerto = dato;        // Nible alto en Puerto
    RW = 0;                // Escribir en LCD
    RS = 1;                // Indica dato para LCD
    E = 1;                // Activa Pulso de reloj
    Delay1KTCYx(5);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // Desactiva Pulso de reloj
    Puerto = temp;        // Nible bajo en Puerto
    RW = 0;                // Escribir en LCD
    RS = 1;                // Indica dato para LCD
    E = 1;                // Activa Pulso de reloj
    Delay1KTCYx(5);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // Desactiva Pulso de reloj
}


/* Inicializa LCD */
void Inicializa_LCD(void)
{ 
    Delay1KTCYx(310);    // Retardo de 110 mseg.
    Config_Puerto;        // Puerto como salida bits 6:0
    Delay1KTCYx(310);
    Puerto = 0x02;        // 0x02
    Delay1KTCYx(310);
    RS=0;    
    RW=0;    
    E = 1;                // E = 1
    Delay1KTCYx(15);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // E = 0
    Delay1KTCYx(15);    // Retardo de 15 mseg (XT = 4MHz)
        Puerto = 0x02;        // 0x02
    Delay1KTCYx(310);
    RS=0;    //
    RW=0;    //
    E = 1;                // E = 1
    Delay1KTCYx(15);        // Retardo de 5ms (XT = 4MHz)
    E = 0;                // E = 0
    Delay1KTCYx(15);    // Retardo de 15 mseg (XT = 4MHz)
    
    
    /* Comandos de Inicializacion */
    
    // Comando1 de 4 
    Comando_LCD(LINES_5x7 & FOUR_BIT );
    /* Dos lineas , matris de 5x7 puntos */
    /* Formato de 4 bits */
    
    // Comando2 de 4
    Comando_LCD(DON & CURSOR_ON & BLINK_ON);
    /* Display encendido */
    /* Cursor encendido con parpadeo */
    
    // Comando3 de 4
    Comando_LCD(CLEAR);
    /* Borra pantalla */
    /* Cursor en linea 1 posicion 0 */
    
    // Comando4 de 4
    Comando_LCD(INCREMENT);
    /* Display y cursor con incremento */

    /* El LCD alfanumerico se ha inicializado y se */
    /* encuentra listo para desplegar mensajes */
}


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

ya que se tiene este codigo en un .h, en el programa principal se madan los mensajes al LCD de la siguiente manera:


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

#include <p18f4550.h>
#include <delays.h>
#include <LCDPortD.h>
#include <timers.h>
//#pragma config OSC=XT

#pragma config FOSC = HS
#pragma config LVP=OFF
#pragma config WDT=OFF
#define    Ck            PORTEbits.RE0
#define    Strobe            PORTEbits.RE1
#define    Out            PORTEbits.RE2
#define CLEAR            0b00000001
#define DON            0b00001111
#define DOFF            0b00001011
#define CURSOR_ON        0b00001111
#define CURSOR_OFF        0b00001101
#define BLINK_ON        0b00001111
#define BLINK_OFF        0b00001110
#define CURSOR_HOME        0b00000010

void ImprimeP(void);
void Mensajes(rom char *);


rom char 
SALUDO[]="BIENVENIDO",
DESCRIPCION[]="programa LCD :)",
CARACTERES[]="!"#$%&/()=)?¡";

void main (void)
{
Delay10KTCYx(100);
Inicializa_LCD();
while(1)
{
ImprimeP();
}
}


void ImprimeP(void)
{
    near rom char *Puntero;
        Delay10KTCYx(10);
        Comando_LCD(CLEAR);
        Comando_LCD(DON & CURSOR_OFF & BLINK_OFF);
        Puntero=&SALUDO[0];
        Comando_LCD(DDRAM_L1);
        Mensajes(Puntero);            
        Puntero=&DESCRIPCION[0];
        Comando_LCD(DDRAM_L2);
        Mensajes(Puntero);
        Delay10KTCYx(300);
        Comando_LCD(CLEAR);
        Puntero=&CARACTERES[0];
        Comando_LCD(DDRAM_L1+2);
        Mensajes(Puntero);
        Puntero=&CARACTERES[0];
        Comando_LCD(DDRAM_L2+3);
        Mensajes(Puntero);    
        Delay10KTCYx(300);
        Comando_LCD(CLEAR);
}

void Mensajes (rom char *Caracter)
{
    while(*Caracter)
    {
        Dato_LCD(*Caracter);
        Caracter++;
    }
}

//********************************************************************************//
por cierto, la parte del LCD, la baje de internet, pero el código no tenia firma así que no puedo darle mis respetos al creador, sin embargo donde quiera que esté gracias, hahahaha
 
Última edición por un moderador:
Pues lo más sencillo creo yo es que imprimas la línea de puros caracteres en blanco
Para cualquier compilador es igual sólo tienes que enviar el carácter vacío en toda la línea
Saludos
 
Pues lo más sencillo creo yo es que imprimas la línea de puros caracteres en blanco
Para cualquier compilador es igual sólo tienes que enviar el carácter vacío en toda la línea
Saludos

Gracias por tu pronta respuesta amigo, tengo este problema, estoy haciendo este reloj pero quiero que me recuerde estas fechas, solo que encima los caracteres y hace parpadear la utlima linea, este es mi codigo, saludos

Código:
#include <16f883.h>
#fuses nowdt,noprotect,nolvp
#use delay (INTERNAL=4m)
#include <ds1307.c>
#include <flex_lcd.c>

void main (void){

int sec=55,min=59,hora=23,dia=9, mes=2,anio=13,dow=4;
char fecha[3];


lcd_init();
lcd_putc("Lic. Martha Salinas.");

ds1307_set_date_time(dia,mes,anio,dow,hora,min,sec);

while(1){
ds1307_get_date(dia,mes,anio,dow);        /// se obtiene la fecha  
ds1307_get_time(hora,min,sec);             /// se obtiene la hora
ds1307_get_day_of_week(fecha);
lcd_gotoxy(4,2);
printf(lcd_putc,"%s %02u/%02u/20%02u",fecha,dia,mes,anio);
lcd_gotoxy(11,3);
printf(lcd_putc, "%02u:%02u:%02u",hora, min, sec);
delay_ms(200);

if(dia==9,mes==2,hora<=19){  //09-feb   cumple Ulysses
lcd_gotoxy(5,4);
lcd_putc("HOY CUMPLE DE ULYSES!");
}else{
lcd_gotoxy(5,4);
lcd_putc("                   ");
}
if(dia==10,mes==2,hora<=19){   //06-mar   cumple Suegra
lcd_gotoxy(5,4);
lcd_putc("HOY CUMPLE DE SUEGRA");
}else{
lcd_gotoxy(5,4);
lcd_putc("                   ");
}
if(dia==9,mes==3,hora<=19){   //09-mar   cumple Mané
lcd_gotoxy(5,4);
lcd_putc("!HOY CUMPLE DE MANE!");
}else{
lcd_gotoxy(5,4);
lcd_putc("                   ");
}
}}
pd adjunto simulacion

arturkick dijo:
GRACIAS por tu pronta respuesta amigo, tengo este problema, estoy haciendo este reloj pero quiero que me recuerde estas fechas, solo que encima los caracteres y hace parpadear la utlima linea, este es mi codigo, saludos
archivo adjunto (simulacion)
 

Adjuntos

  • PROTEUS.rar
    38.4 KB · Visitas: 6
Última edición por un moderador:
Hola,
mira he estado checando el codigo que enviaste, y pues he notado dos cosas:

lo primero es:

dentro del código, imprimes una cadena de caracteres vacíos en cada uno de los else de tus memorias, por esta razón da la impresión de parpadeo:
if(dia==10,mes==2,hora<=19){ //06-mar cumple Suegra
lcd_gotoxy(5,4);
lcd_putc("HOY CUMPLE DE SUEGRA");
}else{
lcd_gotoxy(5,4);
lcd_putc(" ");
}


en general, cada que llega a revisar si se cumple la condición de fechas, imprime una cadena de caracteres vacíos, y asi lo hace con cada uno de los "if" despues de eso regresa al principio del while(1) e imprime la hora, y lo hace de nuevo pasando por todas las condiciones y repitiendo el mismo problema.

para evitar que el parpadeo ocurra podrías eliminar los else de cada una de las memorias, y hacer un sistema de borrado mas complejo, es decir, el verdadero reto es lograr lo siguiente:

if ((mes!=10,dia!=10),(mes!=2,dia!=9),(mes!=3,dia!=9))
{
lcd_gotoxy(5,4);
lcd_putc(" ");
}

la traducción seria: si la variable mes es distinta a 10 y a 2 y a 3 y los días correspondientes a esos meses también son distintos a los establecidos, entonces imprime la linea de caracteres vacíos, o en su defecto podrías limpiar la pantalla con el comando clear que seguramente tiene incluida tu libreria de LCD.

de esta manera limitas a que borre el mensaje únicamente fuera de los días establecidos.

lo segundo es, que probablemente para esta aplicación, podría ser mas conveniente utilizar un switch case en lugar de if, ya que de esa manera evitas que el micro tenga que pasar por if de manera innecesaria.

Bueno, esas serian algunas opciones que podrías utilizar, espero haber ayudado en algo, cualquier cosa seguimos en contacto.

Saludos
 
HOLA AMIGO, gracias por responder, eh estado tratando de ponerlo como me dices, osea declarando en los if que solo ponga el mensajes cuando el dia sea diferente a todos los demas pero el problema es que no me borra la linea de la pantalla, osea; encima todos los mensajes y no se porque. saludos
 
Atrás
Arriba