Autor Tema: lcd_init() --> No me funciona, desesperado  (Leído 12937 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
lcd_init() --> No me funciona, desesperado
« en: 01 de Junio de 2009, 12:38:52 »
Pues he intentado mil maneras distintas. No consigo que el programa pase de esta linea. El caso es que en Proteus me funciona de perlas pero en placa no hay manera. He intentado otro puerto, otro display, otro PIC, he cambiado lo de los retardos en la libreria del LCD, he probado distintas alimentaciones, he probado otra placa.....

No se que mas puedo hacer, no soy capaz ni de encender el display con el PIC, (la backligth si funciona)
Uso el PIC 18F252 y la libreria para el puerto B de ucontrol.

no me funciona ni algo tan simple como esto:

#include <18F252.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

#include <lcd.c>

void main()
{
   lcd_init();
   set_tris_b(0x00);  //RB0-RB7 salidas
   
   while (TRUE) {
   lcd_putc("Ready.....");
   delay_ms(1000);
   }

esta es la libreria que uso para el LCD:

//     B0 
//     B1 
//     B2  E
//     B3  RS
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7
//   (Sin 'RW') conectado a Masa
//
// Funciones soportadas:
//                         lcd_init()
//                         lcd_gotoxy( BYTE col, BYTE fila)
//                         lcd_putc( char c)
//                              \f  Clear display                             
//                              \n  Go to start of second line               
//                              \b  Move back one position


#define use_portb_lcd TRUE  //LCD conectado al puerto b.

struct lcd_pin_map {
   BOOLEAN unused1; // RB0
   BOOLEAN unused2; // RB1
   BOOLEAN enable;  // RB2
   BOOLEAN rs;      // RB3
   int data : 4;    // RB4-RB7
} lcd;

#if defined use_portB_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf81
   #else
    #locate lcd = 6
   #endif
   #define set_tris_lcd(x) set_tris_b(x)
#else
   //#locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf83
   #else
    #locate lcd = 8
   #endif
   #define set_tris_lcd(x) set_tris_d(x)
#endif

#ifndef lcd_type
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#endif

#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      //lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      //lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}



Ke mas puedo probar????  :( :( :( :( :( :( :(

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #1 en: 01 de Junio de 2009, 13:00:11 »
Estas usando el pin RW???Me parece que no lo usas y esta comentado.
mmmm...(esto no es problema pero estoy pensando )  xD

Deberias subir tu diagrama electronico de la placa que no te funciona.


En el Tipo de Oscilador pones HS con un click=4MHz , en este caso cambia a XT .





Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #2 en: 01 de Junio de 2009, 13:14:23 »


No creo que sea problema del programa, pq he intentado varios ejemplos.
Yo creo que se debe a libreria...

Desconectado alexysar

  • PIC16
  • ***
  • Mensajes: 206
    • e-Kit
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #3 en: 01 de Junio de 2009, 13:33:59 »
generalmente hay que borrar el display antes de usarlo, pero despues de inicializarlo. Podrias probar para ver que resultados te da.

Aqui algunos ejemplos que dejo el colega zerc79 Ejemplos LCD
« Última modificación: 01 de Junio de 2009, 13:48:28 por alexysar »

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #4 en: 01 de Junio de 2009, 13:40:24 »
Me juego a que es el contraste..... mira este pdf LCD (aporte de cryn) que a todos les da una mano.

Saludos!
LAS MALVINAS SON ARGENTINAS!

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #5 en: 01 de Junio de 2009, 13:48:11 »
Tampoco poniendo esa linea del '\f'
Tampoco cambiando el delaycicle por delay_us(1) o delay_us(3).

Cuando el programa llega a la linea del init no hace nada, se queda parado.

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #6 en: 01 de Junio de 2009, 13:50:21 »
en el pin del contraste tengo un potenciometro de 10k y en serie una r de 10K, he probado a ponerlo directamente y tampoco.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #7 en: 01 de Junio de 2009, 14:27:03 »
En esta función:
Código: C
  1. void lcd_send_byte( BYTE address, BYTE n ) {
  2.  
  3.       lcd.rs = 0;
  4.       while ( bit_test(lcd_read_byte(),7) ) ;
  5.       lcd.rs = address;
  6.       delay_cycles(1);
  7.       //lcd.rw = 0;
  8.       delay_cycles(1);
  9.       lcd.enable = 0;
  10.       lcd_send_nibble(n >> 4);
  11.       lcd_send_nibble(n & 0xf);
  12. }

Reemplaza la linea: while ( bit_test(lcd_read_byte(),7) ) ;
Por un delay --> delay_us(60);

Estas esperando la habilitación del LCD, realizando una lectura, la cual no la tienes habilitada.
« Última modificación: 01 de Junio de 2009, 14:30:23 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #8 en: 01 de Junio de 2009, 14:31:31 »
en el pin del contraste tengo un potenciometro de 10k y en serie una r de 10K, he probado a ponerlo directamente y tampoco.

 :shock:
leiste por lo menos el pdf?
LAS MALVINAS SON ARGENTINAS!

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #9 en: 01 de Junio de 2009, 14:48:12 »
En esta función:
Código: C
  1. void lcd_send_byte( BYTE address, BYTE n ) {
  2.  
  3.       lcd.rs = 0;
  4.       while ( bit_test(lcd_read_byte(),7) ) ;
  5.       lcd.rs = address;
  6.       delay_cycles(1);
  7.       //lcd.rw = 0;
  8.       delay_cycles(1);
  9.       lcd.enable = 0;
  10.       lcd_send_nibble(n >> 4);
  11.       lcd_send_nibble(n & 0xf);
  12. }

Reemplaza la linea: while ( bit_test(lcd_read_byte(),7) ) ;
Por un delay --> delay_us(60);

Estas esperando la habilitación del LCD, realizando una lectura, la cual no la tienes habilitada.

Nada sigue igual.

Respecto al pdf, que me recomiendas hacer, me refiero a que experimentos de los que cita

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #10 en: 01 de Junio de 2009, 14:59:44 »

Respecto al pdf, que me recomiendas hacer, me refiero a que experimentos de los que cita

yo no tengo idea si estas trabajando en alguna placa entrenadora o directamente en el protoboard, supongamos la segunda opción capas que tu circuito esta bien y hay algún cable cortado u otra  pavada que puede hacerte perder mucho tiempo. Si por lo menos probas encender el display o sea pasar la función init_lcd()  eliminas mucha incertidumbre.....
yo se lo que te digo yo tenia una pista cortada y estaba al borde de tirarlo a la basura y me tome el tiempo de por lo menos hacer la primera prueba.

Saludos!
LAS MALVINAS SON ARGENTINAS!

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #11 en: 01 de Junio de 2009, 15:32:41 »
No, uso una placa entrenadora.

No consigo ver ni un solo cuadrado negro, solo se me enciende el backlight.

ahora he conseguido que el programa pase del lcd_init() y haga lo siguinte, pero no veo ninguna frase en el display.

He habilitado RW y lo he onectado al RB1 del PIC.

este es el programa que he usado:

#include <18F252.h>  //Libreria del PIC escogido

#FUSES XT         //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOOSCSEN   //Oscillator switching is disabled, main oscillator is source
#FUSES NOPUT      //No Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOWDT      //No Watch Dog Timer
#FUSES STVREN     //Stack full/underflow will cause reset
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG    //No Debug mode for ICD
#FUSES NOPROTECT  //Code not protected from reading
#FUSES NOCPD      //No EE protection
#FUSES NOWRT      //Program memory not write protected
#FUSES NOWRTC     //configuration not registers write protected
#FUSES NOWRTB     //Boot block not write protected
#FUSES NOWRTD     //Data EEPROM not write protected
#FUSES NOEBTR     //Memory not protected from table reads
#FUSES NOEBTRB    //Boot block not protected from table reads

#use DELAY(CLOCK=4000000)
#use FIXED_IO(C_OUTPUTS=PIN_C0,PIN_C1,PIN_C2,PIN_C3)

#include <lcd.c>

#INT_EXT
void alarma1(void) //Interrupción pulsador manual alarma zona1
{
 
   output_low(PIN_C0);
   output_low(PIN_C1);
   output_low(PIN_C2);
   output_low(PIN_C3);
   delay_ms(3000);
   
}
 
void main(void)
{
   set_tris_b(0b00000001); //input:   output:
   set_tris_c(0b00000000); //input:   output:
   
   ext_int_edge(H_TO_L);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL); //Todas las interrupciones activadas
   lcd_init();
   while (true)
   {
      output_high(PIN_C0);
      delay_ms(500);
      output_high(PIN_C1);
      delay_ms(500);
      output_high(PIN_C2);
      delay_ms(500);
      output_high(PIN_C3);
      delay_ms(500);
      output_low(PIN_C0);
      output_low(PIN_C1);
      output_low(PIN_C2);
      output_low(PIN_C3);
      lcd_putc('\f');
      lcd_putc("abcdefghijklmnop");
      delay_ms(500);
   }
}


y la libreria:

///////////////////////////////////////////////////////////////////////////
////                             LCDB.C                                ////
////                 Driver for common LCD modules                     ////
////                                                                   ////
////  lcd_init()   Must be called before any other function.           ////
////                                                                   ////
////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
////                     The following have special meaning:           ////
////                      \f  Clear display                            ////
////                      \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         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2007 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

//     B0 
//     B1  RW
//     B2  E
//     B3  RS
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7
//   (Sin 'RW') conectado a Masa
//
// Funciones soportadas:
//                         lcd_init()
//                         lcd_gotoxy( BYTE col, BYTE fila)
//                         lcd_putc( char c)
//                              \f  Clear display                             
//                              \n  Go to start of second line               
//                              \b  Move back one position


#define use_portb_lcd TRUE  //LCD conectado al puerto b.

struct lcd_pin_map {
   BOOLEAN unused1; // RB0
   BOOLEAN rw;      // RB1
   BOOLEAN enable;  // RB2
   BOOLEAN rs;      // RB3
   int data : 4;    // RB4-RB7
} lcd;

#if defined use_portB_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf81
   #else
    #locate lcd = 6
   #endif
   #define set_tris_lcd(x) set_tris_b(x)
#else
   //#locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf83
   #else
    #locate lcd = 8
   #endif
   #define set_tris_lcd(x) set_tris_d(x)
#endif

#ifndef lcd_type
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#endif

#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #12 en: 01 de Junio de 2009, 15:54:34 »
Prueba con la libreria que te adjunto, a ver si podemos solucionar este problema.
No contesto mensajes privados, las consultas en el foro

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #13 en: 01 de Junio de 2009, 15:59:29 »
 El backlight no esta relacionado con la lógica del LCD el lcd que estas utilizando es de 16x2 compatible con el hitachi no?, yo sacaría por el momento el backlight seguiría paso a paso textuales el pdf y pondría una resistencia mucho mas chica por ejemplo ahora tengo montado mi lcd con un pote de 100k (que era el único que tenía) en serie con una resistencia de 180 ohms.
Lo que quiero decir, bajale la resistencia esa en serie y tenés que ver los cuadraditos si es que tu lcd funciona correctamente y seguis los pasos correctamente (sin pic) después es cuestion de conectar todo nuevamente.
 se me ocurren 3 cosas por las cuales no ves los cuadrados:

1- El contraste está muy bajo (hay que bajar la tensión vee).
2- La fuente que estas utilizando no es buena y no puede entregar la corriente para alimentar todo el circuito y la consume todo el backlight (muy improbable).
3- LCD muerto en combate (no creo, yo lo herejie mucho al mio también  :D)...  
LAS MALVINAS SON ARGENTINAS!

Desconectado elnina

  • PIC10
  • *
  • Mensajes: 35
Re: lcd_init() --> No me funciona, desesperado
« Respuesta #14 en: 02 de Junio de 2009, 05:33:36 »
El contraste lo muevo con el pot a 10k, a 20k o menos, hay que poner mas de 20K??
EL lcd no creo, pq tengo dos distintos y no funciona ninguno
La fuente no es pq he probado con pila de 4.5v y transformador de 220/12v con lm7805  a 5v, la fuente da hasta 800mA

La libreria flex_lcd tampoco me fuciona, pero ya me pasa de la linea del init_lcd, a si q debe ser del hardware digo yo??

voy a probar lo del pdf
« Última modificación: 02 de Junio de 2009, 05:35:55 por elnina »