Display custom characters on 16×2 lcd using Microchip Pic16f877 Microcontroller

Here is a simple project on how to build/generate/make custom characters in 16×2 lcd and then print/display them on lcd using microchip pic16f877 microcontroller. Character lcd contains a set of ascii characters and some Chinese characters in their controllers. We invoke the ascii characters present in the ram for displaying them on lcd. But if we want to display some special characters, symbols or similes we first have to make/declare them in the ram of lcd controller since they are not present in the ascii character set of the lcd. Then we can invoke them for displaying on the lcd when ever is required. 

Building and displaying self made custom characters on lcd is not a very hard task. To carry out this task you must know about the internal structure of character lcd. The size of the lcd controller ram, registers of the lcd and CG-RAM(Character generated ram) of lcd. CG-RAM is the most important part of lcd for generating and displaying self made custom characters. CG-RAM is a whole big topic so it is kept in a separate post. CG-RAM is fully discussed in the tutorials below. I recommend you to please take the tutorials other wise you will not unable to understand the code below.

Project Requirements.

  • Microcontroller PIC16f877
  • 16×2 lcd
  • Potentiometer (For Setting lcd Contrast)
  • Crystal 20MHz
  • Connecting wires, Power Supply, Bread board or PCB for circuit.

Circuit diagram of the project is given below. Port-B of Pic16f877 microcontroller is connected with data pins of lcd. LCD controlling pins en(enable), rs(register select), r/w(read/write) are connected to Port-D pin 6 and 7. R/W(Read/Write) pin is grounded because we are only writing to lcd, Grounding the R/W pin enables the write operation for lcd. All the other connections are necessary connections to brought the microcontroller and whole circuit in working condition.

Display custom characters on 16×2 lcd using Microchip Pic16f877 Microcontroller

Code is written in c language. MP-LAB ide and High TECH C compiler is used to compile the code. First i included the header file htc.h. This file must be included in every project which is going to be compiled in High Tech c compiler. Then frequency of the crystal is defined which is 20 MHz. Lcd control pins are defined next. Then some character arrays are defined. These character arrays are actually the custom characters which we are going to display on lcd. Delay function is used to give some arbitrary delay where needed. lcdcmd() function is sending commands to lcd. display() function is displaying characters on lcd. lcdint() function is initializing our lcd. In the main function I am generating and then displaying character on lcd.

To understand the code you must first know the internal structure of lcd. The tutorials links given above are very helpful for understanding the working and internal structure of CG-RAM of lcd. If you didn’t take the tutorials. I recommend you to please go through them before going through the code below. 

   
  #include <htc.h>
  #define __XTAL_FREQ 20e6
  #define en RD7
  #define rs RD6
  #define rw RD5
  char c1[8]={0x04,0x0E,0x0E,0x0E,0x1F,0x04,0x00};
  char c2[8]={0x00,0x0A,0x04,0x04,0x00,0x0E,0x11};
  char c3[8]={0x04,0x0A,0x11,0x11,0x0A,0x04};
  char c4[8]={0x0E,0x0A,0x1F,0x1B,0x1F,0x0A,0x0E};
  char c5[8]={0x0A,0x04,0x04,0xA,0x11,0x04,0x11};
  char c6[8]={0x04,0x0A,0x1F,0x0A,0x15,0x1B,0x11};
  char c7[8]={0x1F,0x11,0x11,0x11,0x11,0x11,0x1F};
  char c8[8]={0x1F,0x1D,0x1B,0x1D,0x1F,0x10,0x10};
   
  void delay(unsigned int time) //Time delay function
  {
  unsigned int i,j;
  for(i=0;i < time;i++)
  for(j=0;j < 10;j++);
  }
  //Function for sending values to the command register of LCD
  void lcdcmd(unsigned char value)
  {
  PORTB=value;
  rs= 0; //register select-rs
  rw = 0; //read-write-rd
  en = 1; //enable-e
  delay(50);
  en=0; //enable-e
  delay(50);
   
  }
  //Function for sending values to the data register of LCD
  void display(unsigned char value)
  {
  PORTB=value;
  rs= 1; //register select-rs
  rw= 0; //read-write-rd
  en= 1; //enable-e
  delay(500);
  en=0; //enable-e
  delay(50);
   
  }
  //function to initialize the registers and pins of LCD
  //always use with every lcd of hitachi
  void lcdint(void)
  {
  TRISB=0x00; //Port 1 is used as output port
  TRISD5=0; //Lcd controlling pins defined
  TRISD6=0; //
  TRISD7=0; //Lcd controlling pins defined
   
  //Initialize Lcd
  delay(15000); display(0x30); delay(4500);
  display(0x30); delay(300); display(0x30); delay(650);
  lcdcmd(0x38); delay(50); lcdcmd(0x0C); delay(50);
  lcdcmd(0x01); delay(50); lcdcmd(0x06); delay(50);
  lcdcmd(0x80); delay(50); //Initialize Lcd
  }
   
  void main()
  {
  unsigned int i;
  lcdint();
   
  lcdcmd(0x40); //CG-RAM 1st character Address- Generating Character
  for(i=0;i<7;i++)
  display(c1[i]);
  delay(50);
   
  lcdcmd(0x40+8); //CG-RAM 2nd character Address- Generating Character
  for(i=0;i<7;i++)
  display(c2[i]);
  delay(50);
   
  lcdcmd(0x40+16); //CG-RAM 3rd character Address- Generating Character
  for(i=0;i<6;i++)
  display(c3[i]);
  delay(50);
   
  lcdcmd(0x40+24); //CG-RAM 4th character Address- Generating Character
  for(i=0;i<7;i++)
  display(c4[i]);
  delay(50);
   
  lcdcmd(0x40+32); //CG-RAM 5th character Address- Generating Character
  for(i=0;i<7;i++)
  display(c5[i]);
  delay(50);
   
  lcdcmd(0x40+40); //CG-RAM 6th character Address- Generating Character
  for(i=0;i<7;i++)
  display(c6[i]);
  delay(50);
   
  lcdcmd(0x40+48); //CG-RAM 7th character Address- Generating Character
  for(i=0;i<7;i++)
  display(c7[i]);
  delay(50);
   
  lcdcmd(0x40+56); //CG-RAM 8th character Address- Generating Character
  for(i=0;i<7;i++)
  display(c8[i]);
  delay(50);
   
  lcdcmd(0x01); //Clear lcd
  delay(100);
   
  while(1){
   
  display(1); //Print/display first character
  delay(10000);
  lcdcmd(0x82); //Cursor jump to row-1 coulomb-2
  display(2); //Print/display 2nd character
  delay(10000);
  lcdcmd(0x84); //Cursor jump to row-1 coulomb-3
  display(3); //Print/display 3rd character
  delay(10000);
  lcdcmd(0x86); //Cursor jump to row-1 coulomb-4
  display(4); //Print/display 4th character
  delay(10000);
  lcdcmd(0x88); //Cursor jump to row-1 coulomb-5
  display(5); //Print/display 5th character
  delay(10000);
  lcdcmd(0x8A); //Cursor jump to row-1 coulomb-6
  display(6); //Print/display 6th character
  delay(10000);
  lcdcmd(0x8C); //Cursor jump to row-1 coulomb-7
  display(7); //Print/display 7th character
  delay(10000);
  lcdcmd(0x8E); //Cursor jump to row-1 coulomb-8
  display(8); //Print/display 8th character
  delay(100000);
   
  lcdcmd(0x01); //Clear lcd
  lcdcmd(0x80); //Cursor jump to row-1 coulomb-1
  delay(100);
  }}
 
The eight characters which i made and displayed on the 16×2 lcd are just random images and symbols. Heart symbol, rocket image and battery capacity image is made and then displayed on the 16×2 lcd. The above code can work with any size of character lcd 8×1, 8×2, 16×1, 16×2, 16×4, 20×1 , 20×4. since each lcd contains the same Hitachi hd4478 lcd controller in them. You may need only to change the row and coulomb of the character displayed.
Download the project files, code(C-Code, Hex-Code) and simulation. The code is written in c language using MP-LAB ide and high tech c compiler is used for compiling code. Simulation is made in proteaus 8.0. Please give us your feed back on the project. Write your comments below.
 

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.