16x2 LCD Interface with 8051 (4-bit Mode, Port 2 Only)
This tutorial explains how to interface a 16x2 LCD with the 8051 microcontroller using 4-bit mode, with both data and control lines connected to Port 2.
📌 Overview
In this setup:
- D4–D7 → P2.4–P2.7
- RS → P2.0
- RW → P2.1
- EN → P2.2
This allows the entire LCD to be controlled using a single port (Port 2).
🔌 Pin Configuration
LCD Connections
| LCD Pin | Function | 8051 Pin |
|---|---|---|
| RS | Register Select | P2.0 |
| RW | Read/Write | P2.1 |
| EN | Enable | P2.2 |
| D4 | Data | P2.4 |
| D5 | Data | P2.5 |
| D6 | Data | P2.6 |
| D7 | Data | P2.7 |
D0–D3 are not used in 4-bit mode
⚙️ Bit Mapping of Port 2
| P2 Pin | Function |
|---|---|
| P2.0 | RS |
| P2.1 | RW |
| P2.2 | EN |
| P2.3 | Unused |
| P2.4–P2.7 | Data (D4–D7) |
⚙️ How It Works
- Data is sent in two nibbles
- Upper nibble → P2.4–P2.7
- Lower nibble → P2.4–P2.7 (shifted)
- Control bits must remain unaffected during data transfer
🧠 Important Concept
Since control and data share the same port, we must:
- Preserve lower bits (P2.0–P2.3)
- Modify only upper nibble when sending data
💻 8051 C Program
#include <reg51.h>
#define LCD P2
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
// Delay
void delay(unsigned int time) {
unsigned int i, j;
for(i = 0; i < time; i++)
for(j = 0; j < 1275; j++);
}
// Enable pulse
void lcd_enable() {
EN = 1;
delay(1);
EN = 0;
}
// Send 4-bit data safely
void lcd_send_nibble(unsigned char nibble) {
LCD &= 0x0F; // Keep lower bits (control pins safe)
LCD |= (nibble & 0xF0); // Send upper nibble
lcd_enable();
}
// Send command
void lcd_cmd(unsigned char cmd) {
RS = 0;
RW = 0;
lcd_send_nibble(cmd); // High nibble
lcd_send_nibble(cmd << 4); // Low nibble
delay(2);
}
// Send data
void lcd_data(unsigned char dat) {
RS = 1;
RW = 0;
lcd_send_nibble(dat);
lcd_send_nibble(dat << 4);
delay(2);
}
// LCD Init
void lcd_init() {
delay(20);
lcd_cmd(0x02); // 4-bit init
lcd_cmd(0x28); // 2 line, 4-bit
lcd_cmd(0x0C); // Display ON
lcd_cmd(0x01); // Clear
lcd_cmd(0x06); // Entry mode
}
// Print string
void lcd_string(char *str) {
while(*str) {
lcd_data(*str++);
}
}
// Main
void main() {
lcd_init();
lcd_string("Port2 LCD");
while(1);
}