[Tut] – Using HD44780 based LCDs – JHD162A

I finally dug out that LCD from the mess in my room and got it to work :). Turns out , its really simple. You dont even need a microcontroller to do it.

Ok. Lets get started :

dsc01984-large

Front View of the LCD

That is the LCD that i bought from SP road (kwality electronics) for 100 bucks. It incorporates the widely popular HD44780 pin configuration. It has 16 pins.

This is how it looks from the back :

LCD  JHD 162A HD44780 Compatiable

Back view of the LCD

There are 16 pins in all. They are numbered from left to right 1 to 16 (if you are reading from the backside) . My LCD came with a marking to indicate which was the 1st pin and which was the 16th. You can see the markings right next to 1st and 16th pins.

I took the back view pic after I soldered a 8 pin connector between the 7 to 14 pins to make it easier to work with. When you buy the LCD ,all the pins will be bare. ( like in the first pic).

Did you notice that there is a fine film covering the LCD display in the first pic? DON’T remove it until you finish soldering wires and connectors to the pins. Otherwise ,the flux and the alcohol that you use during the soldering process will ruin the LCD.

What do the 16 pins do?

lcd pin connections

Solder a 8 Pin connector to the Data pins and wires to the others

Solder a 8 Pin connector to the Data pins and wires to the others

Pin 1 and 2 are the power supply pins. They need to be connected to the negative rail and the postive rail of a +5v power supply respectively. To get a stable +5v Power supply , you can use a 7805 voltage regulator. It will regulate any voltage that you give it into +5v. If you are confused about using the 7805 , check out this tutorial.

Pin 3 is the contrast setting pin. It is said that it must be connected to a potentiometer to control the contrast. However , i have found that it work if you just connect a variable resistor in series with it to GND. The lower the resistance , the greater the contrast. I recommend setting it at around 1.5K – 2K. If you set the value too low or short the pin directly to ground , you will see only dark boxes on the screen. As far as i know , doing this does not have any adverse affect on the LCD.

If putting the Var-resistor does not work out for you , try the old fashioned method with a 10K pot. You must set the voltage to around 1-1.5V for optimum contrast.

Pins 4 , 5 and 6 are control pins of the LCD. I’ll explain about them later on in the post.

Pins 7 to 14 are the Data pins of the LCD. Pin 7 is the Least Significant Bit (LSB) and pin 14 is the Most Significant Bit (MSB) of the data inputs. If you want to display some number or letter on the display , you have to input the appropriate ‘codes’ for that character on these pins. These pins are also used for giving certain commands to the display like clearing the display or moving the cursor to a different location. Upon giving the correct signals to the 3 control pins , the character codes or the commands that you have given to the Data pins will be written to the display or executed by the LCD respectively. To make it easier to give the appropriate inputs to these pins , i recommend wiring up a DIP switch to these pins.

Pins 15 and 16 : Most LCDs have a backlight. A backlight is a light within the LCD panel which makes seeing the chracters on screen easier. When you leave your cell phone or mp3 player untouched for sometime , the screen goes ‘dark’. That is the backlight turning off. It is possible to use the LCD without the backlight as well. Many LCDs come without a backlight. If your LCD has only 14 pins , then it has no backlight. However , the working of the LCD still remains the same even if your LCD doesnt have a backlight. The Backlight is nothing but an LED. So , a resistor must be connected in series with it to limit the current. I am not sure about what value of resistor must be used. This link mentions that the allowable current is 100ma. Then it is best to have a variable resistor (or a transistor) and adjust the current till it is around 90 ma.

Now for the important part : The 3 control pins : R/S , R/W and E

LCD Control Pins

The RS Pin

The LCD has basically two operating modes : Instruction mode and Character Mode

Depending on the status of this pin , the data on the 8 data pins (D0-D7) is treated as either an instruction or as character data.

You have to activate the command mode if you want to give a Instruction to the LCD. Example – “Clear the display” , “Move cursor to home” etc.

You have to activate the character mode if you want to tell the LCD to display some character.

To set the LCD in Instruction mode , you set the 4th pin of the LCD (R/S) to GND. To put it in character mode , you connect it to Vcc.

The Enable Pin

The enable pin has a very simple function. It is just the clock input for the LCD.  The instruction or the character data at the data pins (D0-D7) is processed by the LCD on the falling edge of this pin. The Enable pin should be normally held at Vcc by a  pull up resistor. When a  momentary button switch is pressed , the Pin goes low and back to high again when you leave the switch. Your instruction or character will be executed on the falling edge of the pulse. (ie. The moment the switch closes)

The RW Pin

Generally , we always use the LCD to show things on the screen. However , in some rare cases , we may need to read from the LCD what it is displaying. In such cases, the R/W pin is used. However , this function is beyond the scope of post and will not be explained. For all practical purposes , the R/W pin has to be permanently connected to GND.

The flowchart for operating the LCD

LCD write Sequence

Making the hardware required for driving the LCD

Ok. Now that you have understood this , before starting , it would be more convenient if you soldered together a board with connectors and buttons for controlling all the pins.

Here’s the circuit :

Circuit for the LCD

Circuit for the LCD

You  can solder together a board or you can mount the components on a breadboard. It is upto you to decide.

Note : In the diagram , The RS switch is a press and hold switch , and the Enable switch is a momentary switch. There is a capacitor across The Enable switch for debouncing.

Its not very convenient to have 8 wires and try to make them HIGH or LOW on breadboard. Hence , i recommend that you use a DIP switch along with 8 pin SIP connectors. This is the thing that i made for the job :

The DIP switch on a PCB

The DIP switch on a PCB

dsc02104-large

The DIP switch connected to the LCD

The circuit is very simple and you need only 8 pull down resistors (1K) to make the circuit. You can even use a SIP resistor pack to save space and soldering time.

Circuit for wiring the DIP switch

Circuit for wiring the DIP switch

I have mounted the DIP switch on quite a large PCB. You can make a small one if you want to conserve space.

Download the PCB files from here and make your own DIP switch board.

Join together two female connectors to make a female-female connector. Solder a male connector on the LCD data pins.

Now that you are ready with the supporting hardware, lets get started with the real stuff.

Double check the connections

But first , before powering up the LCD , double check all these things.

1) No pins are shorting on the backside of the panel. (It can happen if you have not cleaned the board after soldering)

2) The contrast pin (3) (Vee) is correctly configured.

3) The backlight (pins 15 , 16) has a resistor in series to limit current.

4) The DIP switch board is working properly.

5) The R/W pin is tied to ground.

6) The circuit is being powered by +5v. This is very important. Dont zap your LCD by accidentally powering it with 12V.

7) The connector for connecting the 8 data pins from the DIP switch board to the LCD is proper. Double check for any loose wires and any mismatched wires on the connector.

Get started with the real stuff

The LCD showing my name

The LCD showing my name

if you are sure that nothing is wrong with your setup , then go ahead and power up you LCD.

See nothing at all on the LCD? Dont panic. Thats what is supposed to happen.

Initializing the LCD

To make the LCD show some signs of life , you need to issue an instruction to it. That instruction is 00001111. Since you are giving an instruction to the LCD , you have to put it in instruction mode by holding the RS pin to GND. In the board that you wired up, you can put RS at GND by pressing the RS push and hold button, such that it remains in a depressed state.

Now , your LCD is in instruction mode and is ready to accept any instruction that we issue to it. Now , set the DIP switches as 00001111. This instruction tells it to turn on the display and show a blinking cursor. Once , you have set the DIP switch to 00001111 , press the Enable momentary Button. You should be seeing a blinking cursor on the screen now. This means that your LCD is initialized and ready to accept characters to display.

Wait , you did not get a blinking cursor? Triple check if your connectors and switches are proper. Check if you have accidentally reversed the MSBs and LSBs on each side of the connector. Check your soldering to see if there are any cold solder joints.

Making characters show up on the display

Ok , once you have got the cursor blinking , the LCD will now accept character data to display. Now , we have to put the LCD in character mode to make it accept characters to display. Press the RS switch to make it ‘undepressed’. Now set the DIP switches to 01000001 and then press the Enable button. If everything has gone right , then you should be seeing a capital A on the screen. But what if you want to display some other letter , like “M”? The procedure is the same , you only replace the 01000001 with the code for M , which is 01001101. The LCD automatically increments the cursor position by 1 everytime you write a character. Try the same thing for “M” , M will appear to the right of A.

After you write to the last location of the first line , you would expect the LCD to automatically jump to the second line. Sadly , it doesnt happen so. Using the second line is slightly more tricky. I’ll explain that in a later post.

Using a µController with the LCD

It is quite a pain to manually do this procedure every time. Using µControllers to automatically send the data and the required signals simplifies the entire job. Here is a video that i took of the LCD being controlled by a Attiny2313. It automatically writes my name continuously in a loop.

Some additional stuff

Here is an online LCD simulator. Practice everything on it first before practically trying it on your LCD.

Download the datasheet for the LCD JHD162A (which i’ve used in this tutorial).

Download the datasheet for HD44780 which is the chip that controls the LCD.

Here’s the instruction set for the LCD which i’ve copied and pasted from the LCD datasheet for your reference :

Instruction Set for the LCD

Instruction Set for the LCD

Here’s the character code table for the LCD which shows the corresponding binary values for each character :

Character Table for the LCD

Character Table for the LCD

Thats it , you now know how to use an LCD!!  Have fun playing with your LCD module !! :)


68 Comments on “[Tut] – Using HD44780 based LCDs – JHD162A”

  1. jafar says:

    sir,

    I am using same lcd but i m not able adjust contrast for lcd. pot is 10k…i am doing this in 8051 development board only. plz tell me how to adjust contrast and what is value for that. i am waiting for reply….

    plz sir,

  2. iamsuhasm says:

    Try shorting the adjust pin directly to ground. Black squares should appear on your LCD top panel (and bottom panel if you have enabled dual mode). This will confirm if your LCD is proper.

    How have you connected the 10K pot? I did not use a pot at all , but instead i used a variable resistor (2.2K) connected in series with the contrast pin and ground. That seemed to work just as well.

    Why dont you try that?

  3. Amit says:

    I tried shorting the adjust pin to ground and only some of the boxes got black while others did not, does this mean lcd does not work or it works only partially
    Will the remaining blocks display anything.

    • iamsuhasm says:

      If you short the adjust pin , then only the top row blocks will darken. The bottom row boxes will not change. This is normal behavior. If this is what is happening with your LCD , then nothing’s wrong.

  4. ar says:

    connect adjust pin to +5 V and not ground, this will set maximum contrast..

  5. iamsuhasm says:

    @Ar ,
    If you connnect the contrast pin directly to Vcc , then it will be minimum contrast , not maximum.
    Maximum contrast is at ground. For optimum contrast , the contrast pin must be set to around 1V. You can put a 10K pot and twiddle along with the voltage until you get the contrast required.

  6. gaurav ahuja says:

    Hey the link to JHD162A datasheet isnt working could you please mail me the datasheet at g********9@gmail.com

  7. Gaurav Ahuja says:

    Hi ive been trying for so many days to get my LCD JHD162A to work. But it doesnt seem to work. All i see is two black lines. i am using atmega8 and the LCD in 4 bit mode with the following connections:
    DB4 -> PC0
    DB5 -> PC1
    DB6 -> PC2
    DB7 -> PC3
    RS -> PB1
    RW -> PB2
    E -> PB3

    If possible please email me the C program for it, or the initialisation sequence.

  8. Lands says:

    i want to know how to clear the display?

  9. prince garg says:

    i am having a typical problem. It seems as if the columns of font table have interchanged. If i try to print the fonts of column 4 (P,Q,R,S,T,U,V,W.X,Y,Z….),what i get on the lcd is column number 3 (@,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O).On the other hand, fonts of column 3 are coming as they should.. I m using pic 16f917. Please reply to my query…

  10. farrukh says:

    hey thanks a lot for the tutorial, i used a 8051 instead of the manual circuitry but your concepts helped a lot. i had been stuck with the lcd for a couple of days and your blog cleared a lot of things…:D

  11. chandresh says:

    can i use some other variable voltage supply for contrast adjustment?
    And can i see the display if i connect it to direct Vcc?

  12. Darshan says:

    Hi Suhas,
    We have written the following code for displaying the message on JHD162A LCD using AT89S52 uc.
    Are there any bugs in the program.Please help us.
    Can u reply me on my mail. darshanadakane@gmail.com

    #include
    #include
    #include
    void lcdcmd (unsigned char value);
    void lcddata (unsigned char value);
    void MSDelay (unsigned int time);
    void DispMsg (char *Disp);
    void DispChar (char CHAR);
    sfr ldata=0x80;
    sbit rs=P2^0;
    sbit rw=P2^1;
    sbit en=P2^2;
    void main ()
    {
    unsigned char str [20], str1 [20];
    int a, b, total;
    a=2; b=5;
    total=a*b;
    P0=0x00;
    sprintf(str1,”TRAIN IS COMING “);
    strcpy (str,”*HITECH COLLEGE*”);
    lcdcmd (0x38); //2line 5×7 matrix
    MSDelay (25);
    lcdcmd (0x0E); //
    MSDelay (25);
    lcdcmd (0x01);
    MSDelay (25);
    lcdcmd (0x0F);
    MSDelay (25);
    //lcdcmd (0x06);
    //MSDelay (25);
    //lcdcmd (0x86);
    lcdcmd (0x80);
    MSDelay (25);
    DispMsg (str1);
    // lcdcmd (0xc5);
    lcdcmd (0xc0);
    MSDelay (25);
    DispMsg (str);
    MSDelay (250);
    MSDelay (2500);
    }
    void lcdcmd (unsigned char value)
    {
    ldata=value;
    rs=0;
    rw=0;
    en=1;
    MSDelay (1);
    en=0;
    return;
    }
    void lcddata (unsigned char value)
    {
    ldata=value;
    rs=1;
    rw=0;
    en=1;
    MSDelay (1);
    en=0;
    return;
    }
    void MSDelay (unsigned int itime)
    {
    unsigned int i,j;
    for(i=0;i<itime;i++)
    for (j=0;j<100;j++);
    }
    void DispMsg (char *Disp)
    {
    while (*Disp)
    DispChar (*Disp++);
    }
    void DispChar (char CHAR)
    {
    lcddata (CHAR);
    }

  13. Aditya says:

    Hey,

    Very good tutorial and a startup guide. The Datasheet link is not working… Could you please upload the datasheet on your server or email it to me?

    Aditya

  14. [...] may consider taking a look at this link to get a good understanding of the LCD, I find it is simpler to use in 4 bit mode. Here is an [...]

  15. Stankiewicz says:

    Hi! I have the same LCD screen. But it doesn’t turn on his backlight. :( can it be broken?

  16. Pramanik says:

    Sir
    I am a beginner in this field. I have purchased GDM1602A LCD. Could any one please tell me how to add/ use counter with the LCD GDM1602A or JHD162A LCD.
    Pramanik

  17. rohit says:

    I am looking for an LCD without an in-built LCD controller. So that I could use ATMEGA169 as the LCD controller to control it. I have searched a lot and I am not finding one.

  18. noe says:

    hola

    tengo una duda los orificios que tiene del lado izquierdo no se utilizan???

  19. Abhi says:

    how to display characters on the second line of the lcd i m using jhd 162a and at89s52 uc.thank you

  20. ABHIKRANT says:

    thank you very much for the blog…
    it realy helped me to display alphabets on the lcd…

  21. abhikrant says:

    thank u very much for the blog…
    i would like to know how to shift the cursor to the next line…
    plz can u mail me something at abhikrant@yahoo.co.in

  22. Avisek Dasgupta says:

    i have successfully displayed what i want on the lcd 1st row but not able to display anything on the 2nd line…please help..plz let me know the instruction to take the cursor to the 2nd line.

    • Sandy says:

      Just send 0x80 as an instruction to the LCD. That should bring the cursor to the beginning of the 2nd line. The span of the 2nd is usually from 0x80 to 0x8F for a 16×2 or 16×4 display.

  23. akshay says:

    sir,
    i am trying to interface the same lcd jhd 162a with my 89c51 but i get no characters on the lcd screen..i am howeer able to see the contrast blocks..

    can u explain it to me?

  24. bucuresti says:

    Be successful and, Also unlike traditional?Einem Anbieter Ein, of Mother Natures.You to become, with significant amounts.Programs are Google bucuresti, Rate The figure weeks of following.Rouge profess of, of insurance in.,

  25. kunal says:

    very good discription.
    i have using 89c51 microcontroller to interfacing lcd jhd 162a.
    plz send me assembly code for 4bit mode.

  26. yeshasvi says:

    dude can we solder the LCD . Will it not damage the LCD module ?

  27. nachiket says:

    hey,
    my problem is that…after the connections are done the LCD lights up and shows a test screen with 16cols in the 1st line all dark after this nuthing happens whatsoever.
    m using LCD JHD162A connected to my parallel port and try 2 clear the display using the given commands acc. 2 d datasheet it dusnt clear the screen nor it prints nething on d LCD.
    also i tried to clear the screen and blink the cursor, but with no luck! m using VS2008, and WinXP. can ne1 seem 2 figure out the prob? Thx in anticipation
    -regards!

  28. Sunil says:

    I have interfaced JHD 162A Display with atmega32 but there is a problem in writing the commands to lcd because lcd dispalys nothing.
    Please help me.

  29. Jeffrey says:

    hi, I have try to use this LCD with PIC16f84A. But after I wrote my program into the pic, it oni get a single black square line, another line is empty.
    my hardware connection is:
    port B = DB0-7
    RA0 = RS
    RA1 = R/W
    RA2 = E
    VEE = Ground
    my program is as shown as below:

    //==========================================================================================
    // Author : Cytron Technologies
    // Project : SK18B (18 pin Starter Kit)
    // Description : Using PIC16F628 for LED Blinking
    //==========================================================================================

    // include
    //==========================================================================================
    #include

    // Configuration
    //==========================================================================================
    __CONFIG (0x3F22); //configuration for the microcontroller

    // Define I/O Pins
    //==========================================================================================
    #define lcd PORTB
    #define RS RA0
    #define EN RA1

    // Function prototype (every function must have a function prototype)
    //==========================================================================================
    void e_pulse(void);
    void delay(unsigned short i);
    void send_char(unsigned char data);
    void send_config(unsigned char data);
    void lcd_goto(unsigned char data);

    // Main function (main fucntion of the program)
    //=========================================================================================
    void main(void)
    {
    //set I/O input output
    TRISA = 0b00000000;
    TRISB = 0b00000000;

    while(1)
    {
    send_config(0b00000001); //clear display at lcd
    send_config(0b00000010); //Lcd Return to home
    send_config(0b00000110); //entry mode-cursor increase 1
    send_config(0b00001100); //diplay on, cursor off and cursor blink off
    send_config(0b00111000); //function set

    lcd_goto(0); //cursor start from beginning

    //display character on LCD
    send_char(‘ ‘);
    send_char(‘T’);
    send_char(‘E’);
    send_char(‘M’);
    send_char(‘P’);
    send_char(‘.’);
    send_char(‘A’);
    send_char(‘=’);

    lcd_goto(20); //cursor go to 2nd line of the LCD

    //display character on LCD
    send_char(‘ ‘);
    send_char(‘T’);
    send_char(‘E’);
    send_char(‘M’);
    send_char(‘P’);
    send_char(‘.’);
    send_char(‘B’);
    send_char(‘=’);
    }
    }

    //========================================================================
    // Function
    //========================================================================
    void delay(unsigned short i)
    {
    for(;i>0;i–);
    }

    void send_config(unsigned char data)
    {
    RS=0;
    lcd=data;
    delay(500);
    e_pulse();
    }

    void e_pulse(void)
    {
    EN=1;
    delay(500);
    EN=0;
    delay(500);
    }

    void send_char(unsigned char data)
    {
    RS=1;
    lcd=data;
    delay(500);
    e_pulse();
    }

    void lcd_goto(unsigned char data)
    {
    if(data<16)
    {
    send_config(0x80+data);
    }
    else
    {
    data=data-20;
    send_config(0xc0+data);
    }
    }

    • Jeffrey says:

      sorry, wrong code attached. this is my modify code.
      //==========================================================================================
      // Author : Jeffrey
      // Project : LCD test
      // Description : Using PIC16F84A for LCD display
      //==========================================================================================

      // include
      //==========================================================================================
      #include

      // Configuration
      //==========================================================================================
      __CONFIG (0x3FF); //configuration for the microcontroller

      // Define I/O Pins
      //==========================================================================================
      #define lcd PORTB
      #define RS RA0
      #define RW RA1
      #define E RA2

      // Function prototype (every function must have a function prototype)
      //==========================================================================================
      void e_pulse(void);
      void delay(unsigned short i);
      void send_char(unsigned char data);
      void send_config(unsigned char data);
      void lcd_goto(unsigned char data);

      // Main function (main fucntion of the program)
      //=========================================================================================
      void main(void)
      {
      //set I/O input output
      TRISA = 0b00000000;
      TRISB = 0b00000000;

      //Initial Condition
      delay(50000);

      send_config(0x02);
      send_config(0x38);
      send_config(0x0E);
      send_config(0x06);

      lcd_goto(0);
      send_char(‘H’);
      send_char(‘E’);
      send_char(‘L’);
      send_char(‘L’);
      send_char(‘O’);

      }

      //========================================================================
      // Function
      //========================================================================
      void delay(unsigned short i)
      {
      for(;i>0;i–);
      }

      void send_config(unsigned char data)
      {
      RS=0;
      lcd=data;
      delay(5000);
      e_pulse();
      }

      void e_pulse(void)
      {
      E=1;
      delay(5000);
      E=0;
      delay(5000);
      }

      void send_char(unsigned char data)
      {
      RS=1;
      lcd=data;
      delay(5000);
      e_pulse();
      }

      void lcd_goto(unsigned char data)
      {
      if(data<16)
      {
      send_config(0x80+data);
      }
      else
      {
      data=data-20;
      send_config(0xc0+data);
      }
      }

  30. parth temkar says:

    hi , dear suhas sir

    i have one big problem that in this video you had shown some extra circuit on bear-board is this thing required????

    plz reply me sir plz

    parth temkar

  31. mutha50 says:

    Sir,

    Thank you very much for this tutorial about LCD.
    I am using a 4×20 HD44780 compatible too on an ATMega16 Microcontroller but i don’t get hem work.
    It’s now 4 weeks that i’m trying to figure out what ‘s wrong with my LCD without succes.
    Here are my connections in 4bit mode:

    D4->PC0
    D5->PC1
    D6->PC2
    D7->PC3
    E->PC5
    RS->PC4

    LED-,D0,D1,D2,D3,R/W,VSS are grounded on original board.
    The backlight and the contrast pot (I get two lines with 20 black boxes each on display)are working good.
    I tested the LCD on a Microprocessor and it works.
    I also used my Microcontroller to program a serie of LEDS and it works.
    The two C-program that i am trying to use to drive my LCD,have been used on the other ATMega 16 Microcotnroller with succes.
    So, guys if you have any idea of what’s going on with my LCD please help me.

    Thanks in advance for your time.

  32. Master Kire says:

    thx a lot… ur post is so perfect that I almost forgot it was in english, now I got my LCD working pretty good for the arduino!!!

  33. Ed says:

    Thanks, I finally got this working this morning!

    Now it’s on to the Arduino!

    Ed

  34. isaketh says:

    heyy suhas….ur blog is quite useful …thanx dude

  35. tejesh rao r b says:

    hi,
    im a BE student and im using lpc2148 to display….the following is my code…i followed your concept but nothing is coming in lcd…its the same lcd which you used……

    #include
    #include

    void lcdready(void);
    void lcdcommand(void);
    void lcddatawrt(void);
    void lcd_amber(void);
    void delay(void);
    void delay1(void);
    void lcd_initialization(void);

    unsigned int n,i,j,x,r;

    int main (void) {

    IODIR1 = 0x00FF0000;
    IODIR0 = 0x70000000;
    PINSEL1=0x00000000;
    lcd_initialization();
    while (1)
    {
    delay1();
    lcd_amber();
    delay1();

    }
    }
    void delay(void){
    for(i=0;i<=62270;i++)
    for(j=0;j<=62270;j++);
    }

    void delay1(void)
    {
    int i;
    char k;
    for(k=0;k<=8;k++)
    {
    for(i=0;i<=400000;i++) ;
    }
    }
    void lcdcommand(void)
    {
    lcdready();
    IODIR1=0X00FF0000;
    IOPIN1 = n;
    IOCLR0=0x10000000;
    IOCLR0=0x20000000;
    IOSET0=0x40000000;
    IOCLR0=0x40000000;
    }
    void lcddatawrt(void)
    {
    lcdready();
    IODIR1=0X00FF0000;
    IOPIN1 = n;
    IOSET0=0x10000000;
    IOCLR0=0x20000000;
    IOSET0=0x40000000;
    IOCLR0=0x40000000;
    }
    void lcdready(void)
    { IODIR1=0X007F0000;
    IOSET1=0x00800000;
    IOCLR0=0x10000000;
    IOSET0=0x20000000;
    while((IOPIN1&0x00800000)== 0x00800000)
    {
    IOCLR0=0x40000000;
    IOSET0=0x40000000;
    }
    }

    void lcd_initialization(void)
    {
    PINSEL1=0x00000000;
    PINSEL2=0x00000000;
    n=0x00380000;
    lcdcommand();
    n=0x000c0000;
    lcdcommand();
    n=0x00060000;
    lcdcommand();
    n=0x00010000;
    lcdcommand();

    }
    void lcd_amber(void)
    {
    while(1){
    n=0x00800000;//start
    lcdcommand();
    n=0x00540000;
    lcddatawrt();
    n=0x00650000;
    lcddatawrt();
    n=0x006d0000;
    lcddatawrt();
    n=0x00700000;
    lcddatawrt();
    n=0x00650000;
    lcddatawrt();
    n=0x00720000;
    lcddatawrt();
    n=0x00610000;
    lcddatawrt();
    n=0x00740000;
    lcddatawrt();
    n=0x00750000;
    lcddatawrt();
    n=0x00720000;
    lcddatawrt();
    n=0x00650000;
    lcddatawrt();
    n=0x00c00000;//start
    lcdcommand();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x00530000;
    lcddatawrt();
    n=0x00650000;
    lcddatawrt();
    n=0x006e0000;
    lcddatawrt();
    n=0x00730000;
    lcddatawrt();
    n=0x006f0000;
    lcddatawrt();
    n=0x00720000;
    lcddatawrt();
    n=0x00900000;//start
    lcdcommand();
    n=0x00540000;
    lcddatawrt();
    n=0x00450000;
    lcddatawrt();
    n=0x004d0000;
    lcddatawrt();
    n=0x00500000;
    lcddatawrt();
    n=0x00200000;
    lcddatawrt();
    n=0x003d0000;
    lcddatawrt();

    }

    }
    i dont knw whats wrong please help me

  36. tejesh rao r b says:

    sorry its
    #include
    #include

  37. tejesh rao r b says:

    ive removed brackets
    #include stdio.h
    #include LPC21xx.H

  38. sid says:

    Excellent info. Can you please send me some link or the code in visual basic 6 to see the mouse move coordinates on LCD.

  39. Awesome bro just awesome tut bt plzzz upload the code alsooo so tat we can have an idea abt how to use it with ATMEGA 16 ….. regards Mayank Sharma

  40. Abraham says:

    @Suhas:Thanx a ton,man!!! I dreaded the LCD and ur tutorial helped me a lot!!!
    @Farrukh: The link you gave in reply to post 9 is also awesome….:)
    @Avisek: You could look into Farrukh’s link or check the code snippet from my code….:)
    …….
    ……..
    void gotopos(int line,int pos)
    {
    char data;
    (line==1)? (data=0x80):(data=0xC0); //Top line DDRAM address starts from 0x80 and 2nd line from 0xC0
    data +=pos;
    P1OUT &=~RS;
    P1OUT |=EN;
    senddata(data); //Send the cursor position
    P1OUT &=~EN;
    P1OUT |=EN;
    }
    …….
    …….
    Here RS is a macro having the bit no of the bit RS pin of LCD is connected to, so is EN (macro for ENABLE pin). I have pulled RW to ground as I don’t intend to read the busy flag. In case you have RW connected to another I/O pin, then pull the pin to ground.
    All the best….:)
    Btw…due to pin constrains I had to use a shift register to parallel load the data onto LCD…In other words, senddata() ensures that the data is recieved by DBx…:)

    For those still unsure
    …………
    ………..
    void senddata(char data)
    {
    int i=0;
    while(i<8)
    {
    ++i;
    (data & BIT7)? (P1OUT |=DAT) : (P1OUT &=~DAT) ; //The data is transfered bit by bit taken from bit 7 of data
    P1OUT |=CLK; //Clock of the shift register pulled high
    wait(1); //Wait for 1 ms
    P1OUT &=~CLK; //Transfer to the serial register over
    data<<=1; //The data is left shifted to tackle the next bit
    }
    }
    ………

  41. sugunachand says:

    I am new to both electronics and software. But after seeing this interested to learn some thing since the blog providing basic idea of LCD display working. Thank you very much.

  42. [...] direction. Post your language of preference so we can help you further. BigDog Tutorial: Using HD44780 based LCDs – JHD162A Reply With Quote View Profile + Post New Thread + Reply to Thread [...]

  43. bid says:

    thanks, been stuck with that lcd for long time.

  44. singG says:

    Hello Suhas I have these 2 programs which I intend to run on the board ( http://www.nskelectronics.in/files/8051_project_board.pdf ).Please let me know how to execute these….please let me know where I am going wrong …thanks

    /**********************************PROGRAM 1***************************/
    //Please note the LCD used in this board is JHD162A

    #include

    sbit EN = P3^4 ;
    sbit RS = P3^5;
    //sbit RW = ; //not mentioned on the schematic

    void delay();
    sfr P1_data = 0x90; //data lines are connected to LCD from port P1 – as per the circuit
    void delay(void);

    void cmd()
    {
    RS = 0;
    //RW = 0;
    EN = 1;
    EN = 0;
    delay();
    }

    void write_lcd()
    {
    RS = 1;
    //RW = 0;
    EN = 1;
    EN = 0;
    delay();
    }

    void init_lcd()
    {
    P1_data = 0x38;
    cmd();
    P1_data = 0x01;
    cmd();
    P1_data = 0x0c;
    cmd();
    P1_data = 0x86;
    cmd();

    P1_data = 0xdf;
    write_lcd();

    P1_data = 0x51 ;
    write_lcd();

    }

    void delay()
    {
    int i,j;
    for(i = 0; i< 75 ; i++)
    for(j = 0; j < 75 ; j++);
    }

    void main()
    {
    for(;;)
    init_lcd();
    }

    /**********************************************PROGRAM 2 *************************************/
    #include
    #include
    #include

    //ANSI STYLE PROTOTYPE
    void lcddata( unsigned char value);
    void lcdcmd( unsigned char value);
    void Delay( unsigned int itime );

    //SFR names declarations
    sfr lcd_port = 0x90;
    sbit RS = P3^5;
    sbit EN = P3^4;
    //sbit RW =

    void main(void)
    {
    unsigned int i,k = 0; //Delay variable
    char j = 0; //LED variable
    unsigned char l[10] = {0x38,0x0E,0x06,0x01,0x41};
    //unsigned char l[10] = {0x38,0x01,0x80};
    char str[] = “Helloworld”;
    char str1[] = “welcome”;
    char *p; //pointer declarations

    for(i = 0 ;i< 3 ; i++)
    lcdcmd(l[i]); //sending basic LCD commands to LCD

    for( p = str; *p ;p++)
    lcddata(*p);

    lcdcmd(0xC0); //0xC0 command for displaying on second line

    for( p = str1; *p ;p++)
    lcddata(*p);

    do{ //infinite loop for LCD scrolling
    lcdcmd(0x18); //0x18 command for LCD scrolling
    Delay(50);
    }while(1);
    }

    void Delay( unsigned int itime)
    {
    int i,j;
    for( i = 0; i < itime ;i++)
    for( j = 0; j < 1275; j++);
    }

    void lcdcmd( unsigned char value )
    {
    lcd_port = value;
    RS = 0; //register select = 0 for command mode
    EN = 1; //latch enable = HIGH
    _nop_();
    EN = 0; //latch enable = LOW
    Delay(10);
    return;
    }

    void lcddata( unsigned char value )
    {
    lcd_port = value;
    RS = 1; //register select = 0 for command mode
    EN = 1; //latch enable = HIGH
    _nop_();
    EN = 0; //latch enable = LOW
    Delay(10);
    return;
    }

  45. exam says:

    Thank you so much.
    you are realy help me
    thank you again

  46. qaisar azeemi says:

    hi;
    i want to display the following data on my lcd screen.

    volts(V) Amps()
    9.0 3.0

    it is displaying on the proteous simulator well but when i tried it to disply practically on hardware it just displayd first line with second line blank :-(

    i am using 89c52 microcontroller and JHD 162A LCD 16×2 display. i am using assembly to program it. Following is my code:

    ;………………program for LCD Display………………………………………………………………………………………………
    RS BIT P2.0
    RW BIT P2.1
    E BIT P2.2

    ORG 00H

    MAIN: MOV DPTR, #MYCOM

    C1: CLR A
    MOVC A,@A+DPTR
    ACALL COMNWRT ; call command subroutien
    ACALL DELAY ; GIVE LCD some time to process
    INC DPTR
    JZ SEND_DATA
    SJMP C1

    SEND_DATA: MOV DPTR,#MYDATA_1
    D1: CLR A
    MOVC A,@A+DPTR
    ACALL DATAWRT ; Call data subroutien
    ACALL DELAY
    INC DPTR
    JZ NEXT
    SJMP D1

    [b]NEXT: MOV A,#06H ; i think problem is in this routine
    CALL COMNWRT
    CALL DELAY

    MOV A,#0C2H
    CALL COMNWRT
    CALL DELAY

    MOV A,#10011001B ;4,,,12V
    CALL FORM_DATA

    MOV A,#0C9H
    CALL COMNWRT
    CALL DELAY

    MOV A,#01100110B; 1,,, 3A
    CALL FORM_DATA

    SJMP $[/b]

    FORM_DATA: ; im skiping mathamatical manipulations here for simplicity.

    DISPLAY: ADD A,#48 ; Convert data to ASCII codes and sent to lcd for display
    MOV P0,A
    CALL DATAWRT
    CALL DELAY
    RET

    COMNWRT: MOV P0,A ;Send command to lcd
    CLR RS ; RS=0 for command register
    CLR RW ; R/W=0 for write
    SETB E ; E=1 for high pulse
    ACALL DELAY
    CLR E ;E=0 FOR low pulse

    RET

    DATAWRT: MOV P0,A ;Copy data to port 1
    SETB RS ; RS=1 For data register
    CLR RW
    SETB E
    ACALL DELAY
    CLR E
    RET

    MYCOM: DB 38H,0CH,01H,06H,80H,0 ; COMMANDS

    MYDATA_1: DB “VOLTS(V) AMPS(A)”

    DELAY: MOV R3,#50
    HERE2: MOV R4,#255
    HERE: DJNZ R4, HERE
    DJNZ R3, HERE2

    RET

    i will be very thankfull to you for your help.

    Regards
    Qaisar Azeemi

  47. lam says:

    Dear iamsuhasm..
    First Thank you so much for your time make this site ,its very helpful for me to learn and know how make LCD work.Could you help me to know is possible to rewrite this code please :
    customChars[0] = Array(0, 4, 2, 31, 2, 4, 0, 0);
    to word (A), and how is call this code ie: hex..binaire ???
    and how converter this code. Thank you in advance your time.Sorry for my English and understand very littler in word computer .
    Best regards
    lam

  48. Charles says:

    Is the RS supposed to be high or low for instruction mode? You have contradictory information about this above.

    Thanks

  49. Manu M says:

    Thank you very much. Heavenly thanks. I didn’t tried. But i owe you. Thanks

  50. sneha says:

    i have a problem with pic18f46j11 controller.
    while doing programming, i got command execution correctly but data has not been displayed.

    can u please suggest me any solution for this???

  51. Katende Allan says:

    i need some help,i have just bought a JHD162A LCD,and have tried interfacing it with arduino but all in vain,tried every possible thing but cant get it to display anything,I connected it exactly like this and ran the hello world code,but am just getting the backlights lighting,no display text on the screen,i have tried grounding pin 5 of the LCD,still nothing,please help me get out of this state of quagmire,i have been doing the same circuit since yeaterday,at first i thought i had made a mistake in the connection,then i re-did everything but the same.I even thought i bought a faulty LCD,then went back and bought a new one but all the same.

  52. sameer thapa says:

    can any1 tell me hw we can type message in lcd ,i hav work with the code also but cant get……….

  53. [...] if you would like to know more about controlling these LCD devices I suggest this website, and the article “How to use intelligent L.C.D.s – Part One” by Julyan llett, [...]

  54. khushal says:

    excellent tutorial.I tried it on cyclone IV nano board.

  55. Ricardo says:

    Hi,
    I think you have an error on this tutorial…

    RS = HIGH means write
    RS = LOW means command..

    just need to switch it :)

    ps: thank you for this tutorial!

  56. udit daga says:

    void main()
    {
    DDRD=0xFF;
    DDRB=0xFF;
    PORTD=0b00000001;
    PORTC=0b00000100;
    PORTB=0b00110000;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    PORTB=0b00001110;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    PORTB=0b00000110;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    set_bit(PORTC,0);
    PORTB=0b01010101;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    PORTB=0b00000110;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    clear_bit(PORTC,0);
    PORTB=0b00010100;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    set_bit(PORTC,0);
    PORTB=0b01000100;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    clear_bit(PORTC,0);
    PORTB=0b00010100;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    set_bit(PORTC,0);
    PORTB=0b01001001;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    clear_bit(PORTC,0);
    PORTB=0b00010100;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);

    set_bit(PORTC,0);
    PORTB=0b01010100;
    clear_bit(PORTC,2);
    _delay_ms(5);
    set_bit(PORTC,2);
    _delay_ms(5);
    }

    this is the code that im using with an interface of atmega 16
    could you suggest if there are any bugs in the code
    connections: b0-b7:port b
    d0:enable
    d1:RW
    d2:RS

  57. Gouresh says:

    Hi Suhaas,
    i need to interface JHD 162A LCD to AT89S51 MCU and display string and a pulse count.
    It initially worked very well, I could see the string as well as the count value. But when i tried the program next day, the LCD shows black boxes. I tried changing the MCU, but the new MCU also gave required output, but failed after 2nd attempt onwards. Can anyone figure out what might be the fault.
    I trust the circuit and the code as well, since it worked well initially.
    I have tried the following
    1) ground the pin3 of the LCD.
    2) using delay before giving any commands.
    Please suggest something. Thanking in advance.
    Gouresh Phadke
    gouresh.phadke@yahoo.com

  58. Gouresh says:

    correction in email id
    gauresh.phadke@yahoo.com
    Thanks alot

  59. kevham says:

    hi suhas.. u hv given a very valuable information…
    I want to interface LCD JHD 162A with MSP430g2231…i hv tried many times..it doesnt work out.. Could u pls help me to get a successful output???

  60. Chris Birkett says:

    This is fantastic, thank you. First line works perfectly – but how do you get to the second? Googling hasn’t helped me so far and you don’t appear to have written your second article yet :P


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 38 other followers