Liquid Crystal Display (LCD):
16x2 LCD can be interfaced with microcontroller in 4 Bit or 8 Bit mode. These differs in how data is send to LCD. In 8 bit mode to write a character, 8 bit ASCII data is send through the data lines D0 – D7 and data strobe is given through E of the LCD. LCD commands which are also 8 bit are written to LCD in similar way.But 4 Bit Mode uses only 4 data lines D4 – D7. In this mode 8 bit character ASCII data and command data are divided into two parts and send sequentially through data lines. The idea of 4 bit communication is used save pins of microcontroller. 4 bit communication is a bit slower than 8 bit communication but this speed difference can be neglected since LCD's are slow speed devices. Thus 4 bit mode data transfer is most commonly used.
Hardware Connection:
16x2 LCD Display 4bit mode with PIC16f877a |
Program:
/*
* File: 5_LCDisplay4BitMode.c
* Author: Udaya Prakash Jayaraman
* 5_LcdDisplay4BitMode.c
*
* Circuit Connection
* Vss to Ground
* Vcc to 5V
* Vee to potentiometer to adjust brightness if needed
* RS- Register Select (0-Command mode)(1-data mode)
* RW- Read/Write, R/W=0: Write & R/W=1: Read
* EN- Enable. Falling edge triggered
* B4 to B7 Databit 0 to 4
* So connect D0 to D4 in Port B4 to B7
* Connect RS(RB0), RW(RB1 or Gnd), EN(RB2)
* A- Anode(+)
* K- Cathode(-)
*
*
* Created
*/
#define _XTAL_FREQ 8000000
#pragma config FOSC = HS // Oscillator Selection bits (RC oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <pic16f877a.h>
/* Configure the data bus and Control bus as per the hardware connection
Databus is connected to P2.4:P2.7 and control bus P2.0:P2.2*/
#define LcdDataBus PORTB //Data Bus
#define LcdBusPins TRISB
#define EN RB2 //use EN as 0 or 1 to sent data and command
#define RW RB1 // Use RW as 0 to set in write mode
#define RS RB0 // Register Select (0-Command mode)(1-data mode)
/* local function to generate delay */
void delay(int cnt)
{
unsigned int i,j;
for(i=0;i<cnt;i++)
{
for(j=0;j<=100;j++);
}
}
/* Function to send the command to LCD.
As it is 4bit mode, a byte of data is sent in two 4-bit nibbles */
void Lcd_CmdWrite(char cmd)
{
LcdDataBus = (cmd & 0xF0); //Send higher nibble
RS = 0; // Send LOW pulse on RS pin for selecting Command register
RW = 0; // Send LOW pulse on RW pin for Write operation
EN = 1; // Generate a High-to-low pulse on EN pin
delay(1000);
EN = 0;
delay(100);
LcdDataBus = ((cmd<<4) & 0xF0); //Send Lower nibble
RS = 0; // Send LOW pulse on RS pin for selecting Command register
RW = 0; // Send LOW pulse on RW pin for Write operation
EN = 1; // Generate a High-to-low pulse on EN pin
delay(100);
EN = 0;
delay(100);
}
/* Function to send the Data to LCD.
As it is 4bit mode, a byte of data is sent in two 4-bit nibbles */
void Lcd_DataWrite(char dat)
{
LcdDataBus = (dat & 0xF0); //Send higher nibble
RS = 1; // Send HIGH pulse on RS pin for selecting data register
RW = 0; // Send LOW pulse on RW pin for Write operation
EN = 1; // Generate a High-to-low pulse on EN pin
delay(100);
EN = 0;
delay(100);
LcdDataBus = ((dat<<4) & 0xF0); //Send Lower nibble
RS = 1; // Send HIGH pulse on RS pin for selecting data register
RW = 0; // Send LOW pulse on RW pin for Write operation
EN = 1; // Generate a High-to-low pulse on EN pin
delay(100);
EN = 0;
delay(100);
}
int main()
{
LcdBusPins = 0x00; // Configure all the LCD pins as output
while(1)
{
char i,a[]={"PIC16F877A MCU!"};
Lcd_CmdWrite(0x02); // Initialize Lcd in 4-bit mode
Lcd_CmdWrite(0x28); // enable 5x7 mode for chars
Lcd_CmdWrite(0x0E); // Display OFF, Cursor ON
Lcd_CmdWrite(0x01); // Clear Display
Lcd_CmdWrite(0x80); // Move the cursor to beginning of first line
Lcd_DataWrite('H');
Lcd_DataWrite('i');
Lcd_DataWrite(' ');
Lcd_DataWrite('U');
Lcd_DataWrite('d');
Lcd_DataWrite('a');
Lcd_DataWrite('y');
Lcd_DataWrite('a');
Lcd_DataWrite('P');
Lcd_DataWrite('r');
Lcd_DataWrite('a');
Lcd_DataWrite('k');
Lcd_DataWrite('a');
Lcd_DataWrite('s');
Lcd_DataWrite('h');
Lcd_CmdWrite(0xc0); //Go to Next line and display Good Morning
for(i=0;a[i]!=0;i++)
{
Lcd_DataWrite(a[i]);
}
}
}