LCD16x2 custom character display using 8051

LCD16x2 Custom Character

LCDs (Liquid Crystal Displays) are used for displaying status or parameters in embedded systems.

LCD 16x2 is a 16-pin device that has 8 data pins (D0-D7) and 3 control pins (RS, RW, EN). The remaining 5 pins are for supply and the backlight for the LCD.

The control pins help us configure the LCD in command mode or data mode. They also help configure read mode or write mode and also when to read or write.

LCD 16x2 can be used in 4-bit mode or 8-bit mode depending on the requirement of the application. In order to use it we need to send certain commands to the LCD in command mode and once the LCD is configured according to our needs, we can send the required data in data mode.

For more information about LCD 16x2 and how to use it, refer to the topic LCD 16x2 display module in the sensors and modules section.

 

LCD16x2 Custom Char using 8051

Custom character shown on LCD16x2
LCD 16x2 Custom Character

 

 

8051 LCD16x2 Connection Diagram

LCD16x2 Interface with 8051
LCD16x2 Connection with 8051

 

Suppose, we decide to put “Bell” shape custom character at pattern number 1 then to store them in CGRAM the following function is used.

void LCD_Custom_Char (unsigned char loc, unsigned char *msg)
{
    unsigned char i;
    if(loc<8)
    {
	/* Command 0x40 and onwards forces the device to point CGRAM address */
	LCD_Command (0x40 + (loc*8));
	for(i=0;i<8;i++)  /* Write 8 byte for generation of 1 character */
           LCD_Char(msg[i]);
    }   
}

The above function will be used to store the custom characters in CGRAM.

 

Display Custom Characters

After storing all custom characters in CGRAM, we can display it on LCD16x2.

To display custom characters, simply provide custom character number (from 0 to 7) as a data to LCD16x2.

 

Example 1

Program to Show different custom characters on LCD16x2.

Code for LCD16x2 custom Char using 8051

/*  
   LCD16x2 8 bit 8051 custom character
   http://www.electronicwings.com
*/


#include<reg51.h>

sfr lcd_data_port=0x90;	/* P1 port as data port */
sbit rs=P2^0;			/* Register select pin */
sbit rw=P2^1;			/* Read/Write pin */
sbit en=P2^2;			/* Enable pin */


void delay(unsigned int count)	/* Function to provide delay Approx 1ms */
{
	int i,j;
	for(i=0;i<count;i++)
		for(j=0;j<112;j++);
}

void LCD_Command (char cmd)	/* LCD16x2 command funtion */
{
	lcd_data_port= cmd;
	rs=0;			/* command reg. */
	rw=0;			/* Write operation */
	en=1; 
	delay(1); 
	en=0;
	delay(5);
}

void LCD_Char (char char_data)	/* LCD data write function */
{
	lcd_data_port=char_data;
	rs=1;			/*Data reg.*/
	rw=0;			/*Write operation*/
	en=1;
	delay(1);
	en=0;
	delay(5);
}

void LCD_String (char *str)	/* Send string to LCD function */
{
	int i;
	for(i=0;str[i]!=0;i++)  /* Send each char of string till the NULL */
	{
		LCD_Char (str[i]);  /* Call LCD data write */
	}
}

void LCD_String_xy (char row, char pos, char *str)  /* Send string to LCD function */
{
	if (row == 0)
	LCD_Command((pos & 0x0F)|0x80);
	else if (row == 1)
	LCD_Command((pos & 0x0F)|0xC0);
	LCD_String(str);  	/* Call LCD string function */
}

void LCD_Init (void)		/* LCD Initialize function */
{
	delay(20);		/* LCD Power ON Initialization time >15ms */
	LCD_Command (0x38);	/* Initialization of 16X2 LCD in 8bit mode */
	LCD_Command (0x0C);	/* Display ON Cursor OFF */
	LCD_Command (0x06);	/* Auto Increment cursor */
	LCD_Command (0x01);	/* clear display */
	LCD_Command (0x80);	/* cursor at home position */
}

void LCD_Custom_Char (unsigned char loc, unsigned char *msg)
{
	unsigned char i;
	if(loc<8)
	{
	/* Command 0x40 and onwards forces the device to point CGRAM address */
	LCD_Command (0x40 + (loc*8));
	for(i=0;i<8;i++)	/* Write 8 byte for generation of 1 character */
		LCD_Char(msg[i]);      
    }   
}


void main()
{
	char i;
	/* Custom char set for alphanumeric LCD Module */
	unsigned char Character1[8] = { 0x00, 0x0A, 0x15, 0x11, 0x0A, 0x04, 0x00, 0x00 };
	unsigned char Character2[8] = { 0x04, 0x1F, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F };
	unsigned char Character3[8] = { 0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00 };
	unsigned char Character4[8] = { 0x01, 0x03, 0x07, 0x1F, 0x1F, 0x07, 0x03, 0x01 };
	unsigned char Character5[8] = { 0x01, 0x03, 0x05, 0x09, 0x09, 0x0B, 0x1B, 0x18 };
	unsigned char Character6[8] = { 0x0A, 0x0A, 0x1F, 0x11, 0x11, 0x0E, 0x04, 0x04 };
	unsigned char Character7[8] = { 0x00, 0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00 };
	unsigned char Character8[8] = { 0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00 };


	LCD_Init();
	
	
	LCD_Custom_Char(0, Character1);  /* Build Character1 at position 0 */ 
	LCD_Custom_Char(1, Character2);  /* Build Character2 at position 1 */ 
	LCD_Custom_Char(2, Character3);  /* Build Character3 at position 2 */ 
	LCD_Custom_Char(3, Character4);  /* Build Character4 at position 3 */ 
	LCD_Custom_Char(4, Character5);  /* Build Character5 at position 4 */ 
	LCD_Custom_Char(5, Character6);  /* Build Character6 at position 5 */ 
	LCD_Custom_Char(6, Character7);  /* Build Character6 at position 6 */ 
	LCD_Custom_Char(7, Character8);  /* Build Character6 at position 7 */ 

	LCD_Command(0x80);  	/* Cursor at home position */
  	LCD_String("Custom char LCD");			
	LCD_Command(0xc0);
			
	for(i=0;i<8;i++)	/* Function will send data 1 to 8 to lcd */
		{
			LCD_Char(i);
			LCD_Char(' ');	/* Space between each custom char */
		}
	while(1);
}

 

Video of custom character Display LCD16x2 8051

 

Example 2 

Animation: Pacman chasing Dot

LCD16x2 Animation using 8051

/*  
   LCD16x2 8 bit 8051 animation
   http://www.electronicwings.com
*/


#include<reg51.h>

sfr lcd_data_port=0x90;		/* P1 port as data port */
sbit rs=P2^0;			/* Register select pin */
sbit rw=P2^1;			/* Read/Write pin */
sbit en=P2^2;			/* Enable pin */

void lcd_built(void);

unsigned char addr,i;

void delay(unsigned int count)	/* Function to provide delay Approx 1ms */
{
	int i,j;
	for(i=0;i<count;i++)
		for(j=0;j<112;j++);
}

void LCD_Command (char cmd)	/* LCD16x2 command funtion */
{
	lcd_data_port= cmd;
	rs=0;			/* command reg. */
	rw=0;			/* Write operation */
	en=1; 
	delay(1);
	en=0;
	delay(5);
}

void LCD_Char (char char_data)  /* LCD data write function */
{
	lcd_data_port=char_data;
	rs=1;			/*Data reg.*/
	rw=0;			/*Write operation*/
	en=1;   				
	delay(1);
	en=0;
	delay(5);
}

void LCD_String (char *str)	/* Send string to LCD function */
{
	int i;
	for(i=0;str[i]!=0;i++)  /* Send each char of string till the NULL */
	{
		LCD_Char (str[i]);  /* Call LCD data write */
	}
}

void LCD_String_xy (char row, char pos, char *str)  /* Send string to LCD function */
{
	if (row == 0)
	LCD_Command((pos & 0x0F)|0x80);
	else if (row == 1)
	LCD_Command((pos & 0x0F)|0xC0);
	LCD_String(str);	/* Call LCD string function */
}

void LCD_Init (void)		/* LCD Initialize function */
{
	delay(20);		/* LCD Power ON Initialization time >15ms */
	
	LCD_Command (0x38);	/* Initialization of 16X2 LCD in 8bit mode */
	LCD_Command (0x0C);	/* Display ON Cursor OFF */
	LCD_Command (0x06);	/* Auto Increment cursor */
	LCD_Command (0x01);	/* Clear display */
	LCD_Command (0x80);	/* Cursor at home position */
}

void LCD_Clear()
{
	LCD_Command (0x01);	/* Clear display */
	LCD_Command (0x80);	/* Cursor at home position */
}

void LCD_Custom_Char (unsigned char loc, unsigned char *msg)
{
    unsigned char i;
    if(loc<8)
    {
     LCD_Command (0x40 + (loc*8));
       for(i=0;i<8;i++)
           LCD_Char(msg[i]);      
    }   
}

void show_set1()
{
	LCD_Char(0x0);
	LCD_Char(0x01);
}

void show_set2()
{
	LCD_Char(0x2);
	LCD_Char(0x3);
}


void show_dots(char j)
{
	LCD_Command(0x80|(addr&0x0f));
	LCD_Char(j);
}

int main(void)
{
	
	LCD_Init();
	LCD_String("Ewings");
	LCD_Command(0x0c3);
	LCD_String("Animation");
	delay(300);
	lcd_built();
	addr=0xc1;
	
	while(1)
	{
		addr=0xc1;
		i=4;
		/* showing set 1 left to right rolling */
		do{
			LCD_Command(addr++);
			show_set1();
			show_dots(i);
			if(i<7)
			i++;
			else
			i=4;
			delay(200);
			LCD_Clear();
			
			LCD_Command(addr++);
			show_set2();
			show_dots(i);
			if(i<7)
			i++;
			else
			i=7;
			delay(200);
			LCD_Clear();
		}while(addr<0xce);
		
		/* showing set 2 right to left rolling */
		do{
			LCD_Command(addr--);
			show_set1();
			show_dots(i);
			if(i<7)
			i++;
			else
			i=4;
			delay(200);
			LCD_Clear();
			
			LCD_Command(addr--);
			show_set2();
			show_dots(i);
			if(i<7)
			i++;
			else
			i=7;
			delay(200);
			LCD_Clear();
		}while(addr>0xc2);
		
		
	}
}


void lcd_built(void)
{
	unsigned char Character1[8] = { 0x01, 0x03, 0x07, 0x0D, 0x0F, 0x02, 0x05, 0x0A };
	unsigned char Character2[8] = { 0x10, 0x18, 0x1C, 0x16, 0x1E, 0x08, 0x14, 0x0A };
	unsigned char Character3[8] = { 0x01, 0x03, 0x07, 0x0D, 0x0F, 0x05, 0x08, 0x04 };
	unsigned char Character4[8] = { 0x10, 0x18, 0x1C, 0x16, 0x1E, 0x14, 0x02, 0x04 };
	unsigned char Character5[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 };
	unsigned char Character6[8] = { 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00 };
	unsigned char Character7[8] = { 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00 };
	unsigned char Character8[8] = { 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 };

	/* ---------- Build Custom Characters -----------------*/
	
	LCD_Custom_Char(0, Character1);  /* Build Character1 at position 0 */
	LCD_Custom_Char(1, Character2);  /* Build Character2 at position 1 */
	LCD_Custom_Char(2, Character3);  /* Build Character3 at position 2 */
	LCD_Custom_Char(3, Character4);  /* Build Character4 at position 3 */
	LCD_Custom_Char(4, Character5);  /* Build Character5 at position 4 */
	LCD_Custom_Char(5, Character6);  /* Build Character6 at position 5 */
	LCD_Custom_Char(6, Character7);  /* Build Character6 at position 6 */
	LCD_Custom_Char(7, Character8);  /* Build Character6 at position 7 */
}

 

Video of LCD16x2 Animation using 8051


Components Used

LCD16x2 Display
LCD16x2 Display
1
8051 AT89c51
8051 AT89c51
1

Downloads

8051_Custom_Character_Keil_Project_File Download
8051_Animation_Keil_Project_File Download
LCD_8bit_Proteus_Simulation_File Download
Ad