Watch the Video Tutorial:

LCDs are alphanumeric (or graphical) displays, which are frequently used in microcontroller-based applications. There are many devices in the market which come in different shapes and sizes. 
Some LCDs have 40 or more character lengths with the capability to display several lines. Some other LCD displays can be programmed to display graphic images. Some modules offer colour displays, while some others incorporate back lighting so that they can be viewed in dimly lit conditions. 
In terms of interfacing technique, we can group them in two categories:  Parallel LCDs and serial LCDs. 
Parallel LCDs like the popular Hitachi HD44780 series are connected to the microcontroller circuitry such that data is transferred to the LCD using more than one line and usually four data lines (4-bit mode) or eight data lines (8-bit mode) are used. 

Figure 1: LCD connection to PIC microcontroller

Serial LCD is connected to a microcontroller using one data line only and data is transferred using the RS232 asynchronous data communications protocol. Serial LCDs are generally much easier to use, but they are more costly than the parallel ones. In this article we will discuss only the parallel LCDs, as they are cheaper and are used more commonly in microcontroller-based projects. 
Low-level programming of a parallel LCD is usually a complex task and requires a good understanding of the internal operation of the LCD, including an understanding of the timing diagrams. The good news is that MikroC Pro for PIC compiler provides library functions for text-based LCDs, which simplify the use of external LCDs.  

The HITACHI HD44780 controller is commonly used in parallel LCD-based microcontroller applications and is one of the most popular LCD controllers used in many LCD modules in industrial and commercial applications and also by hobbyists. This module is monochrome and comes in different shapes and sizes usually with character lengths of 8, 16, 20, 24, 32, and 40 and 1, 2 or 4 lines. Each character consists of 5×8 or 5×11 dot matrix.

                           Figure 2: A 2×16 LCD Display

This LCD display device generally has 14 pins which are marked on the PCB with some models have 16 pins if the the device has a back-light built in. 

Function Pin Number Name Logic State Description
Ground 1 Vss 0V
Power supply 2 Vdd +5V
Contrast 3 Vee 0V to +5V
Control of operation 4 RS 0 D0-D7 are interpreted as commands
1 D0-D7 are interpreted as data
5 R/W 0 Write data (from microcontroller to LCD)
1 Read data (from LCD to microcontroller)
6 E 0 Access to LCD disabled
1 Normal operation
From 1 to 0 data/ commands are sent to LCD
Data/ commands 7 D0 0/1 Bit 0 LSB
8 D1 0/1 Bit 1
9 D2 0/1 Bit 2
10 D3 0/1 Bit 3
11 D4 0/1 Bit 4
12 D5 0/1 Bit 5
12 D6 0/1 Bit 6
14 D7 0/1 Bit 7 MSB

                                                   Table 1: Pin descriptions

Table 1 above shows the pin configuration and pin functions of a typical 14-pin LCD. If back-light is needed and available, The K pin should be connected to ground and pin A/Vee should be connected to positive supply via a series current limiting resistor as shown in figure 3 below.        


                             Figure 3: LCD connection to Port B of PIC Microcontroller     

  Download the HD44780 LCD controller datasheet for more information.  

            MikroC Pro for PIC LCD Library Functions

The mikroC PRO for PIC LCD library provides a large number of functions to control text-based LCDs with 4-bit data interface.  

  Lcd module connections

With mikroC, the first thing to do is to define the LCD module connections, specifying which pin of the PIC to use for which data line.

Command Description Code Example
extern sfr sbit LCD_RS: Register Select line. sbit LCD_RS at RB4_bit;  // Use RB4 pin as RS
extern sfr sbit LCD_EN: Enable line. sbit LCD_EN at RB5_bit;  // Use RB5 pin as EN
extern sfr sbit LCD_D7; Data 7 line. sbit LCD_D7 at RB3_bit;   // Use RB3 pin as D7
extern sfr sbit LCD_D6; Data 6 line. sbit LCD_D6 at RB2_bit;    // Use RB2 pin as D6
extern sfr sbit LCD_D5; Data 5 line. sbit LCD_D5 at RB1_bit;   // Use RB1 pin as D5
extern sfr sbit LCD_D4; Data 4 line. sbit LCD_D4 at RB0_bit;    // Use RB0 pin as D4
extern sfr sbit LCD_RS_Direction; Register Select direction pin. sbit LCD_RS_Direction at TRISB4_bit;
extern sfr sbit LCD_EN_Direction; Enable direction pin. sbit LCD_EN_Direction at TRISB5_bit;
extern sfr sbit LCD_D7_Direction; Data 7 direction pin. sbit LCD_D7_Direction at TRISB3_bit;
extern sfr sbit LCD_D6_Direction; Data 6 direction pin. sbit LCD_D6_Direction at TRISB2_bit;
extern sfr sbit LCD_D5_Direction; Data 5 direction pin. sbit LCD_D5_Direction at TRISB1_bit;
extern sfr sbit LCD_D4_Direction; Data 4 direction pin. sbit LCD_D4_Direction at TRISB0_bit;

Table 2. LCD module connections

Library Routines

Below are short descriptions of LCD library, For more information, please visit online the mikroC pro for PIC LCD library page.

This function initializes the LCD module.
Before you can use this function, the LCD module connections must be defined first as shown above in table 2.


// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;

//Initialize LCD module

This function prints text on Lcd starting from a position you specified.
Both string variables and literals can be passed as a text.
Before you can use this function, the LCD must be initialized. (check Lcd_Init() function ).
Prototype: void Lcd_Out(char row, char column, char *text);
Parameters: row: starting position row number
column: starting position column number
text: text to be written, can be a string variable or a text under double quotes

//Write text “StudentCompanion” on Lcd starting from row 2, column 1:
Lcd_Out(2, 1, “StudentCompanion”);

This function prints text on Lcd at current cursor position. Both string variables and literals can be passed as a text.
Before you can use this function, the LCD must be initialized. (check Lcd_Init() function ).
Prototype: void Lcd_Out_Cp(char *text);
Parameters: text: text to be written

// Write text “Hello!” at current cursor position:

This function prints character on Lcd starting from a position you specified.
Both string variables and literals can be passed as a character.
Before you can use this function, the LCD must be initialized. (check Lcd_Init() function ).
Prototype: void Lcd_Chr(char row, char column, char out_char);
Parameters: row: starting position row number. column: starting position column number. out_char: character to be written, can a text under single quotes

// Write character “a” at row 2, column 3:
Lcd_Chr(2, 3, ‘a’);

This function prints character on Lcd at current cursor position. Both string variables and literals can be passed as a character.
Before you can use this function, the LCD must be initialized. (check Lcd_Init() function ).
Prototype: void  Lcd_Chr_Cp(char out_char);
Parameters: out_char: character to be written

// Write character “b” at current cursor position:

This function sends command to LCD.
Before you can use this function, the LCD must be initialized. (check Lcd_Init() function ).
Prototype: void Lcd_Cmd(char out_char);
Parameters: out_char: command to be sent
Note : Predefined constants can be passed to the function, see Available Lcd Commands below.

// Clear Lcd display:

            Available Lcd Commands
Lcd Command                            Purpose 

  • _LCD_FIRST_ROW                        Move cursor to the 1st row
  • _LCD_SECOND_ROW                   Move cursor to the 2nd row
  • _LCD_THIRD_ROW                       Move cursor to the 3rd row
  • _LCD_FOURTH_ROW                   Move cursor to the 4th row
  • _LCD_CLEAR                                    Clear display
  • _LCD_RETURN_HOME                  Return cursor to home position, returns a shifted display to its original position. Display data RAM is unaffected.
  • _LCD_CURSOR_OFF                      Turn off cursor
  • _LCD_UNDERLINE_ON                  Underline cursor on
  • _LCD_BLINK_CURSOR_ON             Blink cursor on
  • _LCD_MOVE_CURSOR_LEFT           Move cursor left without changing display data RAM
  • _LCD_MOVE_CURSOR_RIGHT        Move cursor right without changing display data RAM
  • _LCD_TURN_ON                          Turn Lcd display on
  • _LCD_TURN_OFF                          Turn Lcd display off
  • _LCD_SHIFT_LEFT                        Shift display left without changing display data RAM
  • _LCD_SHIFT_RIGHT                      Shift display right without changing display data RAM


Display the words “Hello World” on the first line of the LCD and the words “LCD Display” on the second line as shown in the circuit diagram on figure 1 at the top.

// Lcd module connections
        sbit LCD_RS at LATB4_bit;
        sbit LCD_EN at LATB5_bit;
        sbit LCD_D4 at LATB0_bit;
        sbit LCD_D5 at LATB1_bit;
        sbit LCD_D6 at LATB2_bit;
        sbit LCD_D7 at LATB3_bit;
        sbit LCD_RS_Direction at TRISB4_bit;
        sbit LCD_EN_Direction at TRISB5_bit;
        sbit LCD_D4_Direction at TRISB0_bit;
        sbit LCD_D5_Direction at TRISB1_bit;
        sbit LCD_D6_Direction at TRISB2_bit;
        sbit LCD_D7_Direction at TRISB3_bit;
    void main()
      ANSELB = 0;                             // Configure PORTB pins as digital
      Lcd_Init();                                  // Initialize Lcd
      Lcd_Cmd(_LCD_CLEAR);              // Clear display
      Lcd_Cmd(_LCD_CURSOR_OFF);    // Cursor off
     Lcd_Out(1,1,"Hello World");        // Write "Hello World" text in first row
     Lcd_Out(2,1,"LCD Display");        // Write "LCD Display" text in second row
       // Endless loop

You can download the full project files (mikroC source code and Proteus Schematic design) below here. All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).

Download LCD mikroC Source code
Download LCD Tutorial Proteus project