Controlling HD44780-Compatible Character LCDs

Character LCDs, represented by the 16-character by 2-line “1602” modules, are standard components for displaying device status and debugging information. Most of these modules are equipped with the HD44780 (a character LCD controller manufactured by Hitachi, Ltd., whose successor compatible products are supplied by various companies and have become the industry standard), a controller that appeared in the 1980s and continues to be used as an industry standard today. This article explains connection in 4-bit mode, the initialization sequence, DDRAM addresses where characters are stored, how to create custom characters, and troubleshooting when “nothing is displayed.”

Pin Configuration and 4-Bit Mode

The signals used for control are RS for register selection, R/W for read/write selection, the E (Enable) signal, and the data bus DB0 to DB7. The latch timing is the falling edge of E. In addition to these, there are the power supply and V0 (a pin that provides contrast voltage via a variable resistor) for contrast adjustment. Note that the notation varies among Vo, V0, and VEE depending on the module or documentation. Since VEE may refer to a negative voltage supply pin, be sure to check the specifications specific to your module.

In addition to the 8-bit mode that uses all eight data lines, there is a 4-bit mode that uses only the upper four (DB4 to DB7). The 4-bit mode is standard for microcontrollers because it requires less wiring. In 4-bit mode, 1 byte is transferred twice by placing it on DB4 to DB7 in the order of the upper nibble (bit7..4) followed by the lower nibble (bit3..0). These two transfers must be completed as a set. If the boundary between the upper and lower nibbles is disrupted by a pause in processing or an interrupt, subsequent data interpretation will continue to shift, resulting in garbled characters (re-initialization is effective for recovery). The two E pulses for the upper and lower nibbles must be completed within the same task or the same critical section. To prevent the transfers from being separated, use a mutex to ensure exclusive access to the transmission function if using an RTOS, or disable (mask) interrupts only during the upper and lower transfer processing if using bare metal.

Sending Commands and Data Separately

Commands (instructions such as clearing the screen or moving the cursor) are sent when RS = 0, and display data (character codes) are sent when RS = 1. In either case, a pulse is applied to E after stabilizing RS, R/W, and the data bus to satisfy the specified setup and hold times. As a result, the value is latched on the falling edge of E. Although R/W is used for reading (checking the busy flag), if you adopt a method of “waiting for a specified time for each command” instead of reading, you can tie it to GND, reducing the wiring by one more line.

Initialization Sequence: Where Many People Get Stuck

The HD44780 does not have a hardware reset pin, and the internal power-on reset only works when the power-supply ramp conditions are met. If only the microcontroller restarts, it starts from a state where it is unknown whether the LCD is in 8-bit mode or 4-bit mode, or even whether it is in the first half or the second half of a 4-bit transfer. Therefore, the datasheet specifies a procedure to reliably establish the 8-bit mode from any state.

  • After power-on, wait for the specified time (waiting for the LCD’s internal reset to complete: 15 ms or more if VCC ≥ 4.5 V, 40 ms or more if VCC ≥ 2.7 V).
  • Send the nibble 0b0011 (= 0x03, corresponding to the upper 4 bits of 0x30 in 8-bit bus mode), which corresponds to the upper 4 bits of “Function Set (8-bit setting),” to the data bus (DB4 to DB7) three times, with the specified wait times (after the 1st transmission: 4.1 ms or more, after the 2nd transmission: 100 µs or more) in between. After the 3rd transmission, wait for approximately 37 µs or more before proceeding to the next step. This establishes the 8-bit mode regardless of the current state.
  • Send the nibble 0b0010 (= 0x02), which corresponds to the 4-bit setting, to the data bus (DB4 to DB7) to switch to 4-bit mode. In 4-bit connection implementations, it is sometimes conventionally explained as 0x33 followed by 0x32 (both notations refer to transmission of the upper nibble). This article describes the procedure in units of nibbles.
  • Thereafter, use two 4-bit transfers for each command: Function Set (4-bit, 2-line, 5x8 font), Display OFF, Clear Display, Entry Mode Set, and Display ON.

The wait time for each step is specified in the datasheet. Although the wait-time method is simple, the required time varies for each command. In particular, Clear Display (0x01) and Return Home (0x02) require longer wait times than other commands (while many other commands require approximately 37 µs, these two require approximately 1.52 ms). If you do not read the busy flag, wait for the maximum execution time of each command specified in the datasheet plus a margin for worst-case conditions, such as low temperature, low VCC, and low clock speed. For commands other than Clear Display and Return Home, set the wait time based on the maximum value in the same way. If you omit this procedure and wait times, unstable behavior will occur, such as nothing being displayed at all, or recovery only occurring when the power is cycled. It is also a classic symptom that an LCD that has failed to initialize will display only a black bar (all dots lit) on the first line, with only the contrast functioning.

Displaying Characters and DDRAM Addresses

Characters are displayed when character codes are written to the display RAM (DDRAM). The position is specified by the DDRAM address set command (0x80 + address), starting from 0x00 for the first line and 0x40 for the second line. For example, the command to move to the beginning of the second line is 0x80 + 0x40 = 0xC0. Since the HD44780 Series has a DDRAM larger than the number of displayed characters (generally 80 characters) and the allocation to the display window differs depending on the module type, it is important to note that characters following the first line do not necessarily appear on the second line. For a 16-character by 2-line display, the first line is 0x00 to 0x0F, and the second line is 0x40 to 0x4F. When “nothing is displayed even though you intended to write to the second line,” you should first suspect this address.

Note that many products distributed in Japan are the Japanese font version (ROM code A00), which also includes Katakana character codes. However, since low-cost overseas modules have multiple ROM variations such as A02 (European font version) and A01 (Western European font version), check the ROM code of the module in the specifications before purchasing.

Custom Characters (CGRAM)

CGRAM allows you to register up to eight custom 5x8 dot patterns. Each character is defined by 8 bytes (1 byte for each row’s dot pattern). Each row mainly uses 5 dots (corresponding to the lower 5 bits), with the remaining bits being unused or implementation-dependent. Once patterns are written using the CGRAM address set command, they can be displayed using character codes 0x00 to 0x07. Because this feature can make the display of embedded devices much easier to understand, such as with battery level icons, unit symbols (like ℃), and simple level meters, it is worth using.

Troubleshooting When “Nothing Is Displayed”

  • Check the power supply and backlight: First check the VCC and GND wiring, whether the backlight (A/K) is lit, and the wiring of the V0 variable resistor.
  • Nothing is visible at all: Insufficient contrast (V0) adjustment is the most common cause. Turn the variable resistor to first make the black bar visible.
  • A black bar appears but no characters are displayed: This is due to either an issue with the initialization sequence (insufficient wait time or missing steps) or the E signal pulse not being output correctly.
  • The display occasionally shows garbled characters: The upper and lower nibbles of the 4-bit transfer may have become misaligned. Suspect that noise or interrupts have interrupted the transfer; as a recovery measure, it may also be practical to incorporate periodic re-initialization into the design.
  • Only the second line is not displayed: The DDRAM address (0x40) is incorrect, or initialization was performed in 1-line display mode.

Summary

HD44780-compatible controllers can be used reliably by keeping two points in mind: “following the initialization sequence as specified” and “understanding the DDRAM addresses.” Once the driver is modularized, the prototyping speed of devices with displays will increase significantly.

Back to The World of Embedded Software Top