|
|
View previous topic :: View next topic |
Author |
Message |
winson
Joined: 03 Dec 2008 Posts: 24
|
LCD just show grey square |
Posted: Sun Feb 01, 2009 7:51 am |
|
|
Hello,
I was trying to write a simple LCD testing program to display "P" on 1st line and display "L" on the 2nd line, but my 16x2 LCD just show 2 line of grey square. I was using the Port C & Port D of my PIC16F877A and using 8-bits interface to display character on my LCD. I also try to put a pullup resistor to all the port's pins that used but the results is still the same. The 8 data pins of the LCD is connect to Port D and RS, RW, E is connect to the first 3 pins(RA0, RA1, RA2) of Port C.
To write this testing program i was refer to the information provided in the HD44780U datasheet.
Anybody can give some suggestions regarding the error that i have make?
The testing program is shown below.
Any suggestion will be greatly appreciate.
Thanks.
Code: |
#include <16F877A.h>
#fuses hs, nowdt, nolvp, noprotect //Config
#use delay (clock = 20000000) //20MHz Crystal
void init(void); //Function Prototype
void busy_test(void);
void display(void);
void send_command(void);
void send_data(void);
unsigned char PORTC, TRISC, PORTD, TRISD, RS, RW, E, BF;
unsigned char command, data;
#byte PORTC = 0x07
#byte TRISC = 0x87
#byte PORTD = 0x08
#byte TRISD = 0x88
#bit RS = PORTC.0
#bit RW = PORTC.1
#bit E = PORTC.2
#bit BF = PORTD.7
void main()
{
init();
display();
while (1)
{
}
}
void init()
{
PORTC = 0x00; //Clear Port C
PORTD = 0x00; //Clear Port D
TRISC = 0x00; //Set Port C As Output
TRISD = 0x00; //Set Port D As Output
delay_ms (500); //Power-On Delay
//Busy Flag Valid Here
//busy_test(); //Check Busy Flag
command = 0x38; //8-Bits, 2-Lines, 5x7 Dots
send_command(); //Send Command To LCD
delay_ms (10);
//busy_test(); //Check Busy Flag
command = 0x38; //8-Bits, 2-Lines, 5x7 Dots
send_command(); //Send Command To LCD
delay_us (500);
//busy_test(); //Check Busy Flag
command = 0x38; //8-Bits, 2-Lines, 5x7 Dots
send_command(); //Send Command To LCD
delay_ms (1);
busy_test(); //Check Busy Flag
command = 0x38; //8-Bits, 2-Lines, 5x7 Dots
send_command(); //Send Command To LCD
delay_ms (1);
busy_test(); //Check BF
command = 0x08; //Display Off, Cursor Off, No-Blink
send_command(); //Send
delay_ms (1);
busy_test();
command = 0x01; //Clear Display
send_command();
delay_ms (5);
busy_test();
command = 0x06; //Increment Cursor Position, No-Shift
send_command();
delay_ms (1);
busy_test();
command = 0x0F; //Display On, Cursor On, Blink
send_command();
delay_ms (1);
}
void display()
{
busy_test();
command = 0x80; //Set DDRAM Address To 0x00
send_command();
delay_ms (1);
busy_test();
data = 0x50; //Display "P"
send_data();
delay_ms (1);
busy_test();
command = 0xC0; //Set DDRAM Address To 0x40
send_command();
delay_ms (1);
busy_test();
data = 0x4C; //Display "L"
send_data();
delay_ms (1);
}
void busy_test()
{
while (1)
{
TRISD = 0xFF; //Set Port D As Input
//RS = 0; //Command
//RW = 1; //Read Busy Flag
PORTC = 0x02;
delay_cycles (2); //Control Setup Time
//E = 1; //E-Line High
PORTC = 0x06;
delay_cycles (6); //Wait Data Return
if (BF == 0)
{
TRISD = 0x00; //Set Port D Back To Output
//E = 0; //E-Line Low
PORTC = 0x02;
return;
}
//E = 0; //E-Line Low
PORTC = 0x02;
} //End while loop
} //End Function
void send_command()
{
//RS = 0; //Command
//RW = 0; //Write Instruction
PORTC = 0x00;
delay_cycles (2); //Control Setup Time
//E = 1; //E-Line High
PORTC = 0x04;
delay_cycles (3);
PORTD = command; //Put Command To Port D
delay_cycles (3); //Data Setup Time
//E = 0; //E-Line Low
PORTC = 0x00;
delay_cycles (1); //Control & Data Hold Time
}
void send_data()
{
//RS = 1; //Data
//RW = 0; //Write data
PORTC = 0x01;
delay_cycles (2); //Control Setup Time
//E = 1; //E-Line High
PORTC = 0x05;
delay_cycles (3);
PORTD = data; //Put Data To Port D
delay_cycles (3); //Data Setup Time
//E = 0; //E-Line Low
PORTC = 0x01;
delay_cycles (1); //Control & Data Hold Time
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Sun Feb 01, 2009 9:17 am |
|
|
With working code, the normal reason for this, is not having the right voltage on the bias pin (V0). What needs to be on this, varies with the make of the module. Older modules needed a -ve voltage here. Most modern ones need a small +ve voltage, typically something like 0.4v. This is normally fed from a pot, to allow you to set the LCD 'contrast', and set wrong, the LCD just displays rectangular blobs for each character.
There is a driver program for these LCD's included with the compiler, and another (more flexible) one in the code library. Use 'known working' code....
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
winson
Joined: 03 Dec 2008 Posts: 24
|
|
Posted: Tue Feb 03, 2009 4:51 am |
|
|
Finally the LCD is WORKING!
The problem is in the power supply. The 5V Vdd supply voltage drop to 4.33V when it is connect to the LCD. I was using a battery for the LCD, due to high supply current of the 9V battery, thus have to put a current limiting resistor to limit the current that goes into the LCD, And i think because of the LCD consist of certain amount of internal resistance(from calculation it is around 23.23K ohms), this resistance will form a voltage divider with my current limiting resistor and make the supply voltage to the LCD drop to 4.33V. Normally, for LCD it's Vdd range is from 4.5V to 5.5V in order for it to work correctly.
After adjust the value of the current limiting resistor to get back a Vdd which is around 4.6V then the LCD work nicely. Besides, for the Vo of the LCD i was directly connect it to ground to get maximum contrast, this is to avoid the variable resistor(pot) that use to control the contrast from disturbing the voltage value of the Vdd.
For the send_command() and send_data() function i was modify the code to first load the data to the Port D then toggle the E signal from low to high then goes back to low again. I think it also work by set the E signal to high first then load data to Port D and after that set E to low, but since the LCD is working then i will follow the modified code.
Thanks everybody for giving all the useful information! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 03, 2009 3:28 pm |
|
|
Normally a voltage regulator I.C. is used to avoid this problem.
A voltage regulator will maintain +5.0v within its specified maximum
current limit. The most commonly known type is called LM7805. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|