There are many display devices used by the hobbyists. LCD displays are one of the most sophisticated display devices used by them. Once you learn how to interface it, it will be the easiest and very reliable output device used by you! More, for micro controller based project, not every time any debugger can be used. So LCD displays can be used to test the outputs. Obviously, for last possibility, you need to know how to use this stuff pretty well.
Note 1: We have sub divided this article for easy navigation as shown below:-
1. Pin Configuration 2. Block Diagram 3. Control and Display Commands 4. LCD Interfacing 5. LCD Initialization
Note 2: If you are interested in reading about working of LCD – we have an excellent article for you – Working of Liquid Crystal Displays (LCD)
Hitachi has set up a mile stone by its LCD controller IC. All the LCD displays use the same, or any one of the IC s based upon the architecture introduced by Hitachi.
Ok, one minute, all I’m talking about is the character LCD display and not Graphical LCD Display.
Most of the LCD Displays available in the market are 16X2 (That means, the LCD displays are capable of displaying 2 lines each having 16 Characters a), 20X4 LCD Displays (4 lines, 20 characters). It has 14 pins. It uses 8lines for parallel data plus 3 control signals, 2 connections to power, one more for contrast adjustment and two connections for LED back light. Let us have a look to typical pin configurations:
Pin Configuration table for a 16X2 LCD character display:-
Pin Number |
Symbol |
Function |
1 |
Vss |
Ground Terminal |
2 |
Vcc |
Positive Supply |
3 |
Vdd |
Contrast adjustment |
4 |
RS |
Register Select; 0→Instruction Register, 1→Data Register |
5 |
R/W |
Read/write Signal; 1→Read, 0→ Write |
6 |
E |
Enable; Falling edge |
7 |
DB0 |
Bi-directional data bus, data transfer is performed once, thru DB0 to DB7, in the case of interface data length is 8-bits; and twice, through DB4 to DB7 in the case of interface data length is 4-bits. Upper four bits first then lower four bits. |
8 |
DB1 |
|
9 |
DB2 |
|
10 |
DB3 |
|
11 |
DB4 |
|
12 |
DB5 |
|
13 |
DB6 |
|
14 |
DB7 |
|
15 |
LED-(K) |
Back light LED cathode terminal |
16 |
LED+(A) |
Back Light LED anode terminal |
Data/Signals/Execution of LCD
Now that was all about the signals and the hardware. Let us come to data, signals and execution.
LCD accepts two types of signals, one is data, and another is control. These signals are recognized by the LCD module from status of the RS pin. Now data can be read also from the LCD display, by pulling the R/W pin high. As soon as the E pin is pulsed, LCD display reads data at the falling edge of the pulse and executes it, same for the case of transmission.
LCD display takes a time of 39-43µS to place a character or execute a command. Except for clearing display and to seek cursor to home position it takes 1.53ms to 1.64ms. Any attempt to send any data before this interval may lead to failure to read data or execution of the current data in some devices. Some devices compensate the speed by storing the incoming data to some temporary registers.
LCD displays have two RAMs, naming DDRAM and CGRAM. DDRAM registers in which position which character in the ASCII chart would be displayed. Each byte of DDRAM represents each unique position on the LCD display. The LCD controller reads the information from the DDRAM and displays it on the LCD screen. CGRAM allows user to define their custom characters. For that purpose, address space for first 16 ASCII characters are reserved for users. After CGRAM has been setup to display characters, user can easily display their custom characters on the LCD screen.
Images of LCD Display:-
Block Diagram of LCD Display:-
Control and display commands
Instruction |
Instruction Code |
Instruction Code Description | Execution time | |||||||||
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
|||
Read Data From RAM |
1 |
1 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Read data from internal RAM |
1.53-1.64ms |
Write data to RAM |
1 |
0 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Write data into internal RAM (DDRAM/CGRAM) |
1.53-1.64ms |
Busy flag & Address |
0 |
1 |
BF |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Busy flag (BF: 1→ LCD Busy) and contents of address counter in bits AC6-AC0. |
39 µs |
Set DDRAM Address |
0 |
0 |
1 |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Set DDRAM address in address counter. |
39 µs |
Set CGRAM Address |
0 |
0 |
0 |
1 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Set CGRAM Address in address counter. |
39 µs |
Function Set |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
X |
X |
Set interface data length (DL: 4bit/8bit), Numbers of display line (N: 1-line/2-line) display font type (F:0→ 5×8 dots, F:1→ 5×11 dots) |
39 µs |
Cursor or Display Shift |
0 |
0 |
0 |
0 |
0 |
1 |
S/C |
R/L |
X |
X |
Set cursor moving and display shift control bit, and the direction without changing DDRAM data |
39 µs |
Display & Cursor On/Off |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
C |
B |
Set Display(D),Cursor(C) and cursor blink(b) on/off control |
39 µs |
Entry Mode Set |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
SH |
Assign cursor moving direction and enable shift entire display. |
0µs |
Return Home |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
X |
Set DDRAM Address to “00H” from AC and return cursor to its original position if shifted. |
43µs |
Clear Display |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
Write “20H” to DDRAM and set DDRAM Address to “00H” from AC |
43µs |
AC -Address Counter
Outline
Now the instruction can be divided mainly in four kinds
1) Function set instructions
2) Address set instructions
3) Data transfer instructions with internal RAM
4) Others
Details of the Instructions
1) Read Data from RAM
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
1 |
1 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Read 8bit binary data from DDRAM/CGRAM
The selection of RAM is set by the previous address set instruction. If the address set instruction of RAM is not performed before this instruction, the data that is read first is invalid, because the direction of AC is not determined. If the RAM data is read several times without RAM address set instruction before read operation, the correct RAM data from the second, but the first data would be incorrect, as there is no time to transfer RAM data. In case of DDRAM read operation, cursor shift instruction plays the same role as DDRAM address set instruction; it also transfers RAM data to the output data registers.
After read operation, the data address counter is automatically increased or decreased by 1 according to the entry mode. After CGRAM read operation, display shift may not be executed properly.
*In case of RAM write operation, AC is increased or decreased by 1 like that of the read operation. In this time AC indicates the next address position, but the previous data can only by the read instruction.
2) Write data to ram
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
1 |
0 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Write binary 8bit data to DDRAM/CGRAM. The selection of CGRAM or DRAM is set by the previous address set instruction; DDRAM address set, CGRAM address set. RAM set instruction can also determine the AC direction to RAM.
After write operation, the address is automatically increased or decreased by 1 according to the entry mode.
3) Read Busy Flag and Address
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
1 |
BF |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
By making this read out operation, it can be determined if the LCD is performing some internal operation or not. If Busy Flag (BF) is high, some internal operation is going inside the LCD at that particular moment. To perform further operation the data source (e.g. micro controller) must wait for the BF to go low. Here, the address counter value can also be read.
4) Set DDRAM Address
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
1 |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Set DDRAM address to AC, this instruction makes DDRAM data available from MPU. In 1-line display mode, DDRAM address rangers from “00H” to “4FH”. In 2-line display mode, DDRAM address in the first line ranges from “00H” to “27H”, and DDRAM address in the 2nd line is from “40H” to “67H”.
5) Set CGRAM address
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
1 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Set CGRAM address to AC. This instruction makes CGRAM data available from MPU.
6) Function Set
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
X |
X |
DL: Interface data length control bit
DL=’1’ means 8bit mode of data transfer.
DL=’0’ means 4bit mode of data transfer
When 4 bit mode is activated, the data needs to be transferred in two parts, first higher 4bits, and then lower 4 bits.
N: display line number control bit
N=’1’ will allows to characters to display in 2-lines
N=’0’ will allows to characters to display in the first line only
F: display font control bit
F=’0’ will use 5×8 dots format display mode
F=’1’ will use 5×11 dots format display mode
7) Cursor or display Shift
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
0 |
1 |
S/C |
R/L |
X |
X |
Without writing or reading the display data, shifting right/left cursor position or display.
This instruction is made to correct or search or display data. During 2-line display mode, cursor moves to the 2nd line after the 40th digit of the 1st line.
When displayed data is shifted repeatedly, each line shifts individually.
When display shift is performed, the contents of the address counter are not changed.
8) Display On/Off Control
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
C |
B |
This instruction controls Display, Cursor and cursor blink.
D: Display On/Off control bit
D=’1’ means entire display is turned on
D=’0’ means entire display is turned off. But Display data remains in DDRAM.
C: cursor On/Off control bit
C=’1’ turns on the cursor
C=’0’ turns off the cursor. But I/D register retains the data
B: Cursor blink On/Off control bit
B=’1’ makes cursor blink periodically.
B=’0’ stops the cursor to blink and cursor looks steady if the Cursor is turned on.
9) Entry Mode Set
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
SH |
This instruction sets the moving direction of cursor and display.
When I/D= ’1’ cursor moves to the right and DDRAM address is increased by 1.
When I/D= ’0’ cursor moves to the left and DDRAM address is decreased by 1.
CGRAM operates in the same way in this setting.
10) Return Home
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
X |
This instruction sets the address counter to ‘00H’, and returns the cursor to the first column of first line. And if display is shifted previously, this instruction shifts this too. The DDRAM contents don’t change in this instruction.
11) Clear display
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
Clear all the display data by writing “20H” (ASCII code of ‘space’ character) to all DDRAM address, AND set value DDRAM address counter (AC) to “00H”. It returns the cursor to the first column of first line and sets the entry mode to increment mode (I/D=’1’).
8-bit and 4-bit interfacing of LCD
Now the question is how to display data in the LCD or give command to it. There is two modes of data transfer are supported by LCD displays. One is 4bit mode, another is 8 bit mode. To transfer data In 8 bit mode, first put your data in the 8bit bus, then put command in the command bus and then pulse the enable signal.
To send data in 4bit mode; first put upper 4bit in the 4 bit data bus connected to 4MSB pins of LCD display, then put control signals in the control bus, then pulse the E pin once. Next put the lower 4 bit in the data bus and pulse the E pin again. Here is a flowchart simply describing it.
LCD Display Interfacing – Flowchart:-
LCD Initialisation
We are pretty familiar how to send data. But before displaying characters on the LCD display, it must be configured first. To configure an LCD display, four command words must be sent to LCD in either 4 bit mode, or in 8 bit mode. The commands are:
1. Function set
2. Display On/Off control
3. Entry mode set
4. Display Clear
Here is a flow chart of the initialization sequence of LCD display.
Displaying Custom Characters
All these character display modules got the feature to create 8 user defined characters (ASCII Codes 0…7) in addition to the ROM fixed codes.
1.) The command “CG RAM Address Set” defines the ASCII code (Bit 3, 4, 5) and the dot line (Bit 0, 1, 2) of the new character. Example demonstrates creating ASCII code “00H”.
2.) Doing 8 times the write command “Data Write” defines line by line the new character. 8th byte stands for the cursor line.
3.) The new defined character can be used as a “normal” ASCII code (0…7); use with “DD RAM Address Set” and “Data Write”.
Now let us look up the character set that can be displayed using the LCD Displayed
0x00 | 0x10 | 0x20 | 0x30 | 0x40 | 0x50 | 0x60 | 0x70 | 0x80 to 0xd0 | 0xE0 | 0xF0 | |
0x00 |
CG1 |
0 |
@ |
P |
` |
p |
CUSTOM REGIONAL CHARACHTERS |
Α |
|||
0x01 |
CG2 |
! |
1 |
A |
Q |
a |
q |
Ä |
|||
0x02 |
CG3 |
“ |
2 |
B |
R |
b |
r |
Β |
θ |
||
0x03 |
CG4 |
# |
3 |
C |
S |
c |
s |
Ε |
|||
0x04 |
CG5 |
$ |
4 |
D |
T |
d |
t |
Μ |
Ω |
||
0x05 |
CG6 |
% |
5 |
E |
U |
e |
u |
Σ |
ϋ |
||
0x06 |
CG7 |
& |
6 |
F |
V |
f |
v |
Ρ |
Σ |
||
0x07 |
CG8 |
7 |
G |
W |
g |
w |
G |
π |
|||
0x08 |
CG1 |
( |
8 |
H |
X |
h |
x |
√ |
|||
0x09 |
CG2 |
) |
9 |
I |
Y |
i |
y |
¯¹ |
y |
||
0x0A |
CG3 |
* |
: |
J |
Z |
j |
z |
J |
|||
0x0B |
CG4 |
+ |
; |
K |
[ |
k |
{ |
||||
0x0C |
CG5 |
, |
< |
L |
¥ |
l |
| |
||||
0x0D |
CG6 |
– |
= |
M |
] |
m |
} |
||||
0x0E |
CG7 |
. |
> |
N |
^ |
n |
→ |
||||
0x0F |
CG8 |
/ |
? |
O |
_ |
o |
← |
█ |
CG→ CGRAM User Defined Character
Custom Regional characters vary from manufacturer to manufacturer. The Greek letters may or may not appear. It too depends upon the design.
15 Comments
Hi,
Thank you for your tutorial. I have a question regarding the 2 bit command, which follows the 8-bit character is into the bus. What is this command?
Thank you,
Erin
@ Erin – Could you please elaborate ?
hey,
can anyone tell me how to read a data from LCD display panel and fetch to microcontroller?
Thank you very much for the tutorial.. Helped a lot for programming the 2-line alpha numeric display..
I need code for PWM with variable duty cycle from 0 to 100% with in 10 second.
Please help me with your valuable guidance.
Manish, use 16bit timer for this. This would be easiest way to do so.
sir pls tell me how to print a heart symbol on the l.c.d screen..
I need a sample code for the special character like the downwards arrow. Would you be enough kind to provide me with that or explain me how to do? I do change LCD_command and LCD_data to make such pattern but it does not work out for me! 🙁
Henner. Sorry for replying you late. Thanks for spotting out the errors. I’ll remove them in the next edit. Yes, the read/write don’t take time in the order of mili seconds but in the order of micro seconds.
Hi,
Me again; another typo in the table: the Entry Mode Set operation is shown as taking 0 usec, while the busy flag is shown to take 37 usec.
That is reverse: the busy flag takes 0 usec, while the Entry Mode Set takes the regular 37usec.
-h
Thanks for this overview!
I think I’ve found a little error in the table. Comparing data sheets (Looking directly at the Hitachi HD44780), looks like the last column is messed up. Read and write data from RAM is actually ~43usec (instead of ~1.5ms), while the Clear Screen and Home operation is 1.5ms.
I presume this happened because commonly the Clear/Home operation is shown first and the Read/Write operation last in these tables … and while swapping the rows around, that column didn’t make it.
Anyway, thanks for this resource.
NICE WORK THERE IS ONLY ONE WEBSITE WHICH PROVIDES QUALITY AND INFORMATIVE ARTICLES .DO YOU KNOW WHICH IS ? .IT IS OFCOURSE CIRCUITSTODAY
Hi everyone,
You can ask me questions over the FaceBook too. I can answer there also.
I like your most valuable information regarding LCD character display . Thank
It will be more valuable if it provides how to access each pixel (address lines) in LCD Display