Pantech.AI

How to Interface LCD16x2 custom character display with 8051

LCD16x2 Custom Character

LCDs (Liquid Crystal Displays) are commonly used in embedded systems to display status information or parameters.

The LCD 16×2 is a 16-pin device that includes 8 data pins (D0-D7) and 3 control pins (RS, RW, EN). The remaining 5 pins are used for power supply and backlighting.

The control pins are used to configure the LCD in either command mode or data mode, as well as to set read or write modes, determining when data is read from or written to the display.

The LCD 16×2 can operate in either 4-bit mode or 8-bit mode, depending on the specific requirements of the application. To use it, certain commands must be sent in command mode to configure the LCD, and once the setup is complete, data can be sent in data mode to display the required information.

For more details on the LCD 16×2 and how to use it, refer to the “LCD 16×2 Display Module” section in Sensors and Modules.

LCD16x2 Custom Char using 8051

LCD 16×2 Custom Character

8051 LCD16x2 Connection Diagram

LCD16x2 Connection with 8051

If we want to store a “Bell” shape custom character at pattern number 1 in CGRAM, we can use the following function:

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 function above is used to store custom characters in CGRAM.

Display Custom Characters

Once all custom characters are stored in CGRAM, they can be displayed on the LCD16x2.

To display a custom character, simply send its character number (from 0 to 7) as data to the LCD16x2.

Example 1

Program to display various custom characters on the 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);
}

Example 2 

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 */
}

Leave a Comment

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