DB0 EQU P0.0
DB1 EQU P0.1
DB2 EQU P0.2
DB3 EQU P0.3
DB4 EQU P0.4
DB5 EQU P0.5
DB6 EQU P0.6
DB7 EQU P0.7
EN EQU P1.5
RS EQU P1.7
RW EQU P1.6
LCDDATA EQU P0
From the pinouts, it appears that your LCD uses the HD44780 interface,
found on just about all inexpensive parallel LCD displays these days.
I don't use anything from the 8051 family, but I've driven '44780 LCDs
with several other MCU's using the following method.
First, I use the "4-bit" interface. I connect MCU output lines to
DB4-DB7, EN, and RS. I ground the LCD's R/W input, and leave DB0-DB3
open.
The EN line is your clock line. It idles low, is raised for a
millisecond or so to clock data on the DB lines, then is returned low.
The RS line is your command/data line. Set it high to indicate that
the info you're clocking on the DB lines is data, or set it low to
indicate that the DB info represents a command.
My output routine takes a byte as its input, splits it into two
nibbles, then clocks those two nibbles to the DB lines, high nibble
first, MSbit on DB7. (Make sure that the calling routine sets the RS
line to the correct state before sending the byte.)
-place high nibble on DB lines
-EN high
-pause 1 millisecond
-EN low
-pause 1 mS
-place low nibble on DB lines
-EN high
-pause 1 mS
-EN low
-pause 1 mS
In your program, wait about 1 second after powerup before you try to
initialize the LCD (or, for that matter, anything else.) Then send
the following sequence:
This is the initialization sequence that puts the LCD into the 4-bit
mode:
1. $33
2. $32
folowed by three other bytes that put the LCD into 2-line display
mode, no display shift, cursor off, and 5x7 font:
3. $28
4. $0c
5. $06
While sending these five initialization bytes, I pause 15 milliseconds
between each byte. After the display has been intialized, I don't add
interbyte pauses for any other LCD traffic.
By the way - this stuff is simple! I think that the problem folks
have when driving an LCD is that they try to make it too complicated.
Keep your routine simple, and I'm sure all will go well.
Good luck!
Tom
==========================================
Here's some C code from my most recent project:
// ============= LCD Driver Routines =============//
void SendStr(const char* str, const byte addr)
{
// Send string at addr, if addr <> 0,
// or cursor position if addr == 0
int i = 0;
if (addr != 0)
Lcmd(addr);
while (str
!= 0)
Ldat(str[i++]);
}
void Lcmd(byte Cmd)
{
// Sends a byte to LCD in command mode
PORTC &= B11101111; // RS low
Lout(Cmd);
}
void Ldat(byte Dat)
{
// Sends a byte to LCD in data mode
PORTC |= B00010000; // RS high
Lout(Dat);
}
void Lout(byte Dat)
{
// Sends Dat to LCD. Calling routine sets RS to Command (Low) or
// Data (High) mode
clock2LCD(Dat >> 4); // Place high nibble on low bits
clock2LCD(Dat & B00001111); // Send low nibble
}
void clock2LCD(byte nibble)
{
// Clock low 4 bits of nibble to LCD
PORTC &= B11110000;
PORTC |= nibble;
PORTB |= B00000100; // Strobe data using EN
delay(1);
PORTB &= B11111011;
delay(1);
}
==========================================