4 Bit LCD interfacing and programming with PIC Microcontroller

4-bit-lcd-programming-pic-microcontroller-interfacing

LCD displays operate in two modes 4 bit and 8 bit mode. We all might have been familiar with 8 bit mode which is used widely in several systems. But 4 bit mode is something which many of us is not aware of. This mode has some advantages over the 8 bit mode out of which reduction of dedicated data pins is most important. This tutorial will teach you 4 bit LCD interfacing in 4 bit with your controller as well as programming it.

WHAT IS 4 BIT MODE:

We all knew that LCD consists of 8 data pins D0-D7 to receive the data and commands from the Microcontroller. However when developing a complex systems dedicating a complete port i.e 8 pins might be a drawback. To overcome this the LCD controller is capable of running in dual modes 8 bit and 4 bit mode.

8 Bit mode is a normal mode which uses 8 data lines, rs and enable for lcd functioning, see programming LCD in 8 bit mode. However in 4 bit mode only 4 lines D4-D7, along with RS,RW and EN pins are used. This will save us 4 pins of our controller which we might employ it for other purpose.

In 4 Bit mode the data bytes are sliced into two four bits and are transferred in the form of  a nibble. And the rest of the pin functions such as RS,RW and EN remains same. The above design illustrates the connection diagram of a 16×2 LCD with PIC microcontroller in 4 bit mode.

INITIALIZING THE LCD:

The first step in coding the LCD is initializing the LCD connected by giving the commands as input through the data line D4-D7 in the fom of Nibbles. For initializing the LCD following a specific reset sequence should be given and then initialized to follow the 4 bit mode.

  1. Place the byte in D4-D7 pins of LCD and set the EN pin to high and then make it low with time delay of 10ms between them.
  2. Send 28H command to use 2 lines 5×7 matrix in 4 bit mode. 
  3. Send 0FH for making the LCD,cursor and Cursor blinking ON.
  4. Send 06H for incrementing cursor position.
  5. Finally 01 and 02 for clearing screen and returning home.

DATA/COMMAND TRANSMISSION TO THE LCD:

The data transmission to a LCD must be performed by means of assigning logic states to three pins RS and E. R/W pin is not needed so we can ground it as shown in the schematic diagram. The data is send to the module by following these steps.

  1. RS pin should be high to convey LCD a data transmission is going to take place.
  2. Place the Upper nibble in the lower four bits of Port 2 by means of bit shifting and mask the upper four bits.
  3. Pulse En pin from high to low with certain time delay for transmission to complete.
  4. Now place the lower nibble and mask the rest of the bits, then repeat step 3.

CODE:

This code was built using CCS compiler for PIC microcontroller.
#include <4_bit_lcd.h>
#byte LCD=0x08
#byte TRIS_LCD=0x88
#define ENABLE 0x20
#define REG_SL 0x10
void lcd_reset()              //Reset sequence as stated in the LCD datasheet
 { 
   LCD = 0xFF;  
   LCD = 0x03|ENABLE;
   delay_ms(2);
   LCD = 0x03;
   delay_ms(2); 
   LCD = 0x03|ENABLE;
   delay_ms(2);
   LCD = 0x03; 
   delay_ms(2);
   LCD = 0x03|ENABLE;
   delay_ms(2);
   LCD = 0x03; 
   delay_ms(2);
   LCD = 0x02|ENABLE;
   delay_ms(2);
   LCD = 0x02; 
   delay_ms(2);
 }
void lcd_cmd(char cmd)               //Subroutine to send command  
 {  
  LCD = ((cmd>>4)&0x0F)|ENABLE;//Sending higher nibble by shifting with Pulsing ENABLE high delay();
  delay_ms(2);
  LCD = ((cmd>>4)&0x0F);
  delay_ms(2); 
  LCD = (cmd & 0x0F)|ENABLE;//Sending lower nibble ENABLE low
  delay_ms(2);
  LCD = (cmd & 0x0F);
  delay_ms(2);
 } 
void lcd_data (char *dat)          //Subroutine to send data  
 {    
  while(*dat!='') 
   {
     LCD = ((*dat>>4)&0x0F)|0x30;
     delay_ms(2);
     LCD = (((*dat>>4)&0x0F)|REG_SL);
     delay_ms(2); 
     LCD = ((*dat & 0x0F)|ENABLE|REG_SL);
     delay_ms(2);
     LCD = ((*dat & 0x0F)|REG_SL);
     delay_ms(2); 
     dat++; 
   } 
 delay_ms(2); 
 } 
void lcd_init ()  
 { 
   lcd_cmd(0x28);       // 4-bit mode - 2 line - 5x7 font.  
   lcd_cmd(0x0F);       // Display cursor with blink. 
   lcd_cmd(0x06);       // Automatic Increment - No Display shift.    
   lcd_cmd(0x01);    
   lcd_cmd(0x02);       //Clear screen and return home
   lcd_cmd(0x80);       // First row first column   
 }  
void main()   
 {   
   char msg[]="GADGETRONICX";
   TRIS_LCD=0x00;
   lcd_reset();     
   lcd_init();     
   lcd_data(msg);     
   while(TRUE);   
 }

NOTE:

  • The delay required by the LCD for processing data and command depends on the LCD. So in case if you face any trouble in displaying character on LCD try increasing the delay between the enable pulse.

5 Comments

  1. abdullah

    Can I get the assembly code for this work?

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Adbullah,
      Sorry we don’t have assembly code for this

      Reply
  2. John Sohl

    Hmm, my earlier post had the file name stripped. That would be:
    4_bit_lcd dot h
    Thanks!

    Reply
  3. John Sohl

    Thank you for your code, however, you reference the following:
    #include
    For the life of me (actually, about 2 hours of my life) I’ve been completely unable to locate that header file anywhere. Can you please post it or send it to me?

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Hi John,
      You get to use this header file only in CCS compiler 4_bit_lcd.h header file. But I believe you should be able to use the four bit without this header in case if you are using other compilers. Try and follow the steps mentioned under the heading DATA/COMMAND TRANSMISSION TO THE LCD:

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *