Errata, comments, and suggestions are most welcome. Please e-mail to: cburian@uiuc.edu
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 PCB that includes the row and column drivers, to the modules I'm actually talking about which also include an on-board 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. These all use the same interface and memory map. The character set is almost always the same with a mixture of English and Japanese characters, but customized models with different character sets also turn up in the surplus market. Also found are modules with extra segments--fixed numbers or words arranged around the dot matrix display area for extra functions. These extra segments look just like additional 5x7 dot boxes to the controller and can be driven by defining custom characters with appropriate bit patterns to energize these special segments as desired.
Version 0 released mid 1994
Version 35 released March 1995
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
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 "
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
+5V ------------------------ Vcc GND ------------*----------- Vss | / 10k to \<---------- Vee 20k pot / \ | -7V ------------'
For operation over a narrow temperature range (such as always indoors), a pair of resistors can be substituted for the potentiometer. At first, try a 10Kohm resistor between Vcc and Vee, and a 330ohm resistor between Vee and Vss, and adjust from there for optimum contrast.
NOTE2: The data pins DB7-DB0 (or DB7-DB4 when using a 4-bit interface) need to be driven by the CPU for a write, but must be switched to hi-Z (or pulled up with pull-up resistors only) so the module can drive the lines on a read or BUSY FLAG check.
When using a 4-bit wide interface, the most significant nibble 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 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.
CAUTION!
Be careful when hooking power to the module. Reversing +5V and GND will destroy the unit. Carefully examine your datasheet to correctly identify Pin 1.
Standard ASCII is used for chr(32) <space> through chr(125) '}' (<00100000b..01111101b>), except that tilde (~) is replaced by a yen symbol.
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 for use on modules which have 5x11 dot matrices. You can access them readily by adding 128 (<10000000b>, 80x) 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). These are sometimes used to implement a comma and lower case characters g, j, p, q, and y with a decender into the cursor row on 5x8 units.
Font Table ---- ----- LSN x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF MSN +--------------------------------------------------------------- 0x | cg0 cg1 cg2 cg3 cg4 cg5 cg6 cg7 cg0 cg1 cg2 cg3 cg4 cg5 cg6 cg7 1x | <------------------------- UNDEFINED -------------------------> 2x | ! " # $ % & ' ( ) * + , - . / 3x | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 4x | @ A B C D E F G H I J K L M N O 5x | P Q R S T U V W X Y Z [ (*) ] ^ _ 6x | ` a b c d e f g h i j k l m n o 7x | p q r s t u v w x y z { | } --> <-- 8x | <------------------------- UNDEFINED -------------------------> 9x | <------------------------- UNDEFINED -------------------------> Ax | (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) Bx | - (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) Cx | (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) Dx | (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) (*) Ex | (*) (*) (*) (*) (*) (*) (*) (g) (*) (*) (j) (*) (*) (*) (*) (*) Fx | (p) (q) (*) (*) (*) (*) (*) (*) (*) (y) (*) (*) (*) (*) (*) (*)
cg0-cg7 user-definable characters (chr) lower-case character with descenders (*) see list below: Hex Decimal Meaning --- --- ------- 5C 92 Yen A0 160 (blank) A1 161 katakana : : : A5 165 katakana (looks like dot in center) : : : DF 223 katakana (looks like degree symbol) E0 224 LC alpha E1 225 "a" with umlaut ("a) (German) E2 226 LC beta (or German es-szet) with descender E3 227 LC epsilon E4 228 LC mu with descender E5 229 LC sigma E6 230 LC rho E7 231 "g" with descender E8 232 radical (square root sign) E9 233 "- |" (Katakana?) EA 234 "j" with descender EB 235 tiny 3 by 3 'x' in upper left corner EC 236 cent sign ED 237 pounds sterling EE 238 "n" with tilde (Spanish) or overbar EF 239 "o" with umlaut ("o) (German) F0 240 "p" with descender F1 241 "q" with descender F2 242 LC theta F3 243 infinity (lazy-8) F4 244 LC omega F5 245 "u" with umlaut ("u) (German) F6 246 UC sigma F7 247 LC pi F8 248 "x" with overbar F9 249 "y" with descender FA 250 katakana FB 251 katakana FC 252 katakana FD 253 division symbol (:-) FE 254 (blank) FF 255 solid black cursor
_ Note: RS=0 (except as noted), R/W=0, command/data from CPU to LCD on bit7 to bit0, x=don't care.
Clears display and returns cursor to home position (address 0). Execution time: 1.64ms
Returns cursor to home position, returns a shifted display to original position. Display data RAM (DD RAM) is unaffected. Execution time: 40us to 1.64ms
Sets cursor move direction and specifies whether or not to shift display. Execution time: 40us
i=1: increment, i=0: decrement DD RAM address by 1 after each DD RAM write or read.
s=1: display scrolls in the direction specified by the "i" bit when the cursor is at the edge of the display window
Turn display on or off, turn cursor on or off, blink character at cursor on or off. Execution time: 40us
d=1: display on
c=1: cursor on
b=1: blink character at cursor position
Move cursor or scroll display without changing display data RAM. Execution time: 40us
s=1: scroll display, s=0: move cursor
r=1: to the right, r=0: to the left
x= don't care
Set interface data length, mode, font. Execution time: 40us d=1: 8-bit interface, d=0: 4-bit interface. n=1: 1/16 duty, n=0: 1/8 or 1/11 duty (multiplex ratio). For 2-line displays, this can be thought of as controlling the number of lines displayed (n=0: 1-line, n=1: 2-line) except for 1x16 displays which are addressed as if they were 2x8 displays--two 8-character lines side by side. f=1: 5x11 dots, f=0: 5x8 dots.
To read or write custom characters. Character generator (CG) RAM occupies a separate address space from the DD RAM. Data written to, or read from the LCD after this command will be to/from the CG RAM. Execution time: 40us
aaaaaa: 6-bit CG RAM address to point to.
Reposition cursor. Display Data (DD) RAM occupies a separate address space from the CG RAM. Data written to, or read >from the LCD after this command will be to/from the DD RAM. Execution time: 40us
aaaaaaa: 7-bit DD RAM address to point to.
Data is written to current cursor position and (DD/CG) RAM address (which RAM space depends on the most recent CG_RAM_ Address_Set or DD_RAM_Address_Set command). The (DD/CG) RAM address is incremented/decremented by 1 as determined by the "entry mode set" command. Execution time: 40us for display write, 120us for character generator ram write:
dddddddd: 8-bit character code
_ RS as noted, R/W=1, bit7 to bit0 output from LCD to CPU.
Read the status of the busy flag, and the value of the RAM address currently being pointed at. Execution time: 1 cycle
b=1: busy, b=0: OK to send
aaaaaaa: 7-bit current (DD/CG) RAM address counter (as in
"character RAM address set" or "display RAM address
set").
Data is read from current (DD/CG) RAM address position, and the RAM address is automatically incremented/decremented by 1 as determined by the "entry mode set" command. NOTE that the display/cursor is not shifted on data reads. Execution time: 40us for display reads, 120us for character generator ram reads
zzzzzzzz: DB lines must be inputs (or pulled high with pullup resistors) to be driven by the module. An 8-bit character code will be read back from LCD RAM.
WRITE:
______ _____________________________ ___________ RS ______X_________valid_RS_level______X__________ | | | | |<--tAS-->| tAH-->| |<-- ______| | | |____________ R/W ______\_________|___R/W_low____|____/_____________ | | |<----PWEH---->| | | |<-------------|-------TcycE----->| |______________| |_________ E ________________/ \__________________/ tR-->||<-- -->||<--tF || |<--tDSW-->|| | -->| |<--tWH __________________|_______________|________________ D0-D7 __________________X__valid_data___X____________
______ _____________________________ ___________ RS ______X_________valid_RS_level______X__________ | | | | |<--tAS-->| tAH-->| |<-- ______|_________|__ _ ____|____|____________ R/W ______/ | R/W high | \_____________ | | |<----PWEH---->| | | |<-------------|-------TcycE----->| |______________| |_________ E ________________/ \__________________/ tR-->||<-- -->||<--tF | || tDDr-->| |<-- || | -->| |<--tRH ___________________|_______________|________________ data ___________________X__valid_data___X____________
Operation cycle time cannot be less than 1 microsecond
Enable pulse must be at least 450 nanoseconds long, no maximum length
Enable line must change state (L->H) in less than 25ns
Enable line must change state (H->L) in less than 25ns
Register Select and R/W lines must be valid 140ns before enable pulse arrives
RS and R/W must be valid at least 10 ns after enable goes low
When doing a read, the return data will be valid within 320ns of enable going high
When doing a read, the return data will be valid at least 20ns after enable goes low
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
When doing a write, data on lines must be valid for at least 10ns after enable goes low
CG Address CG Data D7-----------D0 x+0 x x x 1 1 1 1 1 ***** x+1 x x x 1 0 0 0 0 * x+2 x x x 1 0 0 0 1 * * x+3 x x x 1 1 1 1 1 = ***** x+4 x x x 1 0 0 0 1 * * x+5 x x x 1 0 0 0 0 * x+6 x x x 1 0 0 0 0 * x+7 x x x 0 0 0 0 0 (cursor line)
As you can see in the above figure, each byte of CG data represents 1 row of pixels in the character, with D0 being the rightmost pixel, and D4 being the leftmost (the upper 3 bits are not displayed). The first address for a character is the topmost row, while the 7th is the bottom. (The 8th is ORed with the cursor underbar). A '1' in any pixel position becomes a dark pixel on the display.
CG RAM occupies a separate address space from the data display (DD) RAM. One must set the (first) CG address before writing any CG data. Each write automatically increments/decrements the CG address pointer to the next location. Remember to set the display back to DD addressing mode before trying to write characters to be displayed.
As an example, we'll define character #3 to be the above symbol by first reading the DD address, writing the CG address to the start of the character's RAM, writing the successive rows of pixel data, then restoring the addressing mode back to DD addressing (which requires the DD address we saved at the beginning.
RS R/W D7----D0 0 1 (baaaaaaa) Read current DD address 0 0 01011000 Set CG RAM address to char #3 (3x8=24=11000b) 1 0 00011111 Write top row of pixels 1 0 00010000 : 1 0 00010001 : 1 0 00011111 : 1 0 00010001 : 1 0 00010000 : 1 0 00010000 Write bottom row of pixels 1 0 00000000 Write cursor row (descender) 0 0 1aaaaaaa Restore DD mode (& address)
(This Section Written by Doug Girling)
"Line 1" (left) addresses are 00h to 07h
"Line 2" (right) addresses are 40h to 47h
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 40h before writing the 9th character on the 1x16 module.
Line 1 addresses are 00h to 0Fh
Line 2 addresses are 40h to 4Fh
Line 1 addresses are 00h to 13h
Line 1 addresses are 00h to 13h
[the command to set address is 80h-93h]
Line 2 addresses are 40h to 53h
[the command to set address is C0h-D3h]
Line 1 addresses are 00h to 13h
Line 2 addresses are 40h to 53h
Line 3 addresses are 14h to 27h
Line 4 addresses are 54h to 67h
Line 1 addresses are 00h to 27h
Line 2 addresses are 40h to 67h
<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
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 x x x x
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 x x x x
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
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
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
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
<INITIALIZATION COMPLETE>
NOTE: Remember to turn the display back on and set up the cursor as desired with an On/Off Control command.
After the fourth instruction, which switches the module to 4-bit operation, the control bytes are sent on consecutive enable cycles (no delay is required between nybbles). Most significant is sent first, followed immediately by least significant nybble.
<POWER ON>
<Wait 15ms>
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 0 n/c n/c n/c n/c set 4-bit operation
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
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 00 0 1 0 0 0 Display off, cursor off, blink off
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 00 0 0 0 0 1 Clear screen, cursor home
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 00 0 0 1 1 0 Increment cursor to the right when writing, don't shift screen
<INITIALIZATION COMPLETE>
NOTE: Remember to turn the display back on and set up the cursor as desired with an On/Off Control command.
__________ | | GND---*---------| 1 | < | | contrast 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
68xx 65xx LCD -----. .----- D0 |--------------------------------| D0 : | : | D7 |--------------------------------| D7 _ | | _ R/W |--------------------------------| R/W | .---. | E |------------------------| | | | .----------. | & |---| E A0 |------| | | | | : | : | (Decode) |------| | `----- A15 |------| | CS(h)`---' -----' `----------' Motorola bus interface
80xx Z80 _ | .------. _ RD |------*--| S Q |----------------------------------------- R/W _ | | | | WR |---*--+--| R | | | | `------' | | .---. .---. | `--| & |O--*-------------------------------| |--- E `-----| | | .---. R .---. | & | `---' `--| |O--v^v^v^v--*--| & |O---| | `---' | `---' `---' C === __|_ / / /
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.
(This Section Written by Doug Girling)
Whether you use a 4-bit or an 8-bit interface, those port pins driving the LCD's data lines must be bidirectional if you wish to read from the LCD. Remember too that you'll have to write your code to switch the port's data direction bits whenever you switch >from reading to writing or visa versa. 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.
You may be able to eliminate the need for a software-generated enable (E) signal if the particular port you are using automatically generates a handshake strobe. In practical terms, most ports only generate a strobe on output, and expect a strobe on input, so this approach is most likely applicable to write-only configurations.
| .-------- | | P.7 |<--->| DB7 P.6 |<--->| DB6 P.5 |<--->| DB5 P.4 |<--->| DB4 P.3 |---->| R/W P.2 |---->| RS P.1 |---->| E P.0 |--nc | | `--------
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.
| .-------- | | PA0 |<--->| DB0 PA1 |<--->| DB1 PA2 |<--->| DB2 PA3 |<--->| DB3 PA4 |<--->| DB4 PA5 |<--->| DB5 PA6 |<--->| DB6 PA7 |<--->| DB7 | | PB0 |---->| R/W PB1 |---->| RS PB2 |---->| E PB3 |--nc `-------- PB4 |--nc PB5 |--nc PB6 |--nc PB7 |--nc |
________________ __________ _____ | 74LS595 | | | | | QA|-------|DB4 | |--------|>ser. clock QB|-------|DB5 | CPU | | QC|-------|DB6 | OUT |--------|>latch QD|-------|DB7 | PORT | | QE|-------|RS | |--------|serial data QF|-------|E | _____| | QG|--nc | | 10Kohm | QH|--nc | | pullup | | | | +5V--^^^---|\Reset | .---|R/W | .-----|\OE | | |__________| | |________________| | GND GND
An alternative with a less expensive shift register has the low pincount advantage, but requires bit manipulation of port pins:
_____ __________ | | | |---------------------------------|E | | ________________ | | | | 74LS164 | | | | | QA|-------|DB4 | |--------|>ser. clock QB|-------|DB5 | CPU | | QC|-------|DB6 | OUT | | QD|-------|DB7 | PORT | | QE|-------|RS | |--------|serial data QF|--nc | | _____| | QG|--nc | | 10Kohm | QH|--nc | | pullup | | | | +5V--^^^---|\Clear | .---|R/W | | | | |__________| |________________| | GND
"On your SPI example, you can free up the latch line by using the clock line with a diode, pullup, and capacitor. I use the SPI in normally high mode, rising clock for data bits. 10K pullup, 10nF to GND, and the clock through diode pulls it low. After all the bits are shifted in, the RC times-out, and clocks [latches] the '595."
PIN DEFINITION
1 SEG 22 2 SEG 21 3 SEG 20 4 SEG 19 666665555555555444444444 5 SEG 18 432109876543210987654321 6 SEG 17 65 40 7 SEG 16 66 39 8 SEG 15 67 38 9 SEG 14 68 37 10 SEG 13 69 36 11 SEG 12 70 35 12 SEG 11 71 34 13 SEG 10 72 33 14 SEG 9 73 UPD44780 TOP 32 15 SEG 8 74 31 16 SEG 7 75 30 17 SEG 6 76 29 18 SEG 5 77 28 19 SEG 4 78 NOTCHED CORNER 27 20 SEG 3 79 /AND POSSIBLE DOT 26 21 SEG 2 80 o 25 22 SEG 1 \ 111111111122222 23 GND 123456789012345678901234 24 OSC 1 25 OSC 2 26 V1 27 V2 28 V3 29 V4 30 V5 31 CL 1 32 CL 2 33 VCC 34 M - 35 D - 36 RS - Reset, assert once 37 R/W* - Hold low for write operation 38 E - Clock low to latch data. 39 DB 0 - The data bus 40 DB 1 - 41 DB 2 - 42 DB 3 - 43 DB 4 - 44 DB 5 - 45 DB 6 - 46 DB 7 - 47 COM 1 48 COM 2 49 COM 3 50 COM 4 51 COM 5 52 COM 6 53 COM 7 54 COM 8 55 COM 9 56 COM 10 57 COM 11 58 COM 12 59 COM 13 60 COM 14 61 COM 15 62 COM 16 63 SEG 40 64 SEG 39 65 SEG 38 66 SEG 37 67 SEG 36 68 SEG 35 69 SEG 34 70 SEG 33 71 SEG 32 72 SEG 31 73 SEG 30 74 SEG 29 75 SEG 28 76 SEG 27 77 SEG 26 78 SEG 25 79 SEG 24 80 SEG 23
ftp.ee.ualberta.ca /pub/cookbook/misc/unsorted 4-bit interface sample in-line assembly code, by Jordan Nicol, for implementation under Dunfield's Micro-C for the Miniboard. It uses port pins PA7-PA3 for 4-bit data and PC6 and PC7 for RS and E.
Parallax Basic Stamp applications
wpi.wpi.edu /stamp (Also see below)
Link to a list of a lot of FTP sites for PROCESSORS