Many parallel character LCD displays use Hitachi HD44780 controller or chip with compatible interface. HD44780 is some kind of standard but I recommend to verify interface details in datasheet provided by vendor. There may be differences in commands and/or timing. Timing is important as Hitachi HD44780 needs time to process commands. If possible then check BUSY flag. If it is not possible then make sure your timing is correct.
This document is only my reference. You can find more details in Hitachi datasheet. Additionally you can find a lot of useful information on Dincer Aydin web page. There is section dedicated to LCD and web simulator: djlcdsim.
Internal RAM structure
Display data RAM (DDRAM) stores characters in 8-bit format. Capacity is 80 characters (bytes). Off screen display data is accessed when display is shifted or can be used as general data storage.
1x8 LCD example
Data organisation:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
... |
79 |
80
|
DDRAM (hex) |
00 |
01 |
02 |
03 |
04 |
05 |
06 |
07 |
.. |
4E |
4F
|
Display shift:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8
|
at reset (hex) |
00 |
01 |
02 |
03 |
04 |
05 |
06 |
07
|
shift left (hex) |
01 |
02 |
03 |
04 |
05 |
06 |
07 |
08
|
shift right (hex) |
4F |
00 |
01 |
02 |
03 |
04 |
05 |
06
|
2x8 LCD example
Data organisation:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
... |
39 |
40
|
Line 1 DDRAM (hex) |
00 |
01 |
02 |
03 |
04 |
05 |
06 |
07 |
.. |
26 |
27
|
Line 2 DDRAM (hex) |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
.. |
66 |
67
|
Display at reset:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8
|
Line 1 DDRAM (hex) |
00 |
01 |
02 |
03 |
04 |
05 |
06 |
07
|
Line 2 DDRAM (hex) |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47
|
Display after left shift:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8
|
Line 1 DDRAM (hex) |
01 |
02 |
03 |
04 |
05 |
06 |
07 |
08
|
Line 2 DDRAM (hex) |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48
|
Display after right shift:
Display position |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8
|
Line 1 DDRAM (hex) |
27 |
00 |
01 |
02 |
03 |
04 |
05 |
06
|
Line 2 DDRAM (hex) |
67 |
40 |
41 |
42 |
43 |
44 |
45 |
46
|
Command Set
Clear Display
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
|
~ 1.52 ms
|
- Clear display data by writing 0x20 ("space") to whole DDRAM memory
- Set AC to DDRAM and 0x00
- Set entry mode to increment (I/D = 1)
Return Home
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
0 |
0 |
0 |
0 |
1 |
x |
|
~ 1.52 ms
|
- Set AC to DDRAM and 0x00
- Return cursor and display (if shifted) to home (original) postition
- Contend of DDRAM is preserved
Entry Mode Set
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
SH |
|
~ 38 us
|
- Set the moving diresction of cursor and display
- I/D = Increment / Decrement DDRAM address
- I/D = 1, cursor moves to right and DDRAM is increased by 1
- I/D = 0, cursor moves to left and DRAM is decreased by 1
- * CGRAM operate in same way when reading from or writing to CGRAM.
- SH = Shift (scroll) of entire display
- SH = 1, after DDRAM write operation entire display is shifted (scrolled) according to I/D value
- SH = 0, no shifting (scrolling) is performed
Display ON / OFF Control
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
0 |
0 |
1 |
D |
C |
B |
|
~ 38 us
|
- D = Display On/Off
- D = 1, display is On
- D = 0, display is Off, content of DDRAM is preserved
- C = Cursor On/Off
- C = 1, cursor is enabled
- C = 0, cursor is disabled, but it's configuration is preserved (I/D, ...)
- B = Blink On/Off
- B = 1, blink is enabled, display will alternate between current data and 0xff character on cursor position
- B = 0, blink is disabled
Cursor or Display Shift
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
0 |
1 |
S/C |
R/L |
x |
x |
|
~ 38 us
|
This instruction shift display or cursor without writing or reading display data. Content of AC (address counter is preserved) when display shift is performed.
S/C |
R/L |
Operation
|
0 |
0 |
Shift cursor to left, AC is decreased by 1
|
0 |
1 |
Shift cursor to right, AC is increased by 1
|
1 |
0 |
Shift display to left, cursor moves according to display
|
1 |
1 |
Shift display to right, cursor moves according to display
|
Function set
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
0 |
1 |
DL |
N |
F |
x |
x |
|
~ 38 us
|
- DL = interface data lenght
- DL = 1, 8-bit bus mode
- DL = 0, 4-bit bus mode
- N = number of lines on display
- N = 1, 2-line display
- N = 0, 1-line display
- F = font type
- F = 1, 5x11 dots format
- F = 0, 5x7 dots format
Set CGRAM Address
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
0 |
1 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
|
~ 38 us
|
This instruction set CGRAM address to AC (addres counter).
Set DDRAM Address
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
0 |
|
1 |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
|
~ 38 ms
|
This instruction set DDRAM address to AC (address counter).
Read Busy Flag and Address
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
0 |
1 |
|
BF |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
|
~ 0 us
|
This instruction shows if internal operation is ongoing. This instruction also read content of AC (address counter).
- BF = busy flag
- BF = 1, internal operation is in progress
- BF = 0, display is ready to accept next instruction / command
Write data to RAM
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
1 |
0 |
|
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
|
~ 38 us
|
This instruction write 8-bit data to DDRAM or CGRAM. Position is selected by AC (address counter). AC is incremented / decremented according to entry mode after write.
Read data from RAM
RS |
R/W |
|
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|
Execution Time
|
1 |
1 |
|
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
|
~ 38 us
|
This instruction read 8-bit data from DDRAM or CGRAM. Position is selected by AC (address counter). AC is incremented / decremented according to entry mode after read.
Initialization of display
8-bit mode
4-bit mode