Interfacing of a 16x2 LCD with 8051 & 8052 microcontrollers
Learn the interfacing of a 16x2 LCD with 8051 and 8052 family microcontrollers along with LCD commands, circuit diagram, and C Program.
Introduction
16x2 LCD is the most popular display for embedded systems, maybe it's a small project or a big product, but 16x2 display has been always a choice for embedded developers. these LCDs are used for various applications in electronic systems, almost every kiosk, any kind of meter, signboards, and almost all the systems we see, use smaller or bigger displays. today we will learn the interfacing of a 16X2 LCD with 8051 and 8052-based microcontroller, the connections and code are provided below.
8051/8052 Family
Firstly let me brief you about the 8051 series, 8051 is a popular 8-bit microcontroller family developed by Intel, this family has 4KB of ROM or program memory and 128 bytes of RAM, the 8052 family is also similar to 8051 just it has an additional ROM of 4KB i.e. total of 8KB and also additional RAM of 128 bytes, making a total of 256bytes, We will be using AT89S52, it is the widely popular microcontroller for small-scale projects with powerful hardware. it sports 8 KB of program memory (ROM) 256 bytes of RAM and 4 ports, for peripherals. after its launch, it became widely popular for various applications, and currently, it is available in multiple versions in the market by different vendors, this hardware is more than enough for our use case, we can also use AT89S51 as well.
Components
- 1 - 16X2 LCD
- 1 - AT89S51/2 Microcontroller ( For controlling the LCD )
- 1 - Potentiometer ( For adjusting the Backlight of the LCD )
- 12 Approx. - connecting wires
16X2 LCD
In your day-to-day life, you must have seen small green-coloured displays from various appliances like DVD Players, Medical Devices, Industrial Control Panels, and Energy Meters. those green coloured displays are called 16X2 LCDs, The term LCD stands for Liquid Crystal Display the 16 refers to the number of rows, and the 2 is the number of columns. these are used in a variety of applications like many consumer electronic devices, embedded systems, control panels, information kiosks, weighing machines at public places and the list goes on.
The 16X2 LCD can be configured in two modes i.e. 8-bit mode and 4-bit mode, for the sake of simplicity we will be using 8-bit mode. So connect the data pins to the desired port of the microcontroller, but be careful with the PORT 0, it doesn’t have internal pull-ups, so to use the PORT 0 you need to connect external pull-up resistors.
Pin configuration of 16x2 LCD
sr no | name | function |
---|---|---|
1 | VSS | ground |
2 | VDD | power supply ( +5V ) |
3 | VEE | contrast |
4 | RS | register select |
5 | R/W | read / write 0=write 1=read |
6 | E | enable |
7-14 | Data | Data lines |
15 | A | Anode ( LCD Backlight ) |
16 | K | Cathode ( LCD Backlight ) |
Here I am connecting the LCD to PORT 1, and other pins i.e.
- RS ( Register Select ): PORT2_0
- R/W ( Read/Write ): PORT2_1
- E ( Enable ): and PORT2_2.
For simplicity, here I have not shown the LCD contrast, VCC
, GND
, and pins but make their connections too, connecting the VCC`` to +5V,
GND` to ground, and the contrast to the Ground through a potentiometer. As our Connections part is done, we will write a program to print "KRYPTON" on this LCD.
16X2 LCD Commands
LCD Commands are the crucial instructions for the Display to perform certain tasks, these commands need to be sent to LCD to work properly
sr no. | Command | Purpose |
---|---|---|
1 | 0x01 | Clear Screen |
2 | 0x02 | Return Home |
3 | 0x04 | Decrement/Shift Cursor Left |
4 | 0x05 | Shift Display Right |
5 | 0x06 | Increment/Shift Cursor Right |
6 | 0x07 | Shift Display Left |
7 | 0x08 | Display Off, Cursor Off |
8 | 0x0A | Display Off, Cursor On |
9 | 0x0C | Display On, Cursor Off |
10 | 0x0E | Display On, Cursor On |
11 | 0x0F | Display On, Cursor Blink |
12 | 0x10 | Shift cursor position to left |
13 | 0x14 | Shift cursor position to Right |
14 | 0x18 | Shift entire display to left |
15 | 0x1C | Shift entire display to Right |
16 | 0x80 | Force cursor to beginning of 1st line |
17 | 0xC0 | Force cursor to beginning of 2nd line |
18 | 0x38 | 2 lines 5x7 matrix |
C Program for AT89S52 (8052) Microcontroller
#include<AT89X52.h> //header file
#define RS P2_0 //register select pin
#define RW P2_1 //read/write pin
#define EN P2_2 //enable pin
#define PORT P1
void delay(); //delay function
void com(char ); //to send command to LCD
void dat(char ); //to send data to LCD
void print(char ); //our function to print the name.
void main(){
while(1){
char text[]="KRYPTON";
int i,n=0;
com(0x0c); // display on cursor off
com(0x01); //clear screen
while(text[i]!='\0'){ //continue to print till we get the null character
// this block is intentionally commented. to be used when printing more than 16 characters
/* if(i>15){
com(0x1c); //shift display left
com(0x0c);
}
*/
print(text[i]);
i++;
}
while(9);
}
}
void print(char c){
com(0x06); // shift cursor to right >>>>>>
dat(c); // pass the character to LCD
}
void delay(){
short int i;
for(i=0;i<=255;i++);
}
void com(char m){
PORT=m;
RS=0;
RW=0;
EN=1;
delay();
EN=0;
delay();
}
void dat(char m){
PORT=m;
RS=1;
RW=0;
EN=1;
EN=0;
delay();
}
In the code above, we have defined a few macros for the connections to the PORTS of our microcontroller, we have included the AT89X52.h
header file to interact with the microcontroller, the same code works for at89s52, at89c52, or other 8052 family of microcontrollers, after that, we have declared prototypes of a few functions, that we have provided definitions after the main
function. the delay
function adds a short delay which is necessary as this LCD requires a High To Low pulse of ~10ms, function com
is for command and dat
is for passing data or text to our display, the function print
is responsible for shifting the cursor and printing characters.
So in the function main
, we have defined an array of characters to store our name, The next lines are to initialize the LCD, i.e. turn on the display and clear the screen (initialization process). Now we have a function print
that simply takes the character and displays it on the LCD by incrementing the cursor (i.e. shifting the cursor to the right). So calling the print function will take one character at a time then do the cursor shifting operation and finally pass the character to the data function that displays it.
But as our LCD has some speed limitations, we cannot pass the values repeatedly in a very short span, we need to add some delay otherwise the LCD will get overloaded and ignore the input, thus we are calling our delay function after every command or data function call. There is a proper way to do this by checking the LCD busy flag, then sending the data else waiting till the busy flag clears, but this becomes very much complex, so we are not using the actual busy flag method instead we have used a simple for loop that creates the similar delay. the last line while(9)
is intentionally placed there, as we don't want to perform any operation once our name is printed, 9 is a truthy value, hence the while(9)
is an infinite loop so there will be no operation after printing "KRYPTON".
If you read the code, you'll find that there is a commented block, which you can use if you want to print longer words, this block will shift the display making space available for the new characters.
Preview of LCD interfaced with 8051
C Program for AT89S51 (8051) microcontroller
The only change here is the header file changed to AT89S51 specific, the rest of the code is similar and you can use it with the AT89X51 microcontroller.
#include<AT89X51.h> //header file is changed to **AT89X51.h**
#define RS P2_0 //register select pin
#define RW P2_1 //read/write pin
#define EN P2_2 //enable pin
#define PORT P1
void delay(); //delay function
void com(char ); //to send command to LCD
void dat(char ); //to send data to LCD
void print(char ); //our function to print the name.
void main(){
while(1){
char text[]="KRYPTON";
int i,n=0;
com(0x0c); // display on cursor off
com(0x01); //clear screen
while(text[i]!='\0'){ //continue to print till we get the null character
// this block is intentionally commented. to be used when printing more than 16 characters
/* if(i>15){
com(0x1c); //shift display left
com(0x0c);
}
*/
print(text[i]);
i++;
}
while(9);
}
}
void print(char c){
com(0x06); // shift cursor to right >>>>>>
dat(c); // pass the character to LCD
}
void delay(){
short int i;
for(i=0;i<=255;i++);
}
void com(char m){
PORT=m;
RS=0;
RW=0;
EN=1;
delay();
EN=0;
delay();
}
void dat(char m){
PORT=m;
RS=1;
RW=0;
EN=1;
EN=0;
delay();
}
Additional Links:
conclusion
16X2 display can be used to print useful information/status for small-scale projects, and embedded systems, these displays operate on 3.3V to 5V DC source and don't require much configuration, also these displays come with an option to adjust the contrast levels so one can increase/decrease the contrast of the display for proper viewing experience. overall these displays can be a great choice for small texts like status information, etc, also we can emulate scrolling text behaviour to display characters more than 16 in length.