Digital Logic Design
LCD example
Version 4.0 / september 2009
Juan Antonio Chvez
Joan Pons
Mercedes Garca
Jordi Llorens
Mauricio Salinas
The LCD display
1.1 General considerations
The DE2 board includes a two-line, 16-character LCD display with a standard controller
module. Its internal block distribution is shown in Figure 1.
16*2
Figure 1. LCD block distribution.
As can be seen in Figure 1, control and interface functions are both provided by a KS0066compatible controller, which interprets the incoming commands from the bus and executes
the requested action(s): show the corresponding characters on the display, run configuration
or read commands, etc.
Let us notice that the Information about the timing, instruction set or programming cycles for
this controller is complex and not suitable to be included in a reduced (and far from
complete) manner in this document. Up to this point, a careful and detailed reading of this
information in the original manufacturers datasheet is compulsory.
Here we only list the interface pins/signals of the circuit and, later in section 1.2, we provide
an example of utilization of this device.
The I/O pins and control signals for this circuit are:
pin
symbol
DE2
signal
VSS
Ground (0V)
VDD
Supply Voltage for Logic (+5 V or +3.3 V)
description
Page - 2
VO
Contrast Adjustment
RD
LRS
R/W
LWRN
Data/Instruction Selection
LEN
DB0
Data Bus
DB1
Data Bus
DB2
Data Bus
10
DB3
Read/Write Selection
Enable
Data Bus
DB[7..0]
11
DB4
12
DB5
Data Bus
Data Bus
13
14
DB6
DB7
Data Bus
Data Bus / BUSY FLAG
15
A_LED
LED Power Supply + (5 V)
16
K_LED
LED Power Supply - (5 V)
17
ON
LCD_ON
Power Supply Enable
IMPORTANT: After writing a character, we must periodically read the data bus bit 7 (DB7), to
check if the operation has already finished; because of that it is called BUSY FLAG.
1.2 Example of utilization
In order to help understanding the LCD controller programming and operation, this section
shows an example of how this can be done. The circuit proposed shows the # character
when pushing a key pushbutton of the DE2 board.
KEY[1]
DB[7..0]
lcd_machine
Clock_div
nrst
LCD_ON
lcdctrl
clk
nrst
LEN
LRS
LWRN
[Link]
OSC_50
KEY[0]
Figure 2. Schematic of the example.
Figure 2 shows that the circuit is composed of two modules:
A frequency divider, called clock_div. Since we are using the 50 MHz clock of the
DE2 board, this module is needed in order to fulfil the timing requirements of the
display: clk should have a frequency of 10 MHz or slower.
Page - 3
A synchronous Moore FSM, called lcd_machine, used either to initialize and
program the display and to check the keypad and show the character on the display.
The state diagram of this module is described in Figure 3.
000
ZZZZZZZZ
101
delay
ZZZZZZZZ
key
001
set1
001111xx
function set
000
mode2
00000110
001
mode1
00000110
001
onoff1
00001111
000
clear2
00000001
000
onoff2
00001111
key
101
charw1
00100011
entry mode set
000
set2
001111xx
on / off control
waitkey
clear display
100
charw2
00100011
010
db(7)
ZZZZZZZZ
db(7)
001
clear1
00000001
db(7)
011
db(7)
readbf1
ZZZZZZZZ
readbf2
key detection, write on
display & busy flag check
Figure 3. State diagram of lcd_machine. Outputs shown on each node/state are rs, rnw, en (upper
box), and data[7..0] (lower box).
Figure 4 shows the VHDL code of the module [Link]. Remember that you must add
the frequency divider for proper work and visualisation.
--DE2 Board LCD display control example
--Character '#' is displayed when pushing a key button
library ieee;
library work;
use ieee.std_logic_1164.all;
entity example is
port (clk, nrst, key
DB
LCD_ON, LEN, LWRN, LRS
end example;
: in std_logic;
: inout std_logic_vector(7 downto 0);
: out std_logic);
architecture arc_example of example is
type machine is (delay, set1, set2, onoff1, onoff2, clear1, clear2, mode1,
mode2, waitkey, charw1, charw2, readbf1, readbf2);
signal lcd_mach : machine;
signal lcdctrl : std_logic_vector(2 downto 0);
begin
-- arc_example
LCD_ON <=
'1';
lcdmachine : process (clk, nrst)
begin
if nrst = '0' then lcd_mach <= delay;
Page - 4
-- state machine definition
-- process lcdmachine
elsif clk'event and clk = '1' then
case lcd_mach is
when delay
=> lcd_mach <= set1;
when set1
=> lcd_mach <= set2;
when set2
=> lcd_mach <= onoff1;
when onoff1
=> lcd_mach <= onoff2;
when onoff2
=> lcd_mach <= clear1;
when clear1
=> lcd_mach <= clear2;
when clear2
=> lcd_mach <= mode1;
when mode1
=> lcd_mach <= mode2;
when mode2
=> lcd_mach <= waitkey;
when waitkey
=> if key = '0' then lcd_mach <= charw1; end if;
when charw1
=> lcd_mach <= charw2;
when charw2
=> lcd_mach <= readbf1;
when readbf1
=> if DB(7) = '1' then lcd_mach <= readbf2;
else lcd_mach <= mode1; end if;
when readbf2
=> if DB(7) = '1' then lcd_mach <= readbf1;
else lcd_mach <= mode1; end if;
end case;
end if;
end process lcdmachine;
with lcd_mach select
lcdctrl <= "001" when
"000" when
"101" when
"100" when
"010" when
"011" when
"000" when
--LCD control signals
set1|onoff1|clear1|mode1,
set2|onoff2|clear2|mode2,
waitkey|charw1,
charw2,
readbf1,
readbf2,
others;
LRS <= lcdctrl(2);
LWRN <= lcdctrl(1);
LEN <= lcdctrl(0);
with lcd_mach select
DB <=
"001111XX"
"00001111"
"00000001"
"00000110"
"00100011"
"ZZZZZZZZ"
end arc_example;
when
when
when
when
when
when
set1|set2,
onoff1|onoff2,
clear1|clear2,
mode1|mode2,
charw1|charw2,
others;
Figure 4. Printout of [Link].
Page - 5