#include < htc.h>
#define _XTAL_FREQ 20e6
#define en RD7
#define rs RD6
#define rw RD5

void delay(unsigned int time)  //Time delay function - Arbitrary delay
{
unsigned int i,j;
for(i=0;i< time;i++)
for(j=0;j< 5;j++);
}

             //Function sending commands to the command register of LCD
void llcdcmd(unsigned char value)  
{
RB0=(value >> 0) & 0x01;
RB1=(value >> 1) & 0x01;
RB2=(value >> 2) & 0x01;
RB3=(value >> 3) & 0x01;

en = 1;    //enable-e
delay(500);
en=0;       //enable-e
delay(500);
}
             //Function sending data to the data register of LCD
void ddisplay(unsigned char value)  
{
RB0=(value >> 0) & 0x01;
RB1=(value >> 1) & 0x01;
RB2=(value >> 2) & 0x01;
RB3=(value >> 3) & 0x01;

en= 1;       //enable-e
delay(500);
en=0;        //enable-e
delay(500);
}


void display(unsigned char c){
rs= 1;       //register select-rs 
rw= 0;       //read-write-rd
delay(150);
ddisplay(c>>4);         //Send Higher nibble 4-bits of 8-bit data
delay(150);
ddisplay(c);            //Send Lower nibble  4-bits of 8-bit data

}
void lcdcmd(unsigned char c){
rs= 0;           //register select-rs 
rw = 0;          //read-write-rd
delay(150);
llcdcmd(c>>4);          //Send Higher nibble 4-bits of 8-bit command
delay(150);
llcdcmd(c);             //Send Lower nibble 4-bits of 8-bit command
}
             //Function to initialize the registers and pins of LCD
             //always use with every lcd of Hitachi
void lcdint(void)         
{
TRISB0=0;
TRISB1=0;
TRISB2=0;
TRISB3=0;               //Port-B is used as output port             
TRISD5=0;               //Read-Write pin as output
TRISD6=0;               //Register select pin as output
TRISD7=0;               //Enable pin as output
rw=0;
rs=0;
PORTB &= 0xF0;	  
PORTB |= (0x03&0x0F);    // Write 0x3
en  = 1;               
delay(150);
en  = 0;               
delay(150);
delay(4500);

PORTB &= 0xF0;	  
PORTB |= (0x03&0x0F);    // Write 0x3
en  = 1;               
delay(150);
en  = 0;              
delay(150);
delay(300);

PORTB &= 0xF0;	  
PORTB |= (0x03&0x0F);    // Write 0x3
en  = 1;              
delay(150);
en  = 0;              
delay(150);
delay(650);

PORTB &= 0xF0;	 
PORTB |= (0x02&0x0F);    // Write 0x2
en  = 1;               
delay(150);
en  = 0;              
delay(150);

display(0x20);          //Lcd in 4-bit mode, 1 line and 5x7 font character
delay(1000);
lcdcmd(0x28);           //Lcd in 4-bit mode, 2 Line and 5x7 font character
delay(50);
lcdcmd(0x0C);           //Display on cursor off
delay(50);
lcdcmd(0x01);           //Clear Lcd Screen
delay(50);
lcdcmd(0x06);           //Entry Mode
delay(50);
lcdcmd(0x80);           //Start from first line
delay(50);
}

void main()
{
lcdint();                 //Initialize character lcd
display('M'); display('i'); display('c'); display('r'); display('o'); display('c');
display('o'); display('n'); display('t'); display('r'); display('o'); display('l');
display('l'); display('e'); display('r');
lcdcmd(0xC0);             //Jump to second line
display('M'); display('i'); display('c'); display('r'); display('o'); display('c');
display('o'); display('n'); display('t'); display('r'); display('o'); display('l');
display('l'); display('e'); display('r');
lcdcmd(0x01);             //Clear lcd
delay(500);
}
Note: Although i declared the R/W pin in code (RD-5) but i am not using it. I made the lcd R/W pin directly ground. So now it remains always in write mode.
Download the project files and code with simulation. Simulation is made in proteaus and code is written using MP-lab ide and high tech c compiler. Please give us Your feed back on the project. If you have any questions regarding post or you dont understand any instruction please leave your comments below.
                                                                                                                                                                       Lcd in 4-bit mode with Pic16f877 code/file