HD44780, HD44780A (LCD-II)

(Dot Matrix Liquid Crystal Display Controller & Driver)

Description
Pin Description
Instruction
Contrast connection
VHDL example


Description

The LCD-II (HD44780, HD44780A) dot matrix liquid crystal display controller & driver LSI displays alphanumerics, kana characters, and symbols. It dirves a dot matrix liquid crystal display under 4-bit or 8-bit microcomputer or microprocessor control. All the functions required for dot matrix liquid crystal display drive ate internally provided on one chip. The user can complete dot matrix liquid crystal display systems with low chip count by using the LCD-II (HD44780, HD44780A).
 
 
HD44780, HD44780A
 

Pin Description

 
Pin No.
Signal Name Input/Output Function
1
VSS Input Gound
2
VDD Input +5V
3
VEE Input Contrast Adjust
4
RS Input Signal to select registers 
'0' : instruction register (for write) 
        Busy flag : address counter 
        (for read) 
'1' : Data register (for read and write)
5
R/W Input Signal to select read (R) and write (W) 
'0' : Write 
'1' : Read
6
Enable Input Operstion start signal for data read/write
7-14
DB0-DB7 Input/Output 8 bit bidirectional three-state data bus lines. 
Used for data transfer between FPGA and LCD
 

Function of each Block

Register

The HD44780 has two 8-bit registers, an instruction register (IR), and a data register(DR).
The IR stores instruction codes such as display clear and cursor shift, and address information for display data RAM (DD RAM) and character generator RAM (CG RAM).
The DR temporarily stores data to be written into the DD RAM or the CG RAM and the data to be read out from DD RAM or CG RAM. Data written into the DR from the FPGA is automatically written into the DD RAM or the CG RAM by internal operation. The DR is also used for data storage when reading data is read from the DD RAM or the CG RAM.
 

Busy flag (BF)

When the busy flag is 1, the HD44780 is in the internal operation mode, and the next instruction will not be accepted. The busy flag is output to DB7 when RS = 0 and R/W = 1. The next instruction must be written after ensuring that the busy flag is 0.
 

Address Counter (AC)

The address counter (AC) assigns addresses to DD and CG RAMs. When an instruction for address is written in IR, the address information is sent from IR to AC. After writing into ( or reading from) DD or CG RAM display data, AC is automatically incremented by 1 of decremented by 1. AC contents are output to DB0-DB6 when RS = 0 and R/W = 1.
 

Display data RAM (DD RAM)

The display data RAM (DD RAM) stores display data represented in 8-bit character codes. Its capacity is 80*8 bits, or 80 characters. The DD RAM address (Add) is set in the address counter (AC) and is represented in hexadecimal.
 

Character Generator RAM (CG RAM)

In the character generator RAM, the user can rewrite character patterns by program. With 5*7 dots, 8 character patterns can be written and with 5*10 dots, 4 characters can be written.
 

Register Selection
RS
R/W
Operation
0
0
IR write as internal operation (Display clear, etc.)
0
1
Read busy flag (DB7) and address counter (DB0-DB6)
1
0
DR write as internal operation (DR to DD or CG RAM)
1
1
DR read as internal operation (DD or CG RAM to DR)
 


Connection for LCD Contrast

The connection for LCD contrast is very easy. Just use a 10K pot and connect as follow:


Instructions

 
Instruction RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description Execution 
Time (Max)
Clear 
Display
0
0
0
0
0
0
0
0
0
1
Clear entrie display and sets DD RAM address 0 in address counter. 1.64 ms
Return 
Home
0
0
0
0
0
0
0
0
1
X
Sets DD RAM address 0 in address counter. Also returns display being shifted to original position. DD RAM contents remain unchanged. 1.64 ms
Entry 
Mode Set
0
0
0
0
0
0
0
1
I/D
S
Sets cursor move direction and specifies shift of display. These operations are performed during data write and read. 40 us
Display 
On/Off 
Control
0
0
0
0
0
0
1
D
C
B
Sets ON/OFF of entire display (D),  cursor ON/OFF (C), and blink of cursor position character (B). 40 us
Cursor or 
Display 
Shift
0
0
0
0
0
1
S/C
R/L
X
X
Moves cursor and shifts display without changing DD RAM contents 40 us
Function 
Set
0
0
0
0
1
DL
N
F
X
X
Sets interface data length (DL), number of display lines (L) and character font (F). 40 us
Set CG RAM 
Address
0
0
0
1
ACG
Sets CG RAM address. CG RAM data is sent and recevied after this setting. 40 us
Set DD RAM 
Address
0
0
1
ADD
Sets DD RAM address. DD RAM data is sent and recevied after this setting 40 us
Read Busy 
Flag & Address
0
1
BF
AC
Reads Busy flag (BF) indicating internal operation is being performed and reads address counter contents. 0 us
Write Data to 
CG or 
DD RAM
1
0
Write Data
Writes data into DD RAM or CG RAM 40 us
Read Data 
from CG or 
DD RAM
1
1
Read Data
Reads data from DD RAM or CG RAM 40 us
I/D = 1 : Increment 
I/D = 0 : Decrement 
S    = 1 : Accompanies display shift 
S/C = 1 : Display shift 
S/C = 0 : Cursor move 
R/L = 1 : Shift to the right 
R/L = 0 : Shift to the left 
DL = 1 : 8 bits, DL = 0 : 4 bits 
N    = 1 : 2 lines, N = 0 : 1 lines 
F     = 1 : 5*10 dots, F = 0 : 5*7 dots 
BF = 1 : Internally operating 
BF = 0 : Can accept instruction 
X : Don't Care
DD RAM : Display data RAM 
CG RAM : Character generator RAM 
ACG : CG RAM address 
ADD : DD RAM address : Corresponds to cursor address 
AC : Address counter used for both DD and CG RAM address
 

VHDL example for LCD display Initialization


Notes:

   

--lcd_init.vhd This program initialize the LCD display

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity lcd_init is

     generic(width : positive := 8);
     port(reset, clock, enable, done_ack : in std_logic;
              done, RW, rs, lcd_e : out std_logic;
              Qout : buffer std_logic_vector(width-1 downto 0)
             );

end lcd_init;

architecture initial of lcd_init is

    type state_type is (waiting, i0, i1, i2, i3, donestate);
    signal state, next_state : state_type;
    signal count,count_temp : std_logic_vector(1 downto 0);
    signal Qout_temp : std_logic_vector(width-1 downto 0);

begin

running : process(state,enable,done_ack,count) is

begin

case state is

when waiting =>
     done <= '0';
     lcd_e <= '1';
     RW <= '0';
     rs <= '0';
     Qout_temp <= "00000000";

     if enable = '1' then
          next_state <= i0;
     else
          next_state <= waiting;
     end if;

when i0 =>
     Qout_temp <= "00000001"; --clear display

     if count = "11" then
          next_state <= i1;
     else
          next_state <= i0;
     end if;

when i1 =>
     Qout_temp <= "00000010"; --clear display & returns cursor to HOME (top left)
 
     if count = "11" then
          next_state <= i2;
     else
          next_state <= i1;
     end if;

when i2 =>
     Qout_temp <= "00111000"; --2 line display
 
     if count = "11" then
          next_state <= i3;
     else
          next_state <= i2;
     end if;
 

when i3 =>
     Qout_temp <= "00001110"; --truns on display with cursor at home position
 
     if count = "11" then
          next_state <= donestate;
     else
          next_state <= i3;
     end if;

when donestate =>
     done <= '1';
     Qout_temp <= ( others => '0' );

     if done_ack = '1' then
          next_state <= waiting;
     else
          next_state <= donestate;
     end if;

end case;

end process running;

timing : process(clock,reset) is

begin

    if rising_edge(clock) then
         Qout <= Qout_temp;
         count <= count_temp;
             if reset = '1' then
                  state <= waiting;
                  count_temp <= "00";
             else
                  state <= next_state;
                  count_temp <= count_temp + "01";
             end if;
    end if;

end process timing;

end initial;



 
Edward Wong ecw@ualberta.ca
Patrick Li pwli@ualberta.ca
Edgar Wong edgar@ualberta.ca
Howard Shum kshum@ualberta.ca

Last update: October 27, 1998