[Moved] LCD 16*2 in 4 bit mode using pic16f877a

Status
Not open for further replies.

renuka gurmeet singh

Junior Member level 2
Joined
Jun 7, 2014
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
132
Please help me to correct this code.Thanks in advance.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<htc.h>
#define _16F877
 
#define XTAL_FREQ   12MHZ
__CONFIG( FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON 
        & LVP_OFF & CPD_OFF & DEBUG_OFF);
 
#define     lcd_port    PORTD
#define     LCD_EN      RB1
#define     LCD_RS      RB0
/////////////////////delay routine///////////////////////////////////
void delay(unsigned int temp)
{
    while(temp!=0)
    {
    temp--;
    }
}
 
/////////////////////main program///////////////////////////////////////
void lcd_cmd (unsigned char cmd)
{
    delay(40);
LCD_RS=0;
lcd_port=((cmd>>4)&0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
lcd_port=(cmd & 0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
}
 
void lcd_data (unsigned char dat)
{
    delay(40);
LCD_RS=1;
lcd_port=((dat>>4)&0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
lcd_port=(dat & 0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
}
void lcd_string(unsigned char *str)
{
    while(*str)
        lcd_data(*str++);
        delay(300);
}
void lcd_init ()
{
        lcd_cmd (0x28);       // 4-bit mode - 2 line - 5x7 font.
        lcd_cmd (0x0C);       // Display no cursor - no blink.
        lcd_cmd (0x06);       // Automatic Increment - No Display shift.
        lcd_cmd (0x80);       // Address DDRAM with 0 offset 80h.
 }
void main(void)
{
        TRISD=0x00;
        TRISB0=0;
        TRISB1=0;
        delay(200);
        lcd_init ();
        lcd_cmd (0x81);
        lcd_data("hvvv");
        lcd_cmd (0xc1);
        lcd_data("g");
    //  while(1);
        
    
}

 
Last edited by a moderator:

How long are those delays?

You seem to be using typical values in mS but the delay is actually just a decrementing loop, with a 16MHz clock each pass of the loop will only be microseconds.
Also check the initial start-up delay (line 23), on some LCDs it can be as much as 100mS before they accept commands.

Brian.
 


Thanks for the reply.I have changed the delays to 200ms,but still its not working.It has been successfully comipled in MPlab with HI-TECH compiler but its not simulating on proteus.I am new to pic microcontroller, help me to solve it.I have attached the pic of my circuit herewith.View attachment lcd in 4 bit mode.bmp
 

ur code should like this...

Code:
#include<htc.h>
#define _16F877
 
#define XTAL_FREQ   12MHZ
__CONFIG( FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON 
        & LVP_OFF & CPD_OFF & DEBUG_OFF);
 
#define     lcd_port    PORTD
#define     LCD_EN      RB1
#define     LCD_RS      RB0
/////////////////////delay routine///////////////////////////////////
void delay(unsigned int temp)
{
    while(temp!=0)
    {
    temp--;
    }
}
 
/////////////////////main program///////////////////////////////////////
void lcd_cmd (unsigned char cmd)
{
    delay(40);
LCD_RS=0;
lcd_port=((cmd>>4)&0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
lcd_port=(cmd & 0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
}
 
void lcd_data (unsigned char dat)
{
    delay(40);
LCD_RS=1;
lcd_port=((dat>>4)&0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
lcd_port=(dat & 0x0F);
    LCD_EN=1;
delay(50);
    LCD_EN=0;
}
void lcd_string(unsigned char *str)
{
    while(*str)
        lcd_data(*str++);
        delay(300);
}
void lcd_init ()
{
        lcd_cmd (0x03);  
        lcd_cmd (0x03);  
        lcd_cmd (0x03);  
        lcd_cmd (0x28);       // 4-bit mode - 2 line - 5x7 font.
        lcd_cmd (0x0C);       // Display no cursor - no blink.
        lcd_cmd (0x06);       // Automatic Increment - No Display shift.
        lcd_cmd (0x80);       // Address DDRAM with 0 offset 80h.
 }
void main(void)
{
        TRISD=0x00;
        TRISB0=0;
        TRISB1=0;
        delay(200);
        lcd_init ();
        lcd_cmd (0x81);
        lcd_data("hvvv");
        lcd_cmd (0xc1);
        lcd_data("g");
      while(1);
}
 

Those delays are quite wrong!

When you use a command like 'delay(40)' expecting a delay of 40mS which is possibly the right delay your LCD needs. However, when you call your delay function, all you do is count 40 down to zero to create the delay. With a 12MHz clock you execute 3,000,000 instructions per second. Your compiler may be producing code that is a small as 2 instructions so when you want 40mS you actually get only 0.013mS which is far too short.

You have three options to fix it:
1. use HTC's built in delay functions if it has them (I don't use HTC so I'm not certain but most compilers have delay functions in them).
2. increase the value you pass to the function by a factor of 3,000 times - but beware of exceeding the limit for an int value. delay(40); becomes delay(120,000);.
3. slow down the delay function so each count you request from it takes longer.

Brian.
 

Please post your new code with the longer delays. The schematic looks OK. I still suspect you have a timing problem.

Brian.
I have increased the delays,but the same problem persists.Please do a look at the code,i suspect there is a problem in delays.I did a little bit modifications in the circuit and code.The circuit image is enclosed herewith.Please do a look.
Code:
#include<htc.h>
#define _16F877

#define	XTAL_FREQ	12MHZ
 
#define 	lcd_port 	PORTD
#define   	LCD_EN	 	RB1
#define   	LCD_RS 		RB0
////////////////////////////////////////////////////////////////////
//void delay();
//void lcd_cmd ();
//void lcd_data (unsigned char dat);
//void lcd_init ();

/////////////////////delay routine///////////////////////////////////
void delay(unsigned short int temp)
{
	while(temp!=0)
	{
	temp--;
	}
}

/////////////////////main program///////////////////////////////////////
void lcd_cmd (unsigned char cmd)
{
		unsigned char a;
		a=cmd;
        lcd_port = (cmd & 0xf0);
		LCD_RS=0;
		LCD_EN=1;
		delay(3000);
       	LCD_EN=0;
		a=cmd;
        lcd_port = ((cmd<<4) & 0xf0);
		LCD_RS=1;
		LCD_EN=1;
		delay(3000);
       	LCD_EN=0;
        delay(50000);
}

void lcd_data (unsigned char dat)
{
		unsigned char a;
		a=dat;
        lcd_port = (dat & 0xf0);
		LCD_RS=1;
		LCD_EN=1;
		delay(30000);
       	LCD_EN=0;
		a=dat;
        lcd_port = ((dat<<4) & 0xf0);
		LCD_RS=1;
		LCD_EN=1;
		delay(30000);
       	LCD_EN=0;
        delay(50000);
        delay(500);
}
void lcd_string(unsigned char *str)
{
	while(*str)
		lcd_data(*str++);
		delay(65000);
}
void lcd_init ()
{
        lcd_cmd (0x28);       // 4-bit mode - 2 line - 5x7 font.
 lcd_cmd (0x3c);  
        lcd_cmd (0x0C);       // Display no cursor - no blink.
        lcd_cmd (0x06);       // Automatic Increm        lcd_cmd (0x80);       // Address DDRAM with 0 offset 80h.
 }
void main(void)
{
		TRISD=0x00;
		TRISB=0x00;
		delay(20000);
		lcd_init ();
		lcd_cmd (0x81);
		lcd_string("HELLO");
		lcd_cmd (0xc1);
		lcd_string("NITISH");
	//	while(1);
		
	
}
 

You still have the delays wrong!

I compiled the code using Microchips own compiler XC8 and these are the actual delays when simulated:

delay(3000); = 12.005mS
delay(5000); = 20.005mS
delay(50000); = 200mS
delay(30000); = 120mS
delay(500); = 2.005mS
delay(65000); = 260mS
delay(20000); = 80mS

Those figures are using XC8 in free mode so they are not optimized, in an optimized compiler the actual delays would almost certainly be shorter.

I suggest reverting to the manufacturers times for the LCD as your delay parameter and adjusting the delay() routine so the parameter value represents steps of 1mS. If you do that, delay(40) will be 40mS, delay(100) will be 100ms and so on. I did a quick Google search and it says HTC version 9.6 onwards have delay functions built in. Try using '__delay_ms(x);' to get millisecond delays where x is the number of milliseconds you want. Note the command is two underscores at the beginning!

Brian.
 

Try using '__delay_ms(x);' to get millisecond delays where x is the number of milliseconds you want. Note the command is two underscores at the beginning!
Thanks it helped me a lot.Thanku dude. :-D
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…