PIC16F877A – LCD 4Bit Interfacing

This article is a continuation of the series of tutorials on the PIC16F877A Microcontroller. The aim of this series is to provide easy and practical examples that anyone can understand. In the previous LCD tutorial, we have used that LCD in 8-bit mode. But here we will see LCD 4-bit interfacing with PIC16F877A Microcontroller.

LCD 4 bit interfacing with PIC16F877A

Introduction

8-bit mode –  Using 8 data lines in LCD (totally 8 data lines are there)

4-bit mode –  Using only 4 data lines in the LCD module

8-bit mode is already working and that looks awesome. Then why we are going to 4-bit mode? This is the question that comes to mind whenever I said 4-bit mode. Yeah, that 8-bit mode is nice. But but but… Just assume. I’m doing one project which requires more number of hardware. But PIC16F877A has only 33 GPIOs. So in that time I can use this 4-bit mode and reduce the pin required for the LCD module. Am I right? Great. That’s why 4-bit mode also important. Already we know the LED’s operation. If we want to enable 4-bit mode we have to do small modifications in the normal method. Let’s see that.

In initializing time we have to give 0x28 command. That’s all.

LCD Initializing

void lcd_init()
{
    cmd(0x02);
    cmd(0x28);
    cmd(0x0e);
    cmd(0x06);
    cmd(0x80);
}

Sending command

Here everything is the same except the way of data writing. Here we have only 4 bits. So we need to send nibble by nibble. So first we need to send first nibble then followed by the second. See that code. I’m writing into Port B’s last 4 bits. Because the last 4 bits are connected to LCD.

void cmd(unsigned char a)
{
    rs=0; 
    PORTB&=0x0F;
    PORTB|=(a&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
    PORTB&=0x0f;
    PORTB|=(a<<4&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
}

Sending Data

Same as sending the command.

void dat(unsigned char b)
{
    rs=1; 
    PORTB&=0x0F;
    PORTB|=(b&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
    PORTB&=0x0f;
    PORTB|=(b<<4&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
}

Circuit Diagram

Code

#include <pic.h>

__CONFIG( FOSC_HS & WDTE_OFF & PWRTE_OFF & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & WRT_OFF & DEBUG_OFF);


#define rs RD2
#define en RD3

void lcd_init();
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay();

void main()
{
    unsigned int i;
    TRISB=TRISD2=TRISD3=0;
    lcd_init();
    cmd(0x90);
    show("www.EmbeTronicX.com");
    while(1)
    {
        for(i=0;i<15000;i++);
        cmd(0x18);
        for(i=0;i<15000;i++);
        
    }   
}

void lcd_init()
{
    cmd(0x02);
    cmd(0x28);
    cmd(0x0e);
    cmd(0x06);
    cmd(0x80);
}

void cmd(unsigned char a)
{
    rs=0; 
    PORTB&=0x0F;
    PORTB|=(a&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
    PORTB&=0x0f;
    PORTB|=(a<<4&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
}

void dat(unsigned char b)
{
    rs=1; 
    PORTB&=0x0F;
    PORTB|=(b&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
    PORTB&=0x0f;
    PORTB|=(b<<4&0xf0);
    en=1;
    lcd_delay();
    en=0;
    lcd_delay();
}

void show(unsigned char *s)
{
    while(*s) {
        dat(*s++);
    }
}

void lcd_delay()
{
    unsigned int lcd_delay;
    for(lcd_delay=0;lcd_delay<=1000;lcd_delay++);
}

Output

LCD 4 bit interfacing with PIC16F877A[ Please find the output image Here ]

Hope you learned something from this. You can download the whole project here.

In our next tutorial, we will see how to interface the DC motor with PIC16F877A.

You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
STM32F7 Bootloader TutorialsRaspberry PI Pico Tutorials
STM32F103 Bootloader TutorialsRT-Thread RTOS Tutorials
Zephyr RTOS Tutorials - STM32Zephyr RTOS Tutorials - ESP32
AUTOSAR TutorialsUDS Protocol Tutorials
Product ReviewsSTM32 MikroC Bootloader Tutorial
VHDL Tutorials
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Table of Contents