Home  ›  Product Guides  ›  Electronics  ›  LCD: Interfacing with PIC Microcontrollers Part 2

Tags: , ,

LCD: Interfacing with PIC Microcontrollers Part 2

By SC Lim

RH2T Mag, Volume 5, Jun 2010

In previous issue, we discussed the general hardware structure, control pins, hardware connection, RAM and registers, and finally the instruction sets of the standard LCD module. Now let’s practice what we’ve learnt!


LCD Initialization

In this part, we will see the initialization with some of the coding examples in C using Microchip MPLAB IDE and HI-TECH C PRO compiler for the PIC10/12/16 MCU Family. These software are free of charge and the latest releases can be obtained from both Microchip and HI-TECH websites.


Before using the LCD for display purpose, LCD has to be initialized either by the internal reset circuit or sending set of commands to the LCD. User has to decide whether an LCD has to be initialized by instructions or by internal reset circuit. We will discuss both types of initialization here.

Initialization by Internal Reset Circuit

An internal reset circuit automatically initializes the HD44780U when the power is turned on. The Busy Flag (BF) is kept in the busy state until the initialization ends (BF = 1). The busy state lasts for 10ms after VCC rises to 4.5V. The following instructions are executed during the initialization.

  • Display clear
  • Function set:
    DL = 1; 8-bit interface data
    N = 0; 1-line display
    F = 0; 5 x 8 dot character font
  • Display on/off control:
    D = 0; Display off
    C = 0; Cursor off
    B = 0; Blinking off
  • Entry mode set:
    I/D = 1; Increment by 1
    S = 0; No shift

There are certain conditions that have to be met, if user wants to use initialization by internal reset circuit. These conditions are shown in the table below.


Power supply conditions using internal reset circuit

Figure below shows the test conditions which are to be met for internal reset circuit to be active.

Internal power supply reset

The problem with internal reset circuit is that it is highly dependent on power supply. It is not hard to meet this critical power supply conditions but it is often difficult to achieve when simple application are involved. Hence, usually the second method, initialization by instruction is used and is recommended most of the time.

If the electrical characteristics conditions listed under the table Power Supply Conditions using Internal Reset Circuit are not met, the internal reset circuit will not operate normally and will fail to initialize the HD44780U. For such a case, initialization must be performed by the MCU as explained in the next section, Initializing by Instruction.


Initialization by Instructions

Initializing LCD with instructions is relatively simple. Given below is a flowchart that describes the step to follow to initialize the LCD.

Flow chart for LCD 8-bit interface initialization

The first 3 commands are usually not required but are recommended when you are using 4-bit interface. So actually you can program the LCD starting from sending function set when working with 8-bit interface. Function set command depends on what kind of LCD you are using and what kind of interface you are using (refer to the table in LCD Command section).

For PIC16F877A, the typical configuration settings and the declaration of LCD pins are shown in the figure below.


A typical configuration settings and declaration of LCD pins for PIC16F877A


LCD Entry Mode

From Commands and Instructions set for LCD type HD44780 table attached at the end of this article, you can see that there are two bits which determine the entry mode for LCD:

a) I/D – Increment/Decrement bit

b) S – Display shift.

Since bit 2 is always set, we get four combinations of entry mode which are 0x04 (1002), 0x05 (1012), 0x06 (1102) and 0x07 (1112). So we get different results with these different entry modes. Normally entry mode 0x06 is used, which is no shift and automatic increment. Do try all the possible entry modes and see the results, I am sure you will be surprised.


Programming example for LCD Initialization in C Language

With the help of the above code, you are able to initialize the LCD. The sample code contains a function/subroutine – LCD_busy. This subroutine is used to call for delay so that there should not be any command or data sent to the LCD until it finishes executing the command. More on this delay routine is explained in the next section.


Checking the Busy Flag

As discussed in the previous section, there must be some delay which is needed to be there for LCD to successfully process the command or data. So this delay can be made either with a delay loop of specified time more than that of LCD process time or we can read the busy flag, which is recommended. The reason to use busy flag is that delay produced is almost the amount of time for which LCD need to process. So, it is best suited for every application.


Steps to Read Busy Flag

When we send the command, the BF or DB7 bit of the LCD becomes 1 and as soon as the command is processed the BF = 0. Following are the steps to be kept in mind while reading the Busy flag.

  • Select command register
  • Select read operation
  • Send enable signal
  • Read the flag
  • So following the above steps we can write the code in C as below…clip_image012

LCD Busy Flag routine in C Language

If you do not want to read the busy flag you can simply use delay routines to provide the specific amount of delays. You have to make sure the delays are reasonable by referring to Commands and Instructions set for LCD type HD44780 table. The example code can be obtained at Cytron’s SK40C (Enhanced 40 pins PIC Start-up Kit) product page. Busy flag cannot be checked when you are using SK40C because the R/W (Read/Write) pin of LCD is connected to Ground permanently. So read command is unable to be executed and delay routines must be used for the LCD functions. The main reason to have such design is to reserve more PIC I/O pins for other applications.

It is often important to initialize the function or uses function prototypes at the beginning of the program (please refer to source code provided here: www.robothead2toe.com.my)

Now that we are ready with the initialization routine and the busy routine for LCD, we’ll move on to the next section on how to send data and command to the LCD.


Sending Commands to LCD

In order to send commands we simply need to select the command register. Everything is same as we have done in the initialization routine. But we will summarize the common steps and put them in a single subroutine. Following are the steps:

  • move data to LCD port
  • select command register
  • select write operation
  • send enable signal
  • wait for LCD to process the command

Keeping these steps in mind we can write LCD command routine as:


Routine for LCD send command in C language


Setting Cursor Position on LCD

To set the cursor position on LCD, we need to send the DDRAM address.

Bit 7 6 5 4 3 2 1 0
Value 1 AD6 AD5 AD4 AD3 AD2 AD1 AD0

DDRAM address

The seventh bit is always 1, and bits 0 to 6 are DDRAM address (refer the LCD Commands and Instruction Set section). So if you want to put the cursor on first position the address will be ‘0000000’ in binary and 7th bit is 1. The address will be 100000002 or 0x80, so for DDRAM all address starts from 0x80.

For 2 lines and 16 characters LCD. The address from 0x80 to 0x8F are visible on first line and 0xC0 to 0xCF is visible on second line, the rest of the DDRAM area is still available but is not visible on the LCD, if you want to check this thing, then simply put a long sting greater than 16 character and shift the entire display, you will see all the missing character coming from the back. By this way you can create scrolling line on LCD (see more on shifting display in commands section).

Below is an example for setting cursor position on LCD:


An example for setting cursor at first line, 4th position


Sending Data to LCD

In order to send data we simply need to select the data register. Everything is same as the command routine. Following are the steps:

·move data to LCD port

·select data register

·select write operation

·send enable signal

·wait for LCD to process the data


LCD send data routine in C language

You have seen that it’s really easy to send command and data to LCD. What if we have a string to send to LCD? It’s simple. We will store the LCD string in the ROM of the PIC microcontroller and call the string character by character. A simple example is shown below.



LCD send string routine in C language



If you have been following this article until this stage, you should be able to configure and display characters on your LCD module using a PIC microcontroller. Have fun! The full sample source code can be obtained from Robot. Head to Toe website (www.robothead2toe.com.my). Please follow us in the next issue for more explanation on the advanced features of the LCD, such as creating custom characters and 4-bit data bus interfacing.



1. Hitachi HD66710 Datasheet

2. http://home.iae.nl/users/pouweha/lcd/lcd0.shtml

3. http://forums.bit-tech.net/showthread.php?p=490773

4. http://www.8052.com/tutlcd


12 Responses to “LCD: Interfacing with PIC Microcontrollers Part 2”

  1. Nadeesha Sandamali says:

    Excellent Lecture.Thank You

  2. Mohamed Hassan says:

    Dears, can i use the pic lcd library such as
    void Lcd_Init();
    void Lcd_Out(char row, char column, char *text);
    void Lcd_Out_Cp(char *text);
    void Lcd_Chr(char row, char column, char out_char);
    void Lcd_Chr_Cp(char out_char);
    void Lcd_Cmd(char out_char);
    and in case we can initiate this configuration how will be the sbits for this configuration ?
    Thanks in advance.

  3. Mohamed Hassan says:

    Dears, i tried to make the configuration of the 8-bit and when i try to print character i found it printed with different characters let me give an example when i tried to print “Mohamed Hassan” it was printed as “Mohamed Haccan” and aslo when i try to print a string of character for char txt it is printed as unknown characters so please can you provide me with your advice.
    Thanks in advance.

  4. Mohamed Hassan says:

    Dears, i finally found the thing that may made the miscommunication, i found the datasheet of my LCD LM162AFC to be worked normally we had to configure its font as 5*8 not 5*7 as you mentioned so please can you provide me with the code in case it can handle my error.
    Thanks in advance.

  5. weitao says:

    can make a tutorial on LCD JHD162A?

  6. hyng says:


    LCD JHD162A is using the same or equivalent controller of HD44780.

  7. weitao says:

    Can I know the full coding?

  8. weitao says:

    Is that possible to change the value of the character list in the CGROM ?

  9. cytron says:

    Hi weitao,
    Actually we published a tutorial on that topic in our RH2T magazine, vol. 6. Please give us some time to upload that tutorial to this site. Thanks.

  10. cytron says:

    Hi weitao,
    CGRAM is what you need to modify in order to create custom characters. The tutorial has been uploaded to this site. Please a look…

  11. weitao says:

    Why something LCD_senddata(‘1′) or LCD_senddata(49), the output is ‘4’ (display in LCD)?

  12. TATU says:

    I tried to make the configuration of the 4-bit but the display showed nothing. Can you send file lcd.c, system.h in 4 bit mode? Thank you!

Leave a Reply

Help us improve the wiki Send Your Comments