Custom Characters on LCD using PIC – MPLAB XC8

LCD Custom Characters

Custom Characters on LCD using PIC – MPLAB XC8

I hope that you already go through our tutorial, Interfacing LCD with PIC Microcontroller – MPLAB XC8. HD44780 compatible controllers used in these LCDs allows us to define 8 custom characters in addition to the standard pre-programmed characters. In this tutorial we will learn, how to create custom characters on LCD using PIC Microcontroller and MPLAB XC8 compiler.


CGROM – Character Generator ROM

This is the memory which holds 5×8 or 5×10 dot patterns of predefined characters in the LCD. It can generate 208 5×8 dot character patterns and 32 5×10 dot character patterns.

DDRAM – Display Data RAM

This is the memory which holds the character data which is currently displayed on the LCD screen. Its capacity is 80×8 bits, ie 80 characters.

CGRAM – Character Generator RAM

This memory works similar to CGROM but as this is a RAM we can modify its data any time. So we can store our custom character patterns in this memory through program. We can store up to eight 5×8 character dot patterns or four 5×10 character dot patterns in this memory.

Character Generation

Characters are displayed on the LCD using 5×8 or 5×10 dot matrix. Most of the commonly available displays uses 5×8 dot matrix. We can simply create a custom character by defining each pixel in the dot matrix. Here is an example of creating Ω symbol on 5×8 dot matrix.

LCD Custom Character Generation

LCD Custom Character Generation


Note that the following program uses our MPLAB XC8 LCD Library and you should include the header file “lcd.h” to your project directory.

#define _XTAL_FREQ 8000000

#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7

#include <xc.h>
#include <stdio.h>
#include "lcd.h";

#pragma config FOSC = HS   // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON  // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF   // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF   // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF   // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF    // Flash Program Memory Code Protection bit (Code protection off)

const unsigned short MyChar5x8[] = {
  0x00, 0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, // Code for char num #0
  0x0E, 0x1B, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x00, // Code for char num #1
  0x0E, 0x1B, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x00, // Code for char num #2
  0x0E, 0x1B, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x00, // Code for char num #3
  0x0E, 0x1B, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // Code for char num #4
  0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // Code for char num #5
  0x00, 0x04, 0x02, 0x1F, 0x02, 0x04, 0x00, 0x00, // Code for char num #6
  0x00, 0x00, 0x0E, 0x11, 0x11, 0x0A, 0x1B, 0x00  // Code for char num #7
void InitCustomChars()
  char i;
  Lcd_Cmd(0x04);   // Set CGRAM Address
  Lcd_Cmd(0x00);   // .. set CGRAM Address
  for (i = 0; i <= 63 ; i++)
  Lcd_Cmd(0);      // Return to Home
  Lcd_Cmd(2);      // .. return to Home

int main()
  TRISD = 0x00;        // PORTD as Output
  InitCustomChars();   // Write custom characters to LCD memory
    Lcd_Write_Char(0); // Display Custom Character 0
    Lcd_Write_Char(1); // Display Custom Character 1
    Lcd_Write_Char(2); // Display Custom Character 2
    Lcd_Write_Char(3); // Display Custom Character 3
    Lcd_Write_Char(4); // Display Custom Character 4
    Lcd_Write_Char(5); // Display Custom Character 5
    Lcd_Write_Char(6); // Display Custom Character 6
    Lcd_Write_Char(7); // Display Custom Character 7
  return 0;

Hope you can understand the working of the program from above comments. Please comment below if you have any doubts.

Circuit Diagram

Interfacing LCD with PIC Microcontroller - Circuit Diagram

Interfacing LCD with PIC Microcontroller – Circuit Diagram


LCD Custom Characters

LCD Custom Characters

Download Here

Buy Here

  • Sale
    Out of stock
    16x2 Green Character LCD Module16x2 Blue Character LCD Module

    16×2 Character LCD Module

    0 out of 5

    16×2 Character LCD is a very basic and low cost LCD module which is commonly used in electronic devices and projects. 16×2 means it contains 2 rows that can display 16 characters. In these displays, each character is displayed using 5×8 or 5×10 dot matrix.  This module can display ASCII characters, special characters and even custom characters. It uses HD44780 compatible controller for its operation. Two variants of this LCD modules are available, one having BLACK characters on GREEN and other having WHITE characters on BLUE.

    150.00165.00 149.00159.00
  • -31%
    PIC 16F877APIC 16F877A

    PIC 16F877A Microcontroller

    0 out of 5

    This powerful (200 nanosecond instruction execution) yet easy-to-program (only 35 single word instructions) CMOS FLASH-based 8-bit microcontroller packs Microchip's powerful PIC architecture into an 40- or 44-pin package and is upwards compatible with the PIC16C5X, PIC12CXXX and PIC16C7X devices. The PIC16F877A features 256 bytes of EEPROM data memory, self programming, an ICD, 2 Comparators, 8 channels of 10-bit Analog-to-Digital (A/D) converter, 2 capture/compare/PWM functions, the synchronous serial port can be configured as either 3-wire Serial Peripheral Interface (SPI™) or the 2-wire Inter-Integrated Circuit (I²C™) bus and a Universal Asynchronous Receiver Transmitter (USART). All of these features make it ideal for more advanced level A/D applications in automotive, industrial, appliances and consumer applications.

    200.00 139.00
  • -21%
    Out of stock
    USB PIC ProgrammerPICKit2 Clone

    USB PIC Programmer PICkit 2

    0 out of 5

    The PICkit 2 programmer is a development tool with a easy to use interface for programming and debugging Microchip’s flash families of micro-controllers. The windows programming interface supports all commonly available PIC microcontrollers. With Microchip’s powerful MPLAB Integrated Development Environment (IDE) the PICkit 2 enables in circuit debugging on most PIC microcontrollers.

    1,170.00 929.00

Share this post

  • Watchapong HipHip

    Dear Ligo
    Could you please explain more about function Lcd_cmd();.I don’t understand how to set adress CGRAM.
    Why we set Lcd_cmd(0x04) and Lcd_cmd(0x00);.

    Thank you

  • Please read the article : and the datasheet of HD44780 controller used in the LCD.

  • Ilozulu Chidiuso

    Dear Ligo, i tried to display 8 custom characters using a 20 x 4 lcd but the 7th and 8th custom character didn’t appear the way they were supposed to , so i took another look at this tutorial and used ” i <= 63 " in the for loop like you used and it worked perfectly. Please could explain how the " i <=63 " affects the display.THANK YOU. PS i used " i <= 49" in the first code.

  • Hello,
    Who told to use 49 ? 63 is the correct value.

  • UnMarciano

    Thank you, you saved my life!