Skip to main content

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 PinFunction8051 Pin
RSRegister SelectP2.0
RWRead/WriteP2.1
ENEnableP2.2
D4DataP2.4
D5DataP2.5
D6DataP2.6
D7DataP2.7

D0–D3 are not used in 4-bit mode


⚙️ Bit Mapping of Port 2

P2 PinFunction
P2.0RS
P2.1RW
P2.2EN
P2.3Unused
P2.4–P2.7Data (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);
}