Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

how to initialize LCD 16x2

Status
Not open for further replies.
The writecommand is only writing the high nibble. After the first few commands you need to write both nibbles. Do as it says in the datasheet. Note in the table, after writing 2 it then writes in pairs.


Mike.

I think the following sequence need to initialize LCD. which sequence need to write both higher and lower nibble

RD7 RD6 RD5 RD4
15ms wait
0011 Function set
0011 Function set
5ms wait
0011 Function set

0010 Function set 4 bit
0010 Function set 4 bit

NF** N - 0 = 1/8 or 1/11 duty (1 line),
0010 F - 0 = 5×8 dots,, ** = 10

0000 Display ON
1000

0000 clear display
0001

0000
0111 Entry mode set ID = 1 increment cursor position; S = 1 display shift
 
OK, here's my routines in C which should work fine,
Code:
//Initialises the LCD
void InitLCD(void){
    LCDTRIS &=0x0f;                                 //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}

//wait for the LCD to finish last command.
void WaitLCDBusy(void){
        LCDTRIS |=0x80;
    LCD_RS=0;
    LCD_RW=1;
    LCD_E=1;
    while(LCDPORT&(0x80));
    LCD_E=0;
    LCDTRIS&=0x0f;
    LCD_RW=0;
}

//Send a command to the LCD
void WriteCommand(unsigned char command){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS = 0;                     //setup to send command
    WriteNibble(command);                //write the high nibble
    WriteNibble(command<<4);        //then the low nibble
}

//Send a character to the LCD
void WriteChar(unsigned char chr){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS=1;                       //Setup to send character
    WriteNibble(chr);                    //write the high nibble
    WriteNibble(chr<<4);            //then the low nibble
}

//Send any 4 bits to the LCD
void WriteNibble(unsigned char command){
    LCDPORT &= 0x0f;                         //clear the data bits
    LCDPORT|=((command & 0xf0));    //or in the new data
    LCD_E = 1;                      //enable the LCD interface
    NOP();            //change to delay of 1uS
    NOP();
    NOP();
    LCD_E = 0;                      //disable it
}

Mike.
 
OK, here's my routines in C which should work fine,


Mike.

Hi mike
Thank you for helping me

This is how I have connected LCD with PIC

PORT D4 - LCD Data pin 4
PORT D5 - LCD Data pin 5
PORT D6 - LCD Data pin 6
PORT D7 - LCD Data pin 7

PORT RC4 - RS
PORT RC5 - RW
PORT RC6 - EN


I don't understand below two line in your routine

LCD_TRIS_RW=0;
LCD_RW=0;

Can you tell me What the pin configuration you have written your routine, Where are data pins RS, RW, EN pin connected ?

Code:
//Initialises the LCD
void InitLCD(void){
    LCDTRIS &=0x0f;                                 //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}
 
You should have a list of #defines in your .h file such as,
Code:
#define LCD_RS PORTAbits.RA3
#define LCD_TRIS_RS TRISAbits.TRISA3
#define LCD_RW PORTAbits.RA4
#define LCD_TRIS_RW TRISAbits.TRISA4
#define LCD_E PORTAbits.RA5
#define LCD_TRIS_E TRISAbits.TRISA5
Obviously, you need to change these to reflect YOUR connections.

Mike.
 
Obviously, you need to change these to reflect YOUR connections.

Mike.

I have done few changes but still not getting data on screen

C:
#define _XTAL_FREQ 8000000
#include <xc.h>


// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

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

#define LCD_RS LATCbits.LATC4
#define LCD_TRIS_RS TRISCbits.TRISC4
#define LCD_RW LATCbits.LATC5
#define LCD_TRIS_RW TRISCbits.TRISC5
#define LCD_E LATCbits.LATC6
#define LCD_TRIS_E TRISCbits.TRISC6

#define  LCDPORT      LATD
#define  LCDTRIS      LATD

void Port_pins_Initialized (void);
void WriteNibble(unsigned char command);
void WaitLCDBusy(void);
void WriteCommand(unsigned char command);
void WriteNibble(unsigned char command);

void Port_pins_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;
    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// all are output, Unused
    TRISC = 0b0000000;// RS RW EN
    TRISD = 0b0000000;//  LCD
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}
//wait for the LCD to finish last command.
void WaitLCDBusy(void){
        LCDTRIS |=0x80;
    LCD_RS=0;
    LCD_RW=1;
    LCD_E=1;
    while(LCDPORT&(0x80));
    LCD_E=0;
    LCDTRIS&=0x0f;
    LCD_RW=0;
}

//Send a command to the LCD
void WriteCommand(unsigned char command){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS = 0;                     //setup to send command
    WriteNibble(command);                //write the high nibble
    WriteNibble(command<<4);        //then the low nibble
}


//Initialises the LCD
void InitLCD(void){
    LCDTRIS &=0x0f;                                 //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}


//Send a character to the LCD
void WriteChar(unsigned char chr){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS=1;                       //Setup to send character
    WriteNibble(chr);                    //write the high nibble
    WriteNibble(chr<<4);            //then the low nibble
}

//Send any 4 bits to the LCD
void WriteNibble(unsigned char command){
    LCDPORT &= 0x0f;                         //clear the data bits
    LCDPORT|=((command & 0xf0));    //or in the new data
    LCD_E = 1;                      //enable the LCD interface
    NOP();            //change to delay of 1uS
    NOP();
    NOP();
    LCD_E = 0;                      //disable it
}


void buffer( unsigned char *p)
{

    while (*p != '\0')
    {
      WriteChar(*p);

        p++;
    }
}

void main ()
{
     unsigned int i = 0;
   unsigned char Data1 [20]="Hello World";
    InitLCD();
    Port_pins_Initialized ();
     buffer(Data1);
    while (1)
    {
        
    }
}
 
Try initializing your pins before the LCD, thay may be set to analogue. If it still doesn't work then where does it get to?

Mike.
 
Try initializing your pins before the LCD, thay may be set to analogue. If it still doesn't work then where does it get to?

Mike.
I have done that still data doesn't display on the screen. but one change I have seen that LCD doesn't show any black boxes
 
And, where does it stop?

Mike.
Screenshot
IMG_20201008_125413.jpg



I think the LCD has been initialized but the data routine has some fault that needs to be corrected
 
Here's your problem,
Code:
#define  LCDTRIS      LATD
It needs to be TRISD.

Mike.
 
Here's your problem,
Code:
#define  LCDTRIS      LATD
It needs to be TRISD.

Mike.

I did that but no luck

C:
#define _XTAL_FREQ 8000000
#include <xc.h>


// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

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

#define LCD_RS LATCbits.LATC4
#define LCD_TRIS_RS TRISCbits.TRISC4
#define LCD_RW LATCbits.LATC5
#define LCD_TRIS_RW TRISCbits.TRISC5
#define LCD_E LATCbits.LATC6
#define LCD_TRIS_E TRISCbits.TRISC6

#define  LCDPORT      LATD
#define  LCDTRISD      LATD

void Port_pins_Initialized (void);
void WriteNibble(unsigned char command);
void WaitLCDBusy(void);
void WriteCommand(unsigned char command);
void WriteNibble(unsigned char command);

void Port_pins_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;
    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// all are output, Unused
    TRISC = 0b0000000;// RS RW EN
    TRISD = 0b0000000;//  LCD
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}
//wait for the LCD to finish last command.
void WaitLCDBusy(void){
        LCDTRISD |=0x80;
    LCD_RS=0;
    LCD_RW=1;
    LCD_E=1;
    while(LCDPORT&(0x80));
    LCD_E=0;
    LCDTRISD&=0x0f;
    LCD_RW=0;
}

//Send a command to the LCD
void WriteCommand(unsigned char command){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS = 0;                     //setup to send command
    WriteNibble(command);                //write the high nibble
    WriteNibble(command<<4);        //then the low nibble
}


//Initialises the LCD
void InitLCD(void){
    LCDTRISD &=0x0f;                                 //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}


//Send a character to the LCD
void WriteChar(unsigned char chr){
    WaitLCDBusy();                  //wait until not busy
    LCD_RS=1;                       //Setup to send character
    WriteNibble(chr);                    //write the high nibble
    WriteNibble(chr<<4);            //then the low nibble
}

//Send any 4 bits to the LCD
void WriteNibble(unsigned char command){
    LCDPORT &= 0x0f;                         //clear the data bits
    LCDPORT|=((command & 0xf0));    //or in the new data
    LCD_E = 1;                      //enable the LCD interface
    NOP();            //change to delay of 1uS
    NOP();
    NOP();
    LCD_E = 0;                      //disable it
}


void buffer( unsigned char *p)
{

    while (*p != '\0')
    {
      WriteChar(*p);

        p++;
    }
}

void main ()
{
     unsigned int i = 0;
   unsigned char Data1 [20]="Hello World";
    Port_pins_Initialized ();
    InitLCD();
  
     buffer(Data1);
    while (1)
    {
        
    }
}
 
Then your hardware is wrong. Did we find out where in the code it stops?

Mike.
 
If it's now working then I suspect your R/W line has a problem. But, congratulations, hope the rest of your project can now proceed.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top