LCD FAQs





LCD FAQ                                             Version 0.00

0.0  LCD FAQ introduction
      Why this FAQ?
      Author
      General description of LCDs
      References
      Where to find this FAQ
      Definitions
1.0  Sources for modules
2.0  Specs
 2.1  Pin description
 2.2  Character set
 2.3  Instruction set
 2.4  Timing
 2.5  Memory map
  2.5.1  Custom characters
  2.5.2  Addressing display ram
 2.6  Initialization
  2.6.1  Initialize for 8-bit operation
  2.6.2  Initialize for 4-bit operation
3.0  Interfacing
 3.1  Manual test circuit
 3.2  Interfacing to CPU bus
 3.3  Interfacing to CPU port
 3.4  Interfacing to Parallax BASIC STAMP
 3.5  Serial Interface
4.0  Notice

0.0 LCD FAQ introduction

        I'm writing now what I wish I had about four months ago, when
I first started playing with LCD character display modules.  I still
haven't figured out the graphics units yet, so no info on those is
included.   This FAQ is geared towards hobbyists and experimenters. 
I think it'll help anyone who finds the datasheets somewhat terse.
        
        Any errors are all mine.  Please email suggestions, additions
or corrections to Chris Burian at cburian(aatt_sign)uiuc.edu

        LCDs are manufactured by quite a few different companies.  Units
typically seen in the surplus market come from Densitron, Epson, Hewlett 
Packard, Optrex, or Sharp.  Common configurations are 16, 20, 24, 32, or
40 characters by 1, 2, or 4 lines.   

        I've been loose with the term LCD here.  One can find LCDs at
any level of integration from what looks like a glass slide and will
need drivers and controller, to a module that includes the row and 
column drivers, to the modules I'm actually talking about which also
include the controller (usually a Hitachi HD44780).  I'd recommend
staying away from modules that do not say they have a controller or
otherwise indicate that it's included, such as by describing the 
character set or noting an ASCII interface.  The units to look for are
usually called character-type dot matrix LCD modules. 

        Most of the modules I've seen use the Hitachi controller, such
as the Densitron, Optrex, and Sharp models.  These all use the same 
interface, and have the same character set and memory map.  This FAQ
right now is only good for LCD's with Hitachi controllers.  Later,
this FAQ will hopefully include data on modules that use SMOS brand
controllers, like Seiko and Epson modules.

        References used to generate version 0.00:  OPTREX Dot Matrix
LCD Module datasheet, June '94 issue of Nuts & Volts magazine, Intel
Embedded Control Applications book-1988, Texas Instruments TTL Logic
Data Book-1988, The Miniboard 2.0 Technical Reference by Fred G. Martin,
Mobile Robots: Inspiration to Implementation by Joseph Jones and Anita 
Flynn.

        The current version will be available on the ftp site 
bode.ee.ualberta.ca, somewhere in /pub/cookbook, and will be occasionally
posted to comp.robotics and sci.electronics.

        Some definitions:

        LCD: liquid crystal display
        Supertwist: a design that improves contrast
        Backlit: uses lamp behind the display instead of reflected light
        Electroluminescent: a kind of lamp that gives off a cool glow,
          powered by hi-voltage AC, typically powered with a converter  
        LED: light emitting diode, the other popular backlight         
        Extended temperature: modules designed for (surprise) use in
          temperatures outside the standard range.  Standard range is 
          0 to 50 C, extended range is -20 to 70 C.  Extended range 
          units need -7VDC as well as +5VDC.  Standard range units need
          only +5VDC.
        Driver: LCD modules of all sorts have column and row, or x and y,
          drivers.  To control one of these modules directly from a CPU
          would take a great deal of time and software overhead, because
          each bit (dot) has to be written separately, usually 4 dots
          at a time.
        Controller: the chip, such as an HD44780 or SED1130, which 
          acts as an interface between your CPU and the row and column
          drivers.  It may have on-chip ram, or may need external ram.
          The controller takes care of generating characters, refreshing
          the display, and so on.  The modules discussed in this FAQ 
          have integral controllers.

1.0 sources for modules

These are the sourses I've seen that are most accessible to the hobbyist.
If you know of more, please email me.

All Electronics, 818-904-0524
B. G. Micro, 214-271-5546
Cronin Electronics, 617-449-5000
Digikey Corporation, 800-DIGIKEY
Herbach & Rademan, 215-788-5583
Hosfelt Electronics, 800-524-6464

...and hundreds more, no doubt.

My favorite references are the Optrex databook for dot matrix modules,
available from Digikey for $2, and the Amateur Robotics column in the
June '94 issue of Nuts & Volts magazine, 430 Princeland Court, Corona,
CA  91719.


2.0 specs

2.1 Pin description

These numbers are the same no matter the physical arrangement of the pins,
(for instance, a row along the top on Optrex units, or a 2x7 .100" center
array on the side of Sharp units).

Pin#  Symbol  Level  Function
 1     Vss     GND    Ground
 2     Vcc     +5V    Module power
 3     Vee    note1   Liquid crystal drive
 4     RS      H/L    Register select, H=data, L=instruction
 5     R/W     H/L    Read/Write, H=read (module->CPU), L=write (CPU->module)
 6     E       H/L    Enable   
 7     DB0    note2   Data bit 0  (least significant bit)
 8     DB1      "
 9     DB2      "
10     DB3      "
11     DB4      "
12     DB5      "
13     DB6      "
14     DB7      "

Backlight drive:  If the module has a back light, it will be driven by 
a pair of pads separate from the interface pads.  Check your datasheet
for power requirements.  Electroluminescent strips usually need 100VAC
from a DC-AC converter driven off the 5V power supply.

note1:  On standard modules Vee is between GND and 5V, on temperature
extended modules it is between GND and -7V.  The potentiometer is the
contrast adjustment.

Standard:

  +5V ------------*----------- Vcc
                  |
                  /
          10k to  \<---------- Vee
          20k pot /
                  \
                  |
  GND ------------*----------- Vss

Temperature extended model:

  +5V ------------------------ Vcc

  GND ------------*----------- Vss
                  |
                  /
          10k to  \<---------- Vee
          20k pot /
                  \
                  |
  -7V ------------'

Extended temperature types may also employ fancy temperature correction
circuitry to provide automatic contrast adjustment.

note2:  For an 8-bit interface, DB7-DB0 are driven by your CPU on a write
but must be switch to hi-Z (or pulled up with pullup resistors only) so the 
module can drive them on a read.  For a 4-bit interface, only DB7-DB4 are 
used.  The most significant nybble is written first (bit7-bit4), then the 
least significant nybble is written (bit3-bit0) on the next Enable cycle.  
DB3 to DB0 are left unconnected.  The DB, RS, and R/W pins have internal 
pullups, so open collector drivers may be used with them.

Power consumption:  Modules use between 10 and 25mW (2 to 5 mA), not counting
the backlight, roughly proportional to number of rows and columns.  

Be careful when hooking power to the module.  Reversing +5V and GND will
destroy the unit.  (Personal experience, eh.)  Carefully examine your
datasheet to correctly identify Pin 1.

2.2 Character set
        
None of the standard ASCII control codes [chr(1)-chr(31), chr(127)] are
implemented.  

Standard ASCII is used for chr(32)  through chr(125) '}'
  <00100000b, 01111101b>        

The lower case characters do not have decenders.  This is because some
LCD's (those with 5x7 dots or 5x8 dots) would chop off the bottom.  Lower
case characters with decenders appear near the top of the character table.
You can access them readily by adding 128 <10000000b> if you want decenders
and have a 5x11 dot unit that will properly display them.

Eight user-defined characters are displayed by chr(0) through
chr(7), and redundantly with chr(8) through chr(15).  
  <00000000b, 00000111b, 00001000b, 00001111b>

chr(16) to chr(31) are undefined.
  <00010000b, 00011111b>

chr(126) is a right arrow ->   <01111110b>
chr(127) is a left arrow  <-   <01111111b>

chr(128) through chr(159) are undefined.
  <10000000b, 10011111b>

chr(160) through chr(223) are katakana (Japanese) characters. 
  <10100000b, 11011111b> 

You might find chr(223) useful, it looks like the degree symbol (it's a
3x3 box in the upper lefthand corner), and chr(165) <10100101b>, a dot 
in the center of the character.

chr(224) through chr(255) are Greek and other symbols.
  <11100000b, 11111111b>

11100000b  LC alpha
11100001b  LC 'a' with two dots over it 
11100010b  LC beta 
11100011b  LC epsilon
11100100b  LC mu
11100101b  LC sigma
11100110b  LC rho
11100111b  decending LC 'g' 
11101000b  radical (square root sign)
11101001b  katakana character
11101010b  decending LC 'j'
11101011b  tiny 3 by 3 'x' in upper left corner
11101100b  cent sign 
11101101b  UC 'L' with two horizontal bars (pounds Sterling?)
11101110b  LC 'n' with a bar over it
11101111b  LC 'o' with two dots over it
11110000b  LC 'p' with decender
11110001b  LC 'q' with decender
11110010b  LC theta
11110011b  infinity symbol 
11110100b  LC omega
11110101b  LC 'u' with two dots over it
11110110b  UC sigma
11110111b  LC pi
11111000b  LC 'x' with a bar over it
11111001b  decending LC 'y' 
11111010b  katakana character
11111011b   "        "
11111100b   "        "
11111101b  division symbol (dash with a dot above and below it)
11111110b  blank
11111111b  solid black cursor


2.3 Instruction Set

Binary data from bit7 to bit 0.  If using a 4-bit interface, bit7-bit4
of data are sent first, then bit3-bit0, on sucessive enable cycles.  

The following instructions are sent with RS (register select) and
R/W (read/write) both low.

Clear display  00000001
  clears display and returns cursor to home position (address 0)

Home cursor    0000001x  
  returns cursor to home position, returns a shifted display to original
  position.  Display data ram is unaffected.  x=don't care

Entry mode     000001ab
  sets cursor move direction and specifies whether or not to shift display
  a=1: increment, a=0: decrement, b=1: with display shift.  decrement is
  for languages that write from right to left.

On/off control 00001abc
  turn display on or off, turn cursor on or off, blink character at cursor
  on or off
  a=1: display on, b=1: cursor on, c=1: blink character at cursor position

Cursor/shift   0001abxx
  move cursor without changing display data ram, shift display without
  changing display data ram
  a=1: shift display, a=0: move cursor, b=1: to the right, b=0: to the left
  x= don't care

Function set   001abcxx
  set interface data length, mode, font
  a=1: 8-bit, a=0: 4-bit, b=1: 1/16 duty, b=0: 1/8 or 1/11 duty,
  c=1: 5x10 dots, c=0: 5x7 dots

Character ram  01aaaaaa    aaaaaa=lower 6 bits of ram address to point to,
address set                  i.e. to read or write custom characters.  MSB's
                             are always 01, so character generator ram 
                             resides from 64 (40h) to 127 (7Fh).  

Display ram    1aaaaaaa    aaaaaaa=7 lower bits of ram address to point to, 
address set                  i.e. reposition cursor.  MSB is always 1, so
                             display ram is from 128 (80h) to 255 (FFh).  

Data write operation:

 RS=1, R/W=0, data on bit7 to bit0
 
 data is written to current cursor position and cursor is incremented

Data read operation:
 
 RS=1, R/W=1, bit7 to bit0 hi-z (inputs to CPU)

 data is read from current cursor position

Read the Busy Flag:

 RS=0, R/W=1, bit7 to bit0 hi-z (inputs to CPU), bit7=1: busy, 
  bit7=0: OK to send, bit6-bit0 returns current address counter.


2.4 Timing

Execution times:  Clear display and home cursor 1.64ms, all others 40us,
 except read busy flag which is complete in a single enable cycle (or
 two cycles, in 4-bit mode).  These execution times mean that after an
 operation, the CPU must do Busy Flag checks until the BF (bit 7) is 0, 
 or else wait more than the execution time before the next operation when 
 the connection to the module from the CPU is write-only.  

Enable cycle time (TcycE)               1000ns min
  Operation cycle time cannot be less than 1 microsecond 

Enable pulse width, high (PWEH)          450ns min
  Enable pulse must be at least 450 nanoseconds long, no maximum length

Enable rise and decay time                25ns max
  Enable line must change state (L->H or H->L) in less than 25ns

Address setup time (tAS)                 140ns min
  Register Select and R/W lines must be valid 140ns before
  enable pulse arrives

Address hold time (tAH)                   10ns min
  RS and R/W must be valid at least 10 ns after enable goes low

Data delay time (tDDR)                   320ns max
  When doing a read, the return data will be valid within 320ns of enable
  going high

Data hold time, read (tDHR)               20ns min
  When doing a read, the return data will be valid at least 20ns after
  enable goes low

Data setup time (tDSW)                   195ns min
  When doing a write, data on lines bit7-bit0 (or bit7-bit4 in 4-bit mode)
  must be valid at least 195 ns before enable goes low

Data hold time, write (tH)                10ns min
  When doing a write, data on lines must be valid for at least 10ns after
  enable goes low


Generally, there are no max time requirements on the user except Enable
rise time.  An LCD module can be driven with just toggle switches for 
data, RS, and R/W, and a debounced pushbutton on the enable line.  


WRITE:
    ______ _____________________________ ___________
RS  ______X_________valid_RS_level______X__________
          |                             |
          |                             |
          |<--tAS-->|        tAH-->|    |<-- 
    ______|         |              |    |____________
R/W ______\_________|___R/W_low____|____/_____________
                    |              |
                    |<----PWEH---->| 
                    |              |
                    |<-------------|-------TcycE----->|     
                    |______________|                  |_________
E   ________________/              \__________________/
                                   |     
                        |<--tDSW-->|     
                        |       -->|    |<--tH
    ____________________|_______________|________________
dat ____________________X__valid_data___X____________


READ:    
    ______ _____________________________ ___________
RS  ______X_________valid_RS_level______X__________
          |                             |
          |                             |
          |<--tAS-->|        tAH-->|    |<-- 
    ______|_________|__   _    ____|____|____________
R/W ______/         |  R/W high    |    \_____________
                    |              |
                    |<----PWEH---->| 
                    |              |
                    |<-------------|-------TcycE----->|     
                    |______________|                  |_________
E   ________________/              \__________________/
                    |              |     
             tDDr-->|   |<--       |     
                        |       -->|    |<--tDHR
    ____________________|_______________|________________
dat ____________________X__valid_data___X____________


2.5 Memory map

2.5.1 Custom characters:
I haven't figured out yet how to write custom characters.  Please help!
Character generator ram appears to reside at 40h to 7Fh in memory.  
There is room for 8 characters of 8 rows each.

2.5.2 Addressing display ram:

16x1 module is arranged as two 8-character lines side by side.
"Line 1" addresses are 80h to 87h
"Line 2" addresses are C0h to C7h
So, as you write characters to the module, the cursor will automatically
increment until you get to the 9th character--you have to move the cursor
to address C0h before writing the 9th character on the 1x16 module.

16x2 module is two lines by 16 chars
Line 1 addresses are 80h to 8Fh
Line 2 addresses are C0h to CFh

20x1 module
Line 1 addresses are 80h to 93h

20x2 module
Line 1 addresses are 80h to 93h
Line 2 addresses are C0h to D3h

20x4 module
Line 1 addresses are 80h to 93h
Line 2 addresses are C0h to D3h
Line 3 addresses are 94h to A7h
Line 4 addresses are D4h to E7h

40x2 module
Line 1 addresses are 80h to A7h
Line 2 addresses are C0h to E7h


2.6 Initialization

Modules with Hitachi controllers will properly self-initialize if Vcc
rises from 0 to 4.5v in a period between .1mS and 10mS.  I suppose
an RC circuit would be needed to keep powerup rise time as slow as .1ms, 
so the manual initialization will be required in most applications.  If
you do use auto initialization, it will come up in this mode:  8-bit 
interface, 1/8 duty cycle (1 line mode), 5x7 font, cursor increment right,
no shift.  On most displays, you want to switch to 1/16 duty cycle (2 line
mode) because for all but the 20x1, there are two logical lines as the
controller sees it.  If you have an 8x11 dot matrix module, you'll want
to switch to the 5x10 font as well (the 11th line is the cursor).

2.6.1 Initialization for 8-bit operation:

POWER ON

Wait 15ms

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   1   1   x   x   x   x    x=don't care

Wait 4.1ms

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   1   1   x   x   x   x

Wait 100us

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   1   1   x   x   x   x

Wait 4.1ms

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   1   1   1   F   x   x    8-bit operation
                                         1/16 duty cycle
                                         F=font, 1 for 5x11 dot matrix
                                                 0 for 5x8 dot matrix

Wait 40us

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   0   0   1   0   0   0    Display off, cursor off, blink off

Wait 40us

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   0   0   0   0   0   1    Clear screen, cursor home

Wait 1.64ms

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0   0   0   0   0   0   0   1   1   0    Increment cursor to the right
                                         when writing, don't shift screen

Wait 40us

INITIALIZATION COMPLETE


2.6.2 Initialization for 4-bit operation:
First four instructions are nybbles, then the following are bytes, sent
on consecutive enable cycles (no delay necessary between nybbles), most
significant first, followed by least significant nybble.

POWER ON

Wait 15ms

RS R/W DB7 DB6 DB5 DB4
0   0   0   0   1   1 

Wait 4.1ms

RS R/W DB7 DB6 DB5 DB4
0   0   0   0   1   1 

Wait 100us

RS R/W DB7 DB6 DB5 DB4
0   0   0   0   1   1  

Wait 4.1ms

RS R/W DB7 DB6 DB5 DB4 
0   0   0   0   1   0   4-bit operation

Wait 40us

RS R/W DB7 DB6 DB5 DB4 
0   0   0   0   1   0
                        
0   0   1   F   x   x   4-bit operation
                        1/16 duty cycle
                        F=font, 1 for 5x11 dot matrix
                                0 for 5x8 dot matrix
                        x=don't care

Wait 40us

RS R/W DB7 DB6 DB5 DB4 
0   0   0   0   0   0   

0   0   1   0   0   0    Display off, cursor off, blink off

Wait 40us

RS R/W DB7 DB6 DB5 DB4
0   0   0   0   0   0   

0   0   0   0   0   1    Clear screen, cursor home

Wait 1.64ms

RS R/W DB7 DB6 DB5 DB4 
0   0   0   0   0   0   

0   0   0   1   1   0    Increment cursor to the right
                         when writing, don't shift screen

Wait 40us

INITIALIZATION COMPLETE


3.0 Interfacing

3.1 Manual test circuit                          
                                             __________
                                            |          |
                            GND---*---------| 1        |
                                  <         |          |
                             10K   ><--.    |          |
                                  <    |    |          |
                            +5V---*---------| 2        |
                                       |    |          |
                                        `---| 3        |
               RS                           |          |
        ,-----switch------------------------| 4        |                             
        |                                   |          |
        |      +5V-----.           GND------| 5        |
        |              |                    |          |
        |              # 3.3k pullup resis. |          |
        |   Enable     |  |\                |          |
        *--pushbutton--*--|  >o-------------| 6        |
        |              |  |/ 74LS04 inverter|          |
        |             ---                   |          |
        |             --- 1uF cap           |          |
        |              |                    |          |
        |    DB0       GND                  |          |
        *---switch--------------------------| 7        |
        |                                   |          |
        |    DB1                            |          |
        *---switch--------------------------| 8        |
        |                                   |          |
       ~~~                                 ~~~        ~~~
       ~~~                                 ~~~        ~~~
        |    DB7                            |          |
        *---switch--------------------------| 14       |
        |                                   |__________|
        |
        GND


3.2 Interfacing to a CPU bus

These modules use an interface like those in Motorola and Zilog systems.
R/W on the module can come from the R/W line on the CPU, which is set
up about the same time as the address, while RS can be selected by the
low order address line A0.  Select Enable by ANDing the output from your
address decoding and the E clock.  Address decoding can be done with 
a magnitude comparator like the 74LS688, or if you have address space to
spare, with just the high order address line (hogging a big chunk of 
addressing space).  

Because Intel CPUs use separate read and write lines, and they are not
set up ahead of time, R/W as well as RS must be set via address lines.
Then the Enable signal may be generated from (NOT(/RD AND /WR)) AND  
PSEN).  

Using the data bus method limits CPU clock speed because of the tDDR read
delay and the TcycE and PWEH requirements of the Hitachi controller.

3.3 Interfacing to a CPU port

Another interface is the use of 7 I/O bits from a port.  In this case,
driving the module is very simple in 4-bit mode.  Example:

      |     .--------
      |     |
  PA0 |-----| DB0
  PA1 |-----| DB1
  PA2 |-----| DB2
  PA3 |-----| DB3
  PA4 |-----| R/W
  PA5 |-----| RS
  PA6 |-----| E
  PA7 |--   |
      |     `--------

First, put the most significant nybble on PA3-PA0, and the appropriate
R/W and RS signals on PA5 and PA4, and PA6 low.  Then toggle PA6 high.
Then toggle PA6 low.  Then put the least significant nybble on PA3-PA0,
then toggle PA6 high, toggle PA6 low.  40 microseconds later, you can
send the next character.  There's no need to worry about cycle timings
at all with any but the most blinding speed CPUs.  Just be sure to 
notice that toggling PA6 is done by itself, while the other pins are
held constant.

If you have port pins to spare, then an 8-bit interface can be done with
11 port pins (10 for write only).

If you don't expect to ever be reading back from the LCD, you can conserve
resources by grounding R/W, saving a pin, and thus using digital outputs
instead of bidirectional ports.

Sample in-line assembly code, by Jordan Nicol, for implementation under 
Dunfield's Micro-C for the Miniboard can be found on ftp cher.media.mit.edu  
It uses port pins PA7-PA3 for 4-bit data and PC6 and 7 for RS and E.

3.4 Interfacing to the Parallax BASIC STAMP

Sample program with physical hookup described in commented code can be
found on the ftp site wpi.wpi.edu in the /stamp directory.  It's a CPU
port hookup as described above.  The application also involves use of
a radio control servo.

3.5 Serial interface

A way to save even more I/O space is to use a serial interface, requiring
just 3 digital output port pins.  It uses a shift register with serial-in, 
parallel-out, and output latch.
               ________________         __________
_____         |  74LS595       |       |          |
     |        |              QA|-------|DB4       |
     |--------|>ser. clock   QB|-------|DB5       |
CPU  |        |              QC|-------|DB6       |
OUT  |--------|>latch        QD|-------|DB7       |
PORT |        |              QE|-------|RS        |
     |--------|serial data   QF|-------|E         |
_____|        |              QG|--     |          |
       10Kohm |              QH|--     |          |
       pullup |                |       |          |
   +5V--^^^---|\Reset          |   .---|R/W       |
        .-----|\OE             |   |   |__________|
        |     |________________|   GND
        GND

This method (which could be adapted to turn any 8-bit digital output into up
to 64 8-bit digital outputs, albeit at a slow speed) uses just three pins.
It does take more processor time to implement, but it is "care free" because
it will take more than 40us for most controllers to send a byte this way,
so a whole screen rewrite could be done without worrying about timing.

The Amateur Robitics column in June '94 Nuts & Volts demonstrated how to use 
this technique with the 68hc11's SPI port, using MOSI, SCK, and /SS.  This 
would be especially handy with a non-networked Miniboard, which has MOSI,
MISO, SCK, and /SS conveniently routed to the top left corner where resistor
pack 2 goes.  The experimenter could put the contrast potentiometer and latch
on a daughterboard mounted underneath the LCD module.  

4.0 Notice

/*
 *  Trademarks and service marks appearing in this FAQ are the property
 *  of their respective owners.  Copyright 1994 by Christopher Burian and
 *  other contributors.  All rights reserved.  Permission is granted to 
 *  distribute and reproduce this FAQ freely as long as this notice and 
 *  all attributions remain intact.  Please email cburian(aatt_sign)uiuc.edu with
 *  any suggestions, additions, or corrections.  Have a groovy day.      
*/