[PIC] LCD 4x20 Initialisation problem

Status
Not open for further replies.

Date

Newbie level 3
Joined
Jun 1, 2014
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
35
Hello everyone,

I've got a big problem ( I guess ?) with my LCD 4x20 :

Here's the datasheet : **broken link removed**

When i send to him my initilisation code , I've got nothing but only two lines of dark squares (line 1 and 3)
My code is actually working on little LCD's displays (16x2) and also on a pic development board.

So I guess there is something wrong with the init routine , but i don't understand a thing about the datasheet, someone told me that with my code I was supposed to make it work , but it seems not.

I'm working with Mplabx 2.10 and my Pic is a 18f4580.
I've checked all my connections and nothing is wrong , my contrast pot is also working well and I want to work on 4bits mode.

So the only problem is and must be the program.

Here's the lcd routine :

Code:
#include <xc.h>

#define LCD_RW	LATCbits.LATC5 						
#define LCD_RS	LATCbits.LATC7					 	
#define LCD_E   LATCbits.LATC6						

#define LCD_D4	LATDbits.LATD3
#define LCD_D5	LATDbits.LATD2
#define LCD_D6	LATDbits.LATD1
#define LCD_D7	LATDbits.LATD0

#define _XTAL_FREQ 8000000

#define LCD_STROBE	LCD_E=1; __delay_ms(5); LCD_E=0; __delay_ms(5);

// Ecrire un caract?re au LCD
void lcd_write(unsigned char c)
{
LCD_D7 = (c & 0x80) ? 1 : 0;
LCD_D6 = (c & 0x40) ? 1 : 0;
LCD_D5 = (c & 0x20) ? 1 : 0;
LCD_D4 = (c & 0x10) ? 1 : 0;
LCD_STROBE;

LCD_D7 = (c & 0x08) ? 1 : 0;
LCD_D6 = (c & 0x04) ? 1 : 0;
LCD_D5 = (c & 0x02) ? 1 : 0;
LCD_D4 = (c & 0x01) ? 1 : 0;
LCD_STROBE;
__delay_ms(5);
}

// Initialiser le LCD en mode 4 bits
void lcd_4bits_init(void)
{
   LCD_RW = 0;
   LCD_RS = 0;
   LCD_E = 1;
  // __delay_ms(15);

   LCD_D4 = 1;
   LCD_D5 = 1;
   LCD_STROBE;
   __delay_ms(1);

   LCD_STROBE;
   __delay_ms(1);

   LCD_STROBE;
   __delay_ms(5);

   LCD_D4 = 0;
   LCD_STROBE;
   __delay_ms(1);

   lcd_write(0x28);        // Mode 4 bits, 2 lignes
   lcd_write(0x0C);        // Display on, cursor off
   lcd_write(0x06);        //
   lcd_write(0x01);        // Clear display

LCD_RS = 1;
}

// Ecrire une cha?ne au LCD
void lcd_puts(const char *s)
{
   LCD_RS = 1;
   while (*s != '\0')
   {
       lcd_write(*s++);
   }
}

// Positionner le curseur
void lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write (0x80 + pos);
LCD_RS = 1;
}

// Effacer le display
void lcd_clear(void)
{
   LCD_RS = 0;
   lcd_write (0x01);
   LCD_RS = 1;
}

// Afficher un char en ASCII (d?cimal)
void lcd_ctoa(unsigned char data)
{
unsigned char digit;

digit = 0;
while(data >= 100)
{
data = data - 100;
digit++;
}
LCD_RS = 1;
lcd_write(digit + 0x30);	

digit = 0;
while(data >= 10)
{
data = data - 10;
digit++;
}
lcd_write(digit + 0x30);	
lcd_write(data + 0x30);	 
}

// Afficher un int en ASCII (d?cimal)
void lcd_itoa(unsigned int data)
{
unsigned char digit;

digit = 0;
while(data >= 10000)
{
data = data - 10000;
digit++;
}
LCD_RS = 1;
lcd_write(digit + 0x30);	

digit = 0;
while(data >= 1000)
{
data = data - 1000;
digit++;
}
LCD_RS = 1;
lcd_write(digit + 0x30);	

digit = 0;
while(data >= 100)
{
data = data - 100;
digit++;
}
LCD_RS = 1;
lcd_write(digit + 0x30);	

digit = 0;
while(data >= 10)
{
data = data - 10;
digit++;
}
lcd_write(digit + 0x30);	
lcd_write(data + 0x30);	 
}

So if someone need another informations about what i'm using or something else i'll be pleased to help.

Hope you'll find what's wrong because i'm starting to be completely mad.

PS: Sorry for the bad english , i'm not used to write in english

Edit 1 : I also use XC8. Tried to find on other posts or else , some new leads to find a solution , but still no idea working :s
 

Hi
Your code bit ugly
use following method

For LCD command write use following function

Code:
void lcdcmd(unsigned char value)
    {
LCD_RS = 0;
LCD_DATA= (value&0xf0);
LCD_STROBE;
LCD_DATA = ((value<<4)&0xf0);
LCD_STROBE;
__delay_ms(10);
    }

For LCD data write use following function

Code:
void lcddata(unsigned char value)
    {
LCD_RS = 1; 
LCD_DATA= (value&0xf0);
LCD_STROBE;
LCD_DATA = ((value<<4)&0xf0);
LCD_STROBE;
__delay_ms(10);
    }

For LCD Initialization

Code:
void lcd_init(){

LCD_EN =0;
 __delay_us(10);  
    lcdcmd=0X30;
         LCD_STROBE;
           __delay_ms(2);

       LCD_RS=0;
       __delay_us(10);  
    lcdcmd =0X30;
         LCD_STROBE;
    __delay_ms(2);

        LCD_RS=0;
       __delay_us(10);  
    lcdcmd=0X30;
           LCD_STROBE;
    __delay_ms(2);

       LCD_RS=0;
       __delay_us(10);  
    lcdcmd =0X20;
         LCD_STROBE;
    __delay_ms(2);

lcdcmd(0x28);
__delay_ms(15);
lcdcmd(0x01);
__delay_ms(10);
lcdcmd(0x06);
__delay_ms(10);
lcdcmd(0x80);
__delay_ms(10);
lcdcmd(0x0c);
__delay_ms(10);
                }

Hoped this will help
 

Ive had a similar problem some years ago, and if i remenber correctly in the end the problem was very simple, try to see on the datasheets the initialization delay, i would give it 25ms just in case.
 

There is no 'main()' in the code shown so isn't possible to see the order you send the initialization instructions to the LCD but I can suggest the usual reason for this is forgetting the very first thing on the last page of the data sheet - the delay between power being applied and the module being able to accept the first commands. Look under the 'POWER ON' in the flow chart, it needs at least 35mS to wake up before you can use it. I always allow longer, normally 100mS, as it only happens once it will hardly be noticable.

Try to use code like PA3040 shows, when several bits are being moved at once it is far more efficient to use the shift and masking method than testing each individual bit.

Brian.
 

Hi !

Thanks for helping me !

I already tried to double all the delays on my code. But i was thinking about something else , on my pin Enable of my LCD , i'm supposed to have 5v right ? Because I have just some mV...

Do i need to had something on it ? I checked the connections between this pin and my pic and I have no problems , so that's weird....

I'll try also your code PA3040 and see if something happen.

I'll keep you informed if something change.
 

#define LCD_STROBE LCD_E=1; __delay_ms(5); LCD_E=0; __delay_ms(5);
means the LCD_E pin is left in the low state except for a brief period (5mS) when you use the LCD_STROBE macro so it would be quite normal for the voltage to appear very low. You need an oscilloscope to see the real signal amplitude.

Brian.
 

The 4x20 LCD is no different from the 16x2 LCD. The initialization parameters is different but essentially is the same. The delay values are identical.

Delays are very important for proper LCD initialization. You need to add some delay between the LCD enable line pulses. This is important as the enable line pulse transfers the data on the DATA lines to the LCD.

Use a scope to check if the lines are actually pulsing it is very easy to make a mistake. Also check the data lines connecting the PIC to the micro-controller, during initialization some data lines like DATA0, DATA1 are made high or low depending on the command being set. So ensure the data lines are also behaving correctly.

The correct procedure must be like this.

1. Set Data on the DATA lines.
2. Make enable high, delay for a few micro-seconds.
3. Make enable low, wait again for a few seconds.

After the end of the initialization routine give a large delay of at least 200 msec.

20x4 LCDs also have different character maps, check the data sheet for this.

But first I suggest you check the DATA, enable, R/W line etc. make sure these are connected and controllable from the PIC. Some I/Os in the PIC may need special steps for configuration as outputs.

thanks
a
 

Hi people !

I come here with some good news !

Maybe it can help some people too , but I finally understood what was wrong , so :

In my main code I had to include <xc.h> and <lcd.h> , but actually the lcd.h i asked him to include wasn't the good one (in my project file), he was including the one in the headers files of microchip compiler XC8 folder , so my pins RS R/W and E , were not good.

This explain everything ! and now he is alive !


Thanks you very much for all your help ! That was very helpfull !
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…