Create LCD custom characters for 16×2 alphanumeric LCD

create lcd custome character

In my previous article, I have discussed the LCD pins configuration and its mode. In this article, I will discuss the steps to generate own custom characters and in the last of the article write a “C” program to display a custom character on LCD.

Firstly we have to know about the LCD controller ( HD44780), it provides the 8 location to store the created LCD custom characters. We can use these custom character as per our requirements. Before describing the steps to generate custom character I want to discuss the HD44780.




Note: See the LCD configuration and its programming .

Some Important registers and memory of HD44780

Here I have some registers and memory which frequently used when you create custom characters on alphanumeric LCD.

INSTRUCTION  REGISTER (IR): It is an eight-bit register and it uses to store the command instruction like the select address of DDRAM, clear the LCD and much more. Some people also called him to command register.

DATA REGISTER (DR): Like IR register data register is also an eight-bit register and its use to write and read the data from DDRAM or CGRAM. Actually, when we write the data on DR it automatically writes to DDRAM or CGRAM at the address which selected by the address command through the internal operation.

Note:  IR  and DR registers are selected by RS Pin.

RS 0 Select the Instruction register.
RS 1 Select the Data register.

 

LCD BUSY FLAG: When HD44780 performs the internal operation, it does not take any instruction. It set the D7 pin high to so the busy status. So whenever we send the instruction LCD we should check the busy flag.

DISPLAY DATA RAM (DDRAM): DDRAM is standing for data dynamic ram, it stores data in an 8bit format and extended up to 80 characters. Data that display currently on LCD, actually they are present in DDRAM. When you want to display a character on LCD then internally ASCII value of this character load from CGROM to DDRAM. The area which is not used for display can be used as data ram.

CUSTOM GENERATOR ROM (CGROM): If you write character ‘A’ on data pin of LCD then ‘A’ will be displayed on the LCD at your define location. But question is that, how is the LCD get the pattern of ‘A’ because we have only written the ASCII value of ‘A’ (0x31 or 48) on LCD data pins.

Actually LCD have a CGROM which have predefined dot character patterns, these pattern access by their ASCII value. So whenever we write the ASCII value of a character on data pin of LCD then LCD fetch the predefined pattern from the CGROM to DDRAM at user-defined the address.

Custom generator ROM, generate 5×8 and 5×10 dot character patterns from 8-bit character code. It can generate up to “208” 5×8 and “32” 5×10 dot character patterns.

CGROM

CUSTOM GENERATORS RAM (CGRAM): There are eight locations, which provided by 16X2 LCD to create the user define custom character patterns. In character generator RAM user can rewrite the character patterns as per their choice, the user can create eight 5X8 and four 5×10 dot character patterns.

e.g. In the below image, I have created the pattern (5×8) of an arrow and calculate the corresponding hex and binary values

CGRAM

 

Note: Using the custom character generator tool, you can create your pattern easily.

Steps to create custom character on LCD

  • Set the RS pin and RW pin in the low state.
  • Send the address location of CGRAM, where you want to save the character’s pattern.
  • Now switch the LCD in data mode to change the state of RS pin from low to high.
  • Send the desired pattern bytes on LCD data pin, like the data display LCD controller automatically increment the address of CGRAM.

SOURCE CODE

In the below example, I have written a simple program to display arrow and betel on 16×2 alphanumeric LCD using the 8051 microcontroller.

custom character
aticleworld

 

#include<reg51.h>

#define LCD P2 /*Attached Lcd on Port*/
#define DDRAM_LOCATION  143  /* 0x8f */
#define BETLE_POSITION  134  /*0x86*/

sbit rs =P3^0; /*Configure RS Pin*/
sbit rw=P3^1; /*Configure R/W pin*/
sbit e =P3^2; /*Configure Enable pin*/


/*Function to write command on Lcd*/
void LcdCommand(const char cCommand);

/*Function to display message on Lcd*/
void DisplayData(const char);

/*Function To Initialize Lcd*/
void LcdInit(void);

/*Function to Provide delay*/
void Delay(unsigned int);

/*Funtion to create pattern in CGRAM*/
void CreateCustomCharacter(unsigned char *pucPattern,const char cLocation);


/*Hex value to create the pattern (Arrow)*/
unsigned char aucPattern1[] = {0x00,0x04,0x08,0x1f,0x08,0x04,0x00,0x00};
/*Hex value to create the pattern (betel leaf)*/
unsigned char aucPattern2[]= {0x00,0x1b,0x15,0x11,0x0a,0x04,0x00,0x00};




void  main()
{

    int iLoop=0;
    int iPosition=0;

    CreateCustomCharacter(aucPattern1,0); /*Create arrow at 0th location of CGRAM*/
    CreateCustomCharacter(aucPattern2,1); /*Create betel leaf at 1st location of CGRAM*/
    LcdInit();  /*Lcd Initialize*/

    while(1)
    {

        for(iLoop=0; iLoop<16; iLoop++)
        {

            iPosition = DDRAM_LOCATION- iLoop;
            LcdCommand(iPosition); /*Address of DDRAM*/

            DisplayData(0); //Display Arrow

            Delay(10);

            LcdCommand(0x01); //Clear the LCD

            LcdCommand(BETLE_POSITION);/*Position where betel leaf display*/

            DisplayData(1); //Display betel leaf

        }
    }

}


/*Create Custom character*/
void CreateCustomCharacter(unsigned char *pucPattern,const char cLocation)
{
    int iLoop=0;

    LcdCommand(0x40+(cLocation*8)); //Send the Address of CGRAM
    for(iLoop=0; iLoop<8; iLoop++)
        DisplayData(pucPattern[iLoop]); //Pass the bytes of pattern on LCD

}


/*Function to write command on Lcd*/
void LcdCommand(const char cCommand)
{
    rs = 0;
    rw = 0;
    e  = 1;
    LCD = cCommand;
    Delay(1);
    e=0;

}

/*Function to Display message on Lcd*/
void DisplayData(const char cData)
{
    rs = 1;
    rw = 0;
    e  = 1;
    LCD = cData;
    Delay(1);
    e=0;
}

/*Function to Provide Delay*/
void Delay(unsigned int i)
{
    int j,k;
    for(j=0; j<i; j++)
        for(k=0; k<1275; k++);
}

/*Initialise the LCD*/
void LcdInit(void)
{

    LcdCommand(0x01);
    LcdCommand(0x38);
    LcdCommand(0x06);
    LcdCommand(0x0c);
}

 

Your opinion matters

Although here I have tried to describe the steps to how to create the custom characters on LCD I would like to know your opinion. So please don’t forget to write the comment in the comment box.

Recommended Post:

 




11 comments

  1. Thank you for your thorough explanation of everything. I greatly appreciate that there were no shortcuts taken. I had looked at a couple other sites regarding the same subject (custom characters on a HD44780-based LCD) and found them lacking because I’m still pretty new to firmware and this will form my foundation. These fundamental examples can’t have mistakes or omitted data. Not at this stage. Other sites might describe DisplayData as “LcdCommand with the (reg select) rs set to 1” rather than showing each function in its entirety. Thank you for taking the time to write quality tutorials.

Leave a Reply

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