Interfacing Lcd(8×1,8×2,10×1,10×2, 16×2, 16×4, 20×1, 20×2, 40×1,40×2) in 4 Bit Mode with Microchip Pic16f877A Microcontroller

Summary of Interfacing Lcd(8×1,8×2,10×1,10×2, 16×2, 16×4, 20×1, 20×2, 40×1,40×2) in 4 Bit Mode with Microchip Pic16f877A Microcontroller


This article details interfacing a 16×2 LCD with a Microchip PIC16F877 microcontroller in 4-bit mode to conserve I/O pins. It explains the division of data into nibbles, circuit connections using specific port bits, and provides C code for initialization and display functions. The project demonstrates displaying text like "Microcontroller" on both lines of the screen.

Parts used in the 16x2 LCD Interfacing Project:

  • 16×2 character lcd
  • Pic 16f877 microcontroller
  • Potentiometer (For setting lcd contrast)
  • Crystal(20MHz)
  • Connecting wires
  • Bread board or PCB for the circuit
  • Power Supply

In this project i am going to interface 16×2 lcd display in 4-bit mode with Microchip Pic16f877 microcontroller. We can interface any size of character lcd display (8×1,8×2,10×1,10×2, 16×2,16×2,16×4,20×1,20×2,40×1,40×2 etc) in 4-bit mode with pic microcontrollers. In 4-bit interface mode only 4 lcd data lines are used to display data on lcd screen. Usually lcd is interfaced in 4-bit mode with microcontrollers to save I\O pins of microcontrollers. Before beginning any further i assume that you know difference between 4-bit and 8-bit lcd interfacing mode with microcntrollers. If not just take the below simple tutorial. Tutorial will help you in understating the basic difference, pros and cons of both the modes. It will also help you in understanding the code below easily.

16×2 lcd in 4-bit mode with pic microcontroller – Project requirements

  • 16×2 character lcd.
  • Pic 16f877.
  • Potentiometer (For setting lcd contrast).
  • Crystal(20MHz).
  • Connecting wires.
  • Bread board or PCB for the circuit.
  • Power Supply. ​​

16×2 lcd in 4-bit mode

16×2 lcd in 4-bit mode

In 4-bit mode only 4-bit data is send to lcd at a time. Since 8-bit microcontrollers contains data in 8-bit form so we divide our data in to two nibbles(1-nibble=4-bits). First higher 4-bits(nibble) is send to lcd and then the lower 4-bits(nibble) with enable stroke signal. Only D4,D5,D6,D7 data pins of 16×2 lcd are used in 4-bit interface mode. D1,D2,D3,D4 are left empty. D4 is our least significant bit and D7 is highest significant bit in 4-bit interface mode. A typical interfacing diagram is given at the right side. 
 

Interfacing 16×2 Lcd with pic microcontroller in 4-bit mode – Project circuit diagram

Interfacing 16×2 lcd with Pic16f877 microcontroller is simple, if you have taken the above tutorial. The circuit of the project is also very simple. Port-B first 4 bits (RB0,RB1,RB2,RB3) of Pic16f877 microcontroller are used to send 4-bit data and commands to lcd. These four Pins(RB0,RB1,RB2,RB3) are Connected to four data pins of 16×2 lcd(D4,D5,D6,D7). Port-D pin# 5 is connected to rw(read-write) pin of lcd. Port-D pin# 6 is connected to rs(register select) pin of lcd. Port-D pin# 7 is connected to en(Enable) pin of 16×2 lcd. If you are newbie and have to idea about the working and pin configuration of lcd. Below is a good tutorial.

Taking the upper tutorial will led you know how 16×2 lcd works & how to configure it.The circuit diagram of the project is given below. 

Interfacing 16×2 Lcd with pic microcontroller in 4-bit mode – Project circuit diagram
   
  #include <htc.h>
  #define _XTAL_FREQ 20e6
  #define en RD7
  #define rs RD6
  #define rw RD5
   
  void delay(unsigned int time) //Time delay function – Arbitrary delay
  {
  unsigned int i,j;
  for(i=0;i< time;i++)
  for(j=0;j< 5;j++);
  }
   
  //Function sending commands to the command register of LCD
  void llcdcmd(unsigned char value)
  {
  RB0=(value >> 0) & 0x01;
  RB1=(value >> 1) & 0x01;
  RB2=(value >> 2) & 0x01;
  RB3=(value >> 3) & 0x01;
   
  en = 1; //enable-e
  delay(500);
  en=0; //enable-e
  delay(500);
  }
  //Function sending data to the data register of LCD
  void ddisplay(unsigned char value)
  {
  RB0=(value >> 0) & 0x01;
  RB1=(value >> 1) & 0x01;
  RB2=(value >> 2) & 0x01;
  RB3=(value >> 3) & 0x01;
   
  en= 1; //enable-e
  delay(500);
  en=0; //enable-e
  delay(500);
  }
   
   
  void display(unsigned char c){
  rs= 1; //register select-rs
  rw= 0; //read-write-rd
  delay(150);
  ddisplay(c>>4); //Send Higher nibble 4-bits of 8-bit data
  delay(150);
  ddisplay(c); //Send Lower nibble 4-bits of 8-bit data
   
  }
  void lcdcmd(unsigned char c){
  rs= 0; //register select-rs
  rw = 0; //read-write-rd
  delay(150);
  llcdcmd(c>>4); //Send Higher nibble 4-bits of 8-bit command
  delay(150);
  llcdcmd(c); //Send Lower nibble 4-bits of 8-bit command
  }
  //Function to initialize the registers and pins of LCD
  //always use with every lcd of Hitachi
  void lcdint(void)
  {
  TRISB0=0;
  TRISB1=0;
  TRISB2=0;
  TRISB3=0; //Port-B is used as output port
  TRISD5=0; //Read-Write pin as output
  TRISD6=0; //Register select pin as output
  TRISD7=0; //Enable pin as output
  rw=0;
  rs=0;
  PORTB &= 0xF0;
  PORTB |= (0x03&0x0F); // Write 0x3
  en = 1;
  delay(150);
  en = 0;
  delay(150);
  delay(4500);
   
  PORTB &= 0xF0;
  PORTB |= (0x03&0x0F); // Write 0x3
  en = 1;
  delay(150);
  en = 0;
  delay(150);
  delay(300);
   
  PORTB &= 0xF0;
  PORTB |= (0x03&0x0F); // Write 0x3
  en = 1;
  delay(150);
  en = 0;
  delay(150);
  delay(650);
   
  PORTB &= 0xF0;
  PORTB |= (0x02&0x0F); // Write 0x2
  en = 1;
  delay(150);
  en = 0;
  delay(150);
   
  display(0x20); //Lcd in 4-bit mode, 1 line and 5×7 font character
  delay(1000);
  lcdcmd(0x28); //Lcd in 4-bit mode, 2 Line and 5×7 font character
  delay(50);
  lcdcmd(0x0C); //Display on cursor off
  delay(50);
  lcdcmd(0x01); //Clear Lcd Screen
  delay(50);
  lcdcmd(0x06); //Entry Mode
  delay(50);
  lcdcmd(0x80); //Start from first line
  delay(50);
  }
   
  void main()
  {
  lcdint(); //Initialize character lcd
  display(M); display(i); display(c); display(r); display(o); display(c);
  display(o); display(n); display(t); display(r); display(o); display(l);
  display(l); display(e); display(r);
  lcdcmd(0xC0); //Jump to second line
  display(M); display(i); display(c); display(r); display(o); display(c);
  display(o); display(n); display(t); display(r); display(o); display(l);
  display(l); display(e); display(r);
  lcdcmd(0x01); //Clear lcd
  delay(500);
  }
 
Note: Although i declared the R/W pin in code (RD-5) but i am not using it. I made the lcd R/W pin directly ground. So now it remains always in write mode.
Download the project files and code with simulation. Simulation is made in proteaus and code is written using MP-lab ide and high tech c compiler. Please give us Your feed back on the project. If you have any questions regarding post or you dont understand any instruction please leave your comments below.
 

Quick Solutions to Questions related to 16x2 LCD Interfacing Project:

  • Why is the 4-bit interface mode usually chosen for microcontrollers?
    Lcd is interfaced in 4-bit mode with microcontrollers to save IO pins of microcontrollers.
  • Which data pins of the 16×2 lcd are utilized in 4-bit interface mode?
    Only D4,D5,D6,D7 data pins of 16×2 lcd are used in 4-bit interface mode while D1,D2,D3,D4 are left empty.
  • How are the Port-B pins of Pic16f877 connected to the lcd?
    Port-B first 4 bits RB0,RB1,RB2,RB3 of Pic16f877 microcontroller are Connected to four data pins of 16×2 lcd D4,D5,D6,D7.
  • What specific pins on Port-D connect to the lcd control signals?
    Port-D pin# 5 is connected to rw pin, pin# 6 to rs pin, and pin# 7 to en pin of 16×2 lcd.
  • Which compiler is specified for compiling the project code?
    High tech c compiler is used for compiling and generating hex code file.
  • How does the llcdcmd function handle command transmission?
    The statement llcdcmd(c>>4) moves our high Byte to right and sends them to llcdcmd function before sending the low Byte.
  • What is the default state of the R/W pin in this specific implementation?
    I made the lcd R/W pin directly ground so it remains always in write mode.
  • What command is sent to clear the lcd screen during initialization?
    Lcdcmd 0x01 is used to Clear Lcd Screen.

About The Author

Muhammad Bilal

I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.