- Interfacing hardware
- Controlling with software
- Source code
1.Interfacing Hardware:
Let’s start with connecting the LCD hardware with microcontroller (P89v51). The following table lists all pins of LCD module (JHD162A) along with their description.
| Pin No | Name | Description |
| 1 | Vss | Ground |
| 2 | Vdd | +5V |
| 3 | Vee | Contrast Adjustment -2V to -5V |
| 4 | RS | Register Select |
| 5 | RW | 1 -Read , 0- Write |
| 6 | E | Enable Strobe |
| 7 | D0 | Data Line |
| 8 | D1 | Data Line |
| 9 | D2 | Data Line |
| 10 | D3 | Data Line |
| 11 | D4 | Data Line |
| 12 | D5 | Data Line |
| 13 | D6 | Data Line |
| 14 | D7 | Data Line |
| 15 | LED+ | Backlit LED +V Vdd (Optional signal) |
| 16 | LED- | Backlit LED –V Vss (Optional signal) |
LCD Pin Description (JHD162A)
1.1 Connecting Supplies:
Vss (Pin 1) is connected to board ground.
Vdd (Pin 2) is connected to + 5V supply.
Vee (Pin 3) is connected using a variable resistance for adjusting contrast.
LED- (Pin 16) is connected to GND
LED+ (Pin 15) is connected to Vdd
1.2 Connecting control and data signals:
Control signal RS, RW and E are connected to IO Port pins. For data lines we can have two configurations 8 bit mode and 4 bit mode. In 8 bit mode all lines D0-D7 are connected to IO port pins of microcontroller. In 4 bit mode only D4-D7 are connected to IO port pins. The example code available in source section(at bottom of this article) uses the 4 bit mode as default, however 8 bit mode is also supported.
Following images show both 8 bit and 4 bit configuration for interfacing LCD with P89v51 microcontroller.
2. Writing software:
The LCD module is an intelligent component. We communicate to LCD module by sending commands from microcontroller. To write data to LCD module separate sequence is followed for 4 bit and 8 bit mode.
Writing command for 8 Bit mode:
- Write 8 bit data on D0-D7
- Generate strobe by taking EN from high to low
Writing command for 4 Bit mode:
- Write 4 bit data (upper nibble) on D4-D7
- Generate strobe by taking EN from high to low
- Write 4 bit data (lower nibble) on D4-D7
- Generate strobe by taking EN from high to low
The following table lists commands supported by LCD module:
LCD Commands:
| Instruction | RS | RW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Description |
| NOP | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | No Operation |
| Clear Display | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Clear Display and Address counter = 0 |
| Cursor Home | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | x | Address counter = 0 |
| Entry mode set | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S | Set cursor direction(I/D) and auto display shift (S) |
| Display Control | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | Turn display (D) and cursor (C) ON/OFF. Set cursor blinking(B) |
| Cursor/ Display shift | 0 | 0 | 0 | 0 | 0 | 1 | S | R/L | x | x | Shift display/cursor (S), specify direction (R/L) |
| Function set | 0 | 0 | 0 | 0 | 1 | DL | N | F | x | x | Set Interface data width (DL), number of display lines (N), character font (F) |
| Set CGRAM Address | 0 | 0 | 0 | 1 | Set CGRAM address (D0-D5), CGRAM data is sent after this command | ||||||
| Set DDRAM Address | 0 | 0 | 1 | Set DDRAM address (D0-D6), DDRAM data is sent after this command | |||||||
| Busy Flag and Address | 0 | 1 | BF | Read busy flag (BF) and address counter(D0-D6) | |||||||
| Write Data | 1 | 0 | Write data (D0-D7) into DDRAM/CGRAM | ||||||||
| Read Data | 1 | 1 | Read data (D0-D7) from DDRAM/CGRAM |
Legends used in table:-
I/D: 1- Increment, 0- Decrement
S: 1- Auto Display shift, 0 – No display shift
D: 1- Display ON, 0 – Display OFF
C: 1- Cursor ON, 0- Cursor OFF
B: 1- Cursor blinking ON, 0 – Cursor blinking OFF
S: 1- Display Shift, 0 –Cursor move
R/L: 1- Shift right, 0- Shift left
DL: 1- 8 bit interface, 0- 4 bit interface
N: 1- 2 lines, 0- 1 line
F: 1- 5X10 dots font, 0- 5X7 dots font
BF: Busy Flag
LCD Controller (JHD162A, HD44780) Commands
All LCD functions are actually a combination of above mentioned commands. We will use some example functions to understand how to use commands to build higher level functionality.
2.1 LCD Initialization: To initialize LCD a typical sequence of commands is followed. We also configure all LCD related parameters such as data interface width, display characteristics etc. in this function.
Initialization sequence:
- Wait for power supplies to stabilize. Wait for approx 2-3 ms
- Write 0×30 to LCD
- wait for 50ms
- Write 0×30 to LCD
- wait for 10ms
- Write 0×30 to LCD
- wait for 1ms
- Set data interface width (Write 0×30 for 8 bit or 0×20 for 4 bit) to LCD
- wait for 50ms
- Set display lines and font dots
- Set Display OFF, Cursor and blinking off (Write 0x0B)
- Set Display ON, Cursor and blinking off (Write 0x0F)
- Set Cursor move direction (I/D) and display shift (S)
- Clear display (Write 0×01)
- Wait 50ms
2.2 Moving Cursor to Home: To move cursor to home position without clearing the screen we will use following commands
- Write 0×03
- Wait for approx 2ms
Similarly many functions can be implemented using LCD commands. LCD Library available from source code section (bottom of this article) provides following functions using C.
| Function | Description |
| Utility functions | |
| InitializeLCD | Initialize LCD hardware |
| ClearScreen | Clears LCD screen |
| MoveCursorToHome | Moves cursor to home position |
| Cursor functions | |
| SetCursorPos | Sets cursor position |
| SetCursorState | Sets cursor state (Blink,ON/OFF) |
| SetCursorBlink | Sets cursor in blinking state |
| SetCursorNoBlink | Disables cursor blinking |
| SetCursorOn | Cursor enabled |
| SetCursorOff | Cursor disabled |
| Writing functions | |
| WriteCharAtPos | Writes character at defined position |
| WriteStringAtPos | Writes string at defined position |
| Custom character/font functions | |
| CreateCustomCharacter | Creates user defined character |
LCD Library functions
2.3 Detailed function description:
| InitializeLCD | |
| Prototype | void InitializeLCD(); |
| Input parameters | None |
| Output | None |
| Description | Initializes LCD hardware. Configures data interface(4bit or 8 bit). Clears the display and places cursor at home with blinking mode |
| ClearScreen | |
| Prototype | void ClearScreen(); |
| Input parameters | None |
| Output | None |
| Description | Clear screen and moves cursor to home. This function takes approx 1.6 ms to complete. |
| MoveCursorToHome | |
| Prototype | void MoveCursorToHome(); |
| Input parameters | None |
| Output | None |
| Description | Moves the cursor to home position |
| SetCursorPos | |
| Prototype | void SetCursorPos(unsigned char row, unsigned char col); |
| Input parameters | row: row number (first row = 0 and so on)col: Column number (first column = 0 and so on) |
| Output | None |
| Description | Sets the cursor position to specified row and column position |
| SetCursorState | |
| Prototype | void SetCursorState(unsigned char isBlinking, unsigned char isOn); |
| Input parameters | isBlinking: 0 – no blinking, 1- blinkingisOn: 0 – cursor OFF, 1- cursor ON |
| Output | None |
| Description | Changes cursor state (Blinking and On/Off) |
| SetCursorBlink | |
| Prototype | void SetCursorBlink(); |
| Input parameters | None |
| Output | None |
| Description | Sets cursor blinking |
| SetCursorNoBlink | |
| Prototype | void SetCursorNoBlink(); |
| Input parameters | None |
| Output | None |
| Description | Disables cursor blinking |
| SetCursorOn | |
| Prototype | void SetCursorOn(); |
| Input parameters | None |
| Output | None |
| Description | Enables cursor |
| SetCursorOff | |
| Prototype | void SetCursorOff(); |
| Input parameters | None |
| Output | None |
| Description | Disables cursor |
| WriteCharAtPos | |
| Prototype | void WriteCharAtPos(unsigned char row, unsigned char col, char ch); |
| Input parameters | row: row position, First row =0 and so oncol: column position, First column = 0 and so onch: character to be written |
| Output | None |
| Description | Writes a single character ch at specified row and column position |
| WriteStringAtPos | |
| Prototype | void WriteStringAtPos(unsigned char row, unsigned char col, char *str); |
| Input parameters | row: row position, First row =0 and so oncol: column position, First column = 0 and so onstr: string to be written |
| Output | None |
| Description | Writes character string at specified row and column position |
| CreateCustomCharacter | |
| Prototype | void CreateCustomChar(unsigned char charIndex, unsigned char *charBitmap); |
| Input parameters | charIndex: character index in CGRAM (0 to 7 are reserved for user defined characters)charBitmap: Bitmap corresponding to the custom character. Character bitmap consists of 5X8 pixels. Bitmap is stored in 8 bytes. 5 LSBs of each byte store the pixel information.Pixel layout of custom character:charBitmap[0] * * * 1 2 3 4 5
charBitmap[1] * * * 6 7 8 9 10 charBitmap[2] * * * 11 12 13 14 15 charBitmap[3] * * * 16 17 18 19 20 charBitmap[4] * * * 21 22 23 24 25 charBitmap[5] * * * 26 27 28 29 30 charBitmap[6] * * * 31 32 33 34 35 charBitmap[7] * * * 36 37 38 39 40 |
Source Code:
Microcontroller: P89V51RD2
LCD Controller: JHD162A
Compiler: SDCC
Source: LCD Source code
Interfacing LCD with 8051,
great tutorial
Posted by z_is_a | February 10, 2010, 1:37 pmits good
Posted by christopher | November 12, 2010, 6:40 amthe code is giving lot of errors with 89v51reg.h
Posted by Ankit Garg | July 18, 2011, 1:19 pmi have a question here….do i need 10k puller when interface with p0 with lcd..because i see sum connection there have puller…i dnt understand about it.
Posted by sivan | August 9, 2011, 8:27 pmSuperB Thanks
Posted by Adeel | October 27, 2011, 1:53 ami have an issue symbols are comming while i try to display the fonts..could you help me..
Posted by Elavarasu | February 28, 2012, 7:41 amh0w can I burn a written prgrm into 8051
Posted by Daniel | June 11, 2012, 10:40 pmHi Daniel,
Refer to tools article which describes all tools including flashing/burning tools.
http://embeddedtutorial.com/2009/12/setting-up-8051-development-environment-with-free-tools/
Hope this helps
Posted by Parveen Kumar | June 16, 2012, 10:29 amHi Elavarasu,
If you are seeing symbols instead of proper fonts that means improper initialization. Try increasing delays in init.
Posted by Parveen Kumar | June 16, 2012, 10:30 amHi Ankit
The code posted in http://embeddedtutorial.com/category/source-code/ section is compiled with SDCC compiler. It might not work as it is with other compilers. Also don’t forget to tell SDCC that you are compiling for 8051, as it supports multiple CPUs
Posted by Parveen Kumar | June 16, 2012, 10:32 am