Autor Tema: Problemas con el LCD en PIC18F2550  (Leído 7065 veces)

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

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Problemas con el LCD en PIC18F2550
« en: 26 de Mayo de 2007, 16:21:36 »
Hola a todos, tengo un problema en el LCD usando el PIC18F2550 y antes de poner codigos, fotos y todo lo q llevo haciendo por lograr algo, quisiera q me digan si al LCD.c tengo q agregar o modificar algo, ya sea ahi o desde mi proyecto definiendo cosas y eso. Haber si me dan una manito  :lol:

Porcierto el lcd q tengo es de 2x16. Y en los puertos del LCD DB4,5,6,7 ¿tengo q poner los pines del PIC RD0,1,2,3 respectivamente? (almenos eso quiero)
Ojala puedan ayudarme :-)


salu2 8) 8)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problemas con el LCD en PIC18F2550
« Respuesta #1 en: 26 de Mayo de 2007, 16:27:27 »
Hola jeremylf

mira este post y revisa el circuito (ejemplo6_parte3.bmp) que está en el adjunto, es con el 18f4550y con el portb.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Problemas con el LCD en PIC18F2550
« Respuesta #2 en: 26 de Mayo de 2007, 17:47:59 »
Ola, e probado con el 18F4550 y va bien, el problema es con el 18F2550 y creo q el problema viene por la libreria LCD (lcd.c), almenos eso creo. Alguien me puede ayudar? nose si tengo q cambiar algo en esa libreria, ya sea ahi o en el proyecto  :?

Si de algo sirve uso un cristal de 4mhz y todo lo hago en el PICDEM 2 PLUS DEMO BOARD de MICROCHiP, compilado con CCS 4.023; los puertos RB4,5,6,7 del LCD van en los puertos RB0,1,2,3 del socket de 40 pines; entonces conecto esos pines del socket a sus pines del puerto RC0,1,2,3 para q se conecte con el socket de 28 pines y asi con el PIC, una imagen:


Para el PIC18F452 modifique el lcd.c desde hace mucho para q funcionara y recien hoy me doy cuenta q funciona tb con el 4550; y ahora tuve q modificar esa libreria ya modificada para q funcionara con el 2550, lo q hice ahora es esto:
Código: [Seleccionar]
////                             LCD_F452.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,2003 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.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//    PUERTO   LCD_DATO            PUERTO   DATO
//     C0         D4               A0      --       
//     C1         D5               A1      E
//     C2         D6               A2      R/W
//     C3         D7               A3      RS
//     C4         --
//     C5         --
//     C6         --
//     C7         --

//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
// #define use_porta_lcd TRUE
       

struct lcd_pin_map {                 // This structure is overlayed

           BOOLEAN unused;           // low order up.  ENABLE will
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rw;               // access to the LCD pins.
           BOOLEAN rs;               // The bits are allocated from             
           int     data : 4;         // be pin A0.

           int     data_b : 8;         // define puerto B
           int     data_c : 8;         // define puerto C           
//           int     data_d : 8;         // define puerto D
        } lcd;
 
 

#if defined use_portb_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_b(x) //
#else
   #locate lcd = getenv("sfr:PORTA")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_a(x)
#endif

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#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 = {1,1,1,1,0}; // For read mode data pins are in

BYTE lcd_read_byte() {
      BYTE low,high;                 // Define 2 registros.
      set_tris_c(LCD_READ);          // Define D0 - D3 como estradas.
      lcd.rw = 1;                    // RW=1, le decimos al LCD que estamos
      delay_us(1);//      delay_cycles(1);               // en modo lectura.
      lcd.enable = 1;                // E=1, para leer el dato del LCD hay que
      delay_us(1);//      delay_cycles(1);               // generar un CK de flanco positivo.
      high = (lcd.data_c & 0x0f);    // Leemos los 4 bit's MSB del LCD a traves
                                     // del puerto "D" (D4-D0) limpiando
                                     // el MSB y lo guardamos en "high"
      lcd.enable = 0;                // E=0, terminamos el pulso de CK.
      delay_us(1);//      delay_cycles(1);               // Generamos un delay de 1 ciclo de inst.

      lcd.enable = 1;                // E=1, le decimos al LCD que nos envie
      delay_us(1);                   // los 4 bit's LSB de datos. generando
                                     // un retardo de 1us.
      low = (lcd.data_c & 0x0f);     // Leemos los 4 bit's LSB del LCD a traves
                                     // del puerto "D" (D4-D0) limpiando
                                     // el MSB y lo guardamos en "high"     
      lcd.enable = 0;                // E=0, terminamos el pulso de CK.
     
      set_tris_c(LCD_WRITE);        // Define D0 - D3 como salidas.
      return( (high<<4) | low);     // retornamos de la sub-rutina con una
                                    // constante = "high-low"
}

void lcd_send_nibble( BYTE n ) {    // mandamos los datos al LCD.
      lcd.data_c = n;
      delay_us(1);//      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_us(1);//      delay_cycles(1);
      lcd.rw = 0;
      delay_us(1);//      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {                // Proceso de inicialización del LCD.
    BYTE i;                      // Definimos un registro llamado "i".
    set_tris_lcd(LCD_WRITE);     // Definimos el A1, A2, A3 como salidas.
    set_tris_c(LCD_WRITE);       // Definimos D0, D1, D2, D3 como salidas.

    lcd.rs = 0;                  // RS = A3, ponemos el puerto 0 lógico
    lcd.rw = 0;                  // RW = A2, ponemos el puerto 0 lógico
    lcd.enable = 0;              // E  = A1, ponemos el puerto 0 lógico

    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[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {  // Sub-rutina de ubicación del cursor
   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);    // clear display
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break; // Go to start of second line
     case '\i'   : lcd_gotoxy(1,1);        break; //     
     case '\b'   : lcd_send_byte(0,0x10);  break; // move back one position
     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);
}
*/
Nose pero creo q el problema venga de ahi o quiza de las conexiones, haber si se dan un tiempito porfa  :lol:

Ah y el codigo para hacer funcionar el lcd es algo tan simple como prender un led:
Código: [Seleccionar]
#include <18f2550.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#include <LCD_f2550.c>

void main(void)
   {
   lcd_init();
   lcd_putc("HOLA");
   }
Probando con el PIC18F452 y 4550 (cambiando los includes y eso claro) este codigo va bien. Gracias de antemano  :mrgreen:


salu2 8) 8) 8) 8)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problemas con el LCD en PIC18F2550
« Respuesta #3 en: 28 de Mayo de 2007, 11:28:34 »
a primera vista, te falta definir los pines para la LCD:

Código: C
  1. #define use_portb_lcd TRUE
  2.  
  3. #include <lcd.c>

si no lo defines, entonces lcd.c te tomará el porta


también recuerdo que tuve problemas con ese driver usando la versión 4.023, y entonces probé con una versión anterior y funcionaba, pero no hagas caso de esto último, prueba lo primero de arriba.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Problemas con el LCD en PIC18F2550
« Respuesta #4 en: 28 de Mayo de 2007, 17:50:28 »
Nada con eso se prende el led RB3 pero no funciona el LCD  :(

porfa, alguien puede ayudarme ?


salu2 8) 8)

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Problemas con el LCD en PIC18F2550
« Respuesta #5 en: 28 de Mayo de 2007, 18:45:33 »
No  se procupen ya me salio, el problema era en el codigo del lcd_f2550.c  falto cambiar letras por otras en este caso puertos y bueno las puse para el puerto B.
Alfinal quedo asi:

Código: [Seleccionar]
////                             LCD_F452.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,2003 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.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//    PUERTO   LCD_DATO            PUERTO   DATO
//     B0         D4               A0      --       
//     B1         D5               A1      E
//     B2         D6               A2      R/W
//     B3         D7               A3      RS
//     B4         --
//     B5         --
//     B6         --
//     B7         --

//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
// #define use_porta_lcd TRUE
       

struct lcd_pin_map {                 // This structure is overlayed

           BOOLEAN unused;           // low order up.  ENABLE will
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rw;               // access to the LCD pins.
           BOOLEAN rs;               // The bits are allocated from             
           int     data : 4;         // be pin A0.

           int     data_b : 8;         // define puerto B
           int     data_c : 8;         // define puerto C           
//           int     data_d : 8;         // define puerto D
        } lcd;
 
 

#if defined use_portb_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_b(x) //
#else
   #locate lcd = getenv("sfr:PORTA")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_a(x)
#endif

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#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 = {1,1,1,1,0}; // For read mode data pins are in

BYTE lcd_read_byte() {
      BYTE low,high;                 // Define 2 registros.
      set_tris_b(LCD_READ);          // Define D0 - D3 como estradas.
      lcd.rw = 1;                    // RW=1, le decimos al LCD que estamos
      delay_us(1);//      delay_cycles(1);               // en modo lectura.
      lcd.enable = 1;                // E=1, para leer el dato del LCD hay que
      delay_us(1);//      delay_cycles(1);               // generar un CK de flanco positivo.
      high = (lcd.data_b & 0x0f);    // Leemos los 4 bit's MSB del LCD a traves
                                     // del puerto "D" (D4-D0) limpiando
                                     // el MSB y lo guardamos en "high"
      lcd.enable = 0;                // E=0, terminamos el pulso de CK.
      delay_us(1);//      delay_cycles(1);               // Generamos un delay de 1 ciclo de inst.

      lcd.enable = 1;                // E=1, le decimos al LCD que nos envie
      delay_us(1);                   // los 4 bit's LSB de datos. generando
                                     // un retardo de 1us.
      low = (lcd.data_b & 0x0f);     // Leemos los 4 bit's LSB del LCD a traves
                                     // del puerto "D" (D4-D0) limpiando
                                     // el MSB y lo guardamos en "high"     
      lcd.enable = 0;                // E=0, terminamos el pulso de CK.
     
      set_tris_b(LCD_WRITE);        // Define D0 - D3 como salidas.
      return( (high<<4) | low);     // retornamos de la sub-rutina con una
                                    // constante = "high-low"
}

void lcd_send_nibble( BYTE n ) {    // mandamos los datos al LCD.
      lcd.data_b = n;
      delay_us(1);//      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_us(1);//      delay_cycles(1);
      lcd.rw = 0;
      delay_us(1);//      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {                // Proceso de inicialización del LCD.
    BYTE i;                      // Definimos un registro llamado "i".
    set_tris_lcd(LCD_WRITE);     // Definimos el A1, A2, A3 como salidas.
    set_tris_b(LCD_WRITE);       // Definimos D0, D1, D2, D3 como salidas.

    lcd.rs = 0;                  // RS = A3, ponemos el puerto 0 lógico
    lcd.rw = 0;                  // RW = A2, ponemos el puerto 0 lógico
    lcd.enable = 0;              // E  = A1, ponemos el puerto 0 lógico

    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[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {  // Sub-rutina de ubicación del cursor
   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);    // clear display
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break; // Go to start of second line
     case '\i'   : lcd_gotoxy(1,1);        break; //     
     case '\b'   : lcd_send_byte(0,0x10);  break; // move back one position
     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);
}
*/

Igual gracias de todos modos a los q quisieron ayudarme, gracias.


salu2 8) 8) 8)

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:Problemas con el LCD en PIC18F2550
« Respuesta #6 en: 20 de Enero de 2016, 14:33:00 »
Prueben la siguiente configuración:

Código: C
  1. #Include <18F2550.h>
  2. #use delay(clock=20M)
  3.  
  4. #define use_portB_lcd TRUE
  5. #fuses nowdt,noprotect,nolvp,hs
  6. //LCD handle:
  7. #define LCD_DB4   PIN_B4
  8. #define LCD_DB5   PIN_B5
  9. #define LCD_DB6   PIN_B6
  10. #define LCD_DB7   PIN_B7
  11. #define LCD_RS    PIN_B1
  12. #define LCD_RW    PIN_B2
  13. #define LCD_E     PIN_B0
  14.  
  15.  
  16. //LCD library:
  17. #include  <lcd.c>
  18.  
  19. //Main program:
  20. void main()
  21. {
  22. while(true)
  23. {
  24. lcd_init();
  25. printf(lcd_putc,"HOLA");
  26. delay_ms(8);
  27. }
  28. }

Desconectado HumbertoN

  • PIC10
  • *
  • Mensajes: 5
Re:Problemas con el LCD en PIC18F2550
« Respuesta #7 en: 14 de Mayo de 2020, 16:57:27 »
Hola! Disculpa podrías poner foto de la conexión que hiciste del pic al lcd? Ya que a mí no me funciona