How to control a HD44780-based Character-LCD
The Industry Standard Character LCD
Visitor # (unknown)
© 1995-2012 Peter Ouwehand.
Last updated on 2012-10-03
Miscellaneous examples
5. Miscellaneous examples
5.1. PIC16C54 using only 3 lines
This example is donated by Marc Simons.
If you have any questions/comments please send e-mail to


Brief description:

Pins RB0, RB1 and RB2 are used for controlling AND driving text to the LCD display. Most of the time the PIC's are sufficient enough for most applications, except when it comes to more I/O. This simply cannot be expanded, except when you go to the BIG GUYS like the PIC16C74 etc. where I have done some applications with too. Observe the schematics: An PIC16C54 is the heart of the whole thing. It drives the HEF4094 CMOS serial2parallel converter. This gives us the databus towards the LCD display. Since the HEF4094 strobe is activated at the rising edge, and the LCD display on the falling edge, these can be shared. So, on the rising edge the 4094 spits out it's new byte, and on the falling edge the LCD reads it in. By the way, this concept cannot read out info from the LCD display. (Personal opinion: It is useless anyway!) Now the hard part comes: How to derive 'text' from 'commands'?? The LCD has a pin for it: The RS-pin. When it is clear, commands are accepted. when set, text is accepted. How is it solved?

Before I spit out a character to the HEF4094, I set the clock for 500uSec. Resistor R1 will load capacitor C5. Then, I spit the text character towards the 4094 as soon as possible. Therefore the capacitor simply does not have the time to discharge: The LCD will accept it as text. For commands it is the same, however, of course the other way around: The capacitor must be discharged. T1 forms an emitter follower to buffer the R/C network. The reason for this is that the LCD RS input is an TTL input, so without proper buffering it will not work.

The code contains a few basic routines to handle the LCD display. The switch that I added is purely for fun: To be able to toggle rotation of the text. I used an 16 characters / 2 lines LCD display from an old security keypad. (Go to a surplus electronics store, they always have some!)

P.S. Any suggestions for good code from YOUR side are always welcome! Best Regards from, your PIC Scueezer Weezel!

MSIMONS.ZIP (27,140 bytes) includes the schematics, source code and include file needed for this example.
5.2. ATMEL AT90S2313-10PI C-demo
This demo is donated by Jon Wackley (VE3JTN).
If you have any questions/comments please send e-mail to

Brief description:

Chip: ATMEL AT90S2313-10PI
Clock: 9.420 MHz
Compiler: avr-gcc
Written by: Jon Wackley (VE3JTN)
Date: November 3rd 2002
Availability: (2,559 bytes) which contains the C-source

Table 5.1. Hardware interface
PD0(2) RS(4)
PD1(3) R/W(5)
PD6(11) E(6)
PB0(12) D0(7)
PB1(13) D1(8)
PB2(14) D2(9)
PB3(15) D3(10)
PB4(16) D4(11)
PB5(17) D5(12)
PB6(18) D6(13)
PB7(19) D7(14)
5.3. Variant on PIC16C54 using only 3 lines
This example is donated by Stefan Heinzmann.
If you have any questions/comments please send e-mail to Stefan Heinzmann.


Brief description:

I just came across the schematics for driving an LCD module with just 3 lines on the PIC ( I just wanted to show you an even simpler (and slightly cheaper) way:

- Replace the HEF4094D with a plain 8-bit shift register like the 74HC164 (it will be slightly cheaper). It has no STR input, so the PIC's RB3 just connects to the LCD module's EN signal.

- Connect RB1 to the RS signal of the LCD module, and to the two data inputs of the 74HC164. After having shifted out a byte into the 74HC164, you can put the state of the RS signal on this line.

You don't need a transistor and such, and the timing isn't critical.

You operate it like this:
With EN inactive, you shift out a byte into the shift register in the same way as you did before. This byte defines what's on the DB0-7 signals. Of course, DB0-7 will wiggle while you're shifting, but the LCD will not care as long as EN is inactive. Then, with EN still inactive, you put the state of RS on the PIC's RB1 pin, but you don't toggle the clock line (RB0). Then, you pulse the EN line (RB2) to make the LCD module accept the byte.

It should also be possible to use this technique with a hardware SPI port, which is available in some PICs (or other controllers).

Cheers Stefan
5.4. AVR control of an HD44780-based Character-LCD
A variant on "5.3. Variant on PIC16C54 using only 3 lines" by Frank Henriquez can be found at: 3-line LCD interface ported to the AVR

A local copy of the page is available here.
5.5. HD44780 class in VB6
This example is donated by Spiros Zafrantsas.
If you have any questions/comments please send e-mail to Spiros Zafrantsas.

Brief description:

I intented to make a full emulation of the HD44780, like initialze, busy flag, set display etc., but I only managed to emulate simple commands, like Clear, Home, write data and other, because of short time that I had. I don't have the schematic that I use for the LCD but I believe most of the schematic will do the trick. In future maybe I try and make one up, based on the LCD that I have now.

Files to download are LCDEmulation(ocx).rar and LCDClass.rar.
5.6. Other information sources (Local copy available as zipped file, approx 318kB)
Valid XHTML 1.1! Valid CSS!
Get Firefox Euro No Patents