| Bitbanging HD44780 based display module with ARM(R) microcontroller |
|
|
|
| Written by Administrator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Saturday, 06 January 2007 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OverviewDisplay modules are very usefully addition to any microcomputer system. Constant evolution of the display technology has led to explosion of choices from classical passive 2 color LCD displays to the glowing OLED (Organic Light Emitting Diode) or VFD (Vacuum Fluorescent Display) modules. Despite all of the changes in the underlaying display technology it is almost certain that character module is based on the industry standard controller the Hitachi (now Renesas) HD44780 or one of its clones and variations. This tutorial describes step by step development of the HBBR Basic software library used to interface an HD44780 based module to the ARM based microcontroller.. Greatest focus is on a the details of the software written in HBBR Basic but the description should be useful to anybody working with the HD44780 based modules. For anybody seeking further information there are number of excellent web based resources, some them are mentioned in the links section. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Pin | Description |
| Notes |
| 1 | VSS | GND | Ground |
| 2 | VCC | +5 V | Logic power supply |
| 3 | VEE | Contrast control | Connect to a voltage between GND and VCC – see documentation for details |
| 4 | RS | Registers Select |
|
| 5 | R/W | Read / Write |
|
| 6 | E | Enable |
|
| 7 | DB0 | Bit 0 | Connect to GND if not used |
| 8 | DB1 | Bit 1 | Connect to GND if not used. |
| 9 | DB2 | Bit 2 | Connect to GND if not used. |
| 10 | DB3 | Bit 3 | Connect to GND if not used. |
| 11 | DB4/PD0 | Bit 4 / Bit 0 |
|
| 12 | DB5/PD1 | Bit 5 / Bit 1 |
|
| 13 | DB6/PD2 | Bit 6 / Bit 2 |
|
| 14 | DB7/PD3 | Bit 7 / Bit 3 / BF |
|
Controlling HD44780
HD44780 has built-in 2 registers IR Instruction Register and DR Data Register through which software can control operation of the display.
From the hardware perspective HD44780 was designed to be directly interfaced with number of different MPU through a well defined bus. This bus is used to transfer data between MPU and display controller. It is a bidirectional parallel bus that can operate in 2 modes full size 8 bit or half size 4 bit. There are 3 control signals RS, R/W and E and either 8 data bits DB0-DB7 or 4 PD0-PD3, DB7 (PD3) is reused as a Busy Flag indicator.
In addition to defining signals bus specification has to describe all of the possible operations that can be performed using the bus with detailed sequencing of the signals as well as precise timing information. Although the HD44780 is designed to be directly interfaced with the MPU it is unlikely to find ARM based microcontroller with the external bus interface compatible with HD44780. But direct bit manipulation (bitbanging) technique makes it possible to emulate bus behavior under software control, while relaxed timing requirements make it fairly easy to meet them.
In the case of HD44780 RS and R/W control signals are used to determine transfer type and direction while E is used to sequence bus operation. RS can be thought of as a 1 bit address, it selects between Instruction.
HD44780 bus transfers
| RS | R/W | Operation |
| 0 | 0 | IR (Instruction Register) write |
| 0 | 1 | Read busy flag DB7 and address counter DB0 to DB6 |
| 1 | 0 | DR (Data Register) write |
| 1 | 1 | DR (Data Register) read |
4 Bit mode signal direction
| Pin | Direction | Comment |
| E | O | Output only |
| RS | O | Output only |
| R/W | O | Output only |
| PD0 | IO | Input/Output |
| PD1 | IO | Input/Output |
| PD2 | IO | Input/Output |
| PD3/BF | IO | Input/Output |
The Wikipedia link explaining in more details of the bus
Selecting control pins
If the microcontroller board does not have a built-in interface for the display module it is possible to select almost any available pin for the interface. The only limitation is on the data pins which must be able to operate as both input or output, control signals can be output only.

In HBBR Basic the easiest way to control the pins is using GPIO Hardware Abstraction Class. It allows full control over the pin using set of operations. All pins and their functions are identified through integer constants.
GPIO functions used are:
Configure for pin function and direction
Clr to set pin output to 0
Set to set pin output to 1
Pin to input pin state
Function GPIO.Configure(ByVal pin As Integer) As Integer
Function GPIO.Clr(ByVal pin As Integer)
Function GPIO.Set(ByVal pin As Integer)
First step is to identify and assign pins to the interface. Below is an example of pin configuration for a Hobby-Robtotics iH1 board supporting lpc2148 or lpc2138.
' Pin assigment for iH1_lpc2138 series board
' Customize for specific board!
' RS - P1.23
' R/W - P1.25
' E - P1.22
' PD0 - P1.27
' PD1 - P1.20
' PD2 - P1.26
' PD3 – P1.21
The actual assignment is done in lcd_initialize_LCD_pin_iH1_lpc2138 sub called from Main.
For the control pins two values are defined, one for setting pin to the output LCD_X_OUT and the other for setting pin value LCD_X as in the example below:
LCD_E = P1_22
LCD_E_OUT = P1_22_OUT
Data pins require 3 values, the extra one for setting pin to be input LCD_PDX_IN as in the example below:
LCD_PD0 = P1_27
LCD_PD0_OUT = P1_27_OUT
LCD_PD0_IN = P1_27_IN
Testing pin assignment
Before connecting display to the ARM microcontroller it is highly recommended to test the actual pin assignment. The test is located in the lcd_test Sub which is called when LCD_TEST is defined. The test procedure is using Debug.Break statement to stop the program execution and allow for manual inspection of the state of the pins.
First test sets all of the pins to LOW and then step by step sets pins to HIGH state, stopping after each pin. At the end of the testing data pins are turned to input while all 3 control pins are pulsed in infinite loop.
After successful test and verification of connection display module can be safely connected to the ARM board.
Write to Instruction Register
Fundamental in controlling HD44780 is the ability to send instructions to it. This requires implementing a bus cycle emulation through bitbanging as done in in lcd_write_IR subroutine.
For a 4 bit interface bus cycle consists of 4 steps:
1 set the control lines
2 output high nibble
3 output low nibble
4 Either synchronize using Busy Flag or wait fixed 10 ms delay for the end of the controller operation.

Setting control lines is straightforward using GPIO functions Clr and Set
' RS=0 R/W=0 E=0
res = IO.Clr(LCD_RS)
res = IO.Clr(LCD_RW)
res = IO.Clr(LCD_E)
Outputing high nibble and low nibble works very similar with the only difference being the bits used for output. The operation is done in lcd_output_high_nibble and lcd_output_low_nibble subroutines. Both of which take as an argument byte to be outputted.
The sequence is as follows:
E pin is raised high with:
res = IO.Set(LCD_E)Call to lcd_set_data_pins_OUT ensures that data pins are configured as outputs.
4 data pins are then set to the value corresponding to the bit position in the byte
1 ms delay is initiated
E pin is set low with:
res = IO.Clr(LCD_E)1 ms delay is initiated
Call to lcd_set_data_pins_IN reverts data pins to be configured as inputs
In 4 bit bus mode for each byte two nibbles have to be outputted by calling lcd_output_high_nibble and lcd_output_low_nibble subroutines, order is important!
After receiving instruction or data HD44780 controller takes some time to process it. Last step in write to the Instruction Register makes ensures that controller is ready for the next operation. This step can be implemented in 2 ways;
Wait fixed delay (longer then any possible processing delay) before returning control to the program
Use Busy Flag to determine end of the processing
Both approaches have their advantages.
Using fixed delays is simple to implement and avoids a situation where program is stuck in the infinite loop waiting for the busy flag to clear.
Using Busy Flag has the advantages of speeding up entire process of sending instructions and data by avoiding unnecessary delays. However, there is a possibility that program can become stuck waiting for Busy Flag. This situation can be dealt with timeouts but it complicates code.
Initializing after power-up
After power has been applied controller has to be initialized to enable 4 bit bus size. Initialization is achieved by following steps outlined in data sheet “Initializing by Instruction”. All these steps are implemented in lcd_initialize_HD44780 and in lcd_init_4_bit_interface subroutines.
The steps are as follows:
Wait for a fixed delay at least 15 ms after power has been applied ( 500 ms )
Set RS=0 R/W=0 E=0 to low
Output &h3 nibble 3 times with 10 ms delay between the steps
Output &h2 nibble
Set mode using Function set instruction, the exact mode value has to be determined for a specific display.
At this point bus interface is initialized to the required 4 bit and controller is ready to accept instruction over the 4 bit bus. To finish initialization code in lcd_initialize_HD44780, following instructions are sent.
' Display ON/OFF
Call lcd_write_IR(LCD_DISP_ALL_ON_CMD)
' Display Clear
Call lcd_write_IR(LCD_CLEAR_CMD)
' Entry Mode Set
'Increment and shift cursor
Call lcd_write_IR(&H06)
Sending Instructions
High level subroutine lcd_write_IR is used to send instructions to the HD44780 controller. As an argument it takes byte with instruction code. There are a number of predefined constants with instruction codes,
High level functions
lcd_write_string
This subroutine is used to send the a string of the characters to the display module the current cursor position.
lcd_set_cursor_pos(row,col)
This subroutine is used to set current cursor position.
Example
The example application first initializes display then sends “Hello World!” string. After that it enters infinite loop reading a line and sending displaying it on the sencond line.
References
HITACHI HD44780U (LCD-II) (Dot Matrix Liquid Crystal Display Controller/Driver) ADE-207-272(Z) '99.9 Rev. 0.0 - datasheet.
Links
Peter Ouwehand -How to control a HD44780-based Character-LCD
Ian Harries - HD44780-Based LCD Modules http://www.doc.ic.ac.uk/~ih/doc/lcd/
Mark Owen's site with graphical design characters (can be slow to load!) HD44780 LCD User-Defined Graphics
LCD Technology http://en.wikipedia.org/wiki/Liquid_crystal_display
OLED http://en.wikipedia.org/wiki/Organic_light-emitting_diode
VFD http://en.wikipedia.org/wiki/Vacuum_fluorescent_display




