Friday, February 20, 2009

Displaying custom 5x8 characters on your HD44780 LCD

Creating and displaying your own custom characters on your HD44780 based LCD is very easy. When you send "data" to the LCD (which represents an ascii character to be displayed), the LCD consults its internal ROM and looks up the pattern corresponding to your character. This internal ROM can not be modified by the user and contains a fixed set of characters that can be displayed. However, the LCD also contains some internal RAM that can be used by the user to define his own set of characters. There is enough character RAM for up to 8 custom characters to be defined.
Step 1: Send the Command
To define your own custom characters, you simply write to the character RAM. To do this, simply send the command (0x40 + address). The address can be anywhere from 0 - 63 as there are 64 bytes available for use. To start out, simply set the address to zero. So, send the instruction (0x40). I have my code set up like this:
send_cmd(0x40 + 0);
Step 2: Send the Data
You are now ready to start sending data to the LCD module to define your own characters. Each of the LCD blocks is composed of 5x8 pixels. Each row of pixels, top to bottom, represents one byte. Since each row only has 5 pixels, only the lower 5 bits of each byte you send will be considered by the LCD module. So, to start defining a character like the one shown here, you will need to now send the following data like this:


The character RAM pointer will auto-incriment so you don't have to keep setting the address. Just send the data. The above 8 bytes define the first character. To define another character, just directly send another 8 bytes representing your second character.
Step 3: Use Your Characters

To use your freshly-created custom characters, all you have to do now is set the display address back to a valid position on the LCD screen and send your character. Every character you define has an ascii value of 0 - 7. For example, to display your first character, send the number 0x00 as data. If you have a second, third or fourth (or so on) character defined, send data 0x01, 0x02, 0x03 (and so on). I have my code configured as follows:
set_cursor(2, 1);

This will display our custom character.
Here's a complete program that puts it all into context:
The above program utilizes my HD44780 C18 Driver Code.


  1. Nice description. This really helped me allot!! THANKS!

    Kind regards,
    Ingmar Hendriks

  2. Nice and clear

  3. Unfortunately you didn't write anything about your implementation of send_data() and send_cmd(). I thought they only differ in setting the RS pin (0 - command, 1 - data), but that doesn't work for me.

  4. Really great and simple explanation. Keeping it simple, makes it easy to understand! Nice post, veegee!


  5. Thanks so very muchly for taking the time to put this up on the interweb for others. This has been a big help for me.