Drive an HD44780 LCD With Just Two Wires

I found a rather slick circuit here and it fell right in with what I was doing at the time. I needed all the pins on ATmega168 that I could get, so even driving an LCD with only 6 wires as opposed to the full 11 seemed too luxurious. The circuit that I found serves as an interface to the HD44780 LCD displays and lets you drive them with only two signal lines, clock and data. It is an improvement over some similar multiplexing methods that do pretty much the same thing, but require 3 lines: clock, data, and enable. Myke Predko's circuit has the data and enable lines combined using a diode logic AND gate.

How It Works

a serial-to-parallel 6-bit shift register with additional logic to fold the data and enable lines together

D-Type Flip-Flops Make For a Good Shift Register

A shift register is a device that can store a number of bits one by one, reading them from the same gate, and output them all at once. 74LS174 is a package of 6 D-type flip-flops and we have it daisy-chained here so that the first gate's output is second gate's input, second gate's output is third gate's input, etc. First gate's input and sixth's gate output are not connected to each other. The device thus behaves exactly like a shift register: on a rising edge of the clock signal, inputs get latched in the flip-flops. Since they are daisy-chained so that the second, third, etc. flip-flop have their inputs tied to the previous flip-flop's output, in exactly six clock cycles whatever we pushed in the first flip-flop on the first cycle will appear on the sixth flip-flop's output. If we keep strobing (lowering and raising) the clock line, bits will move between the flip-flops until they eventually "fall out" of the sixth output gate. What's good about this is that we can read any output gate at any time! So the whole thing boils down to a simplified model of a conveyor belt.
Of course it would be possible to use true shift registers for this, like 74164, but there aren't any hex (six-gated) shift registers readily made that I know of, and with an 8-bit register we would have two extra bits to worry about since we are not using the clear line to empty the chip (that would necessitate pulling another wire from the MCU). And why do we need exactly six bits? Read on. :)

What Gets Sent to the LCD

The really interesting part is how the LCD's enable (E) line is driven. If you read the HD44780 datasheet, you know that it can operate in four-bit data mode where a full byte is sent to it using only four data lines, in two cycles. Also, there are three control lines for us to use: RS (Register Select), RW (Read/Write) and E (Enable). We are using a simple write-only interface — we won't be reading anything from the LCD — so we can permanently tie the RW line to the ground (see schematic). RS line we will be using to send command- or character-sense bits, so it must stay, and the E line we obviously need as well. Using the 4-bit data interface, we arrive to a total of 6 bits.
The input data (D) line together with the clock (CLK) line serves to load the shift register with those six bits. The topmost bit we push is E bit, which is always going to be a 1, so by the time a 1 appears on output gate 6 (Q6 in the schematic) all the other bits will have arrived in their respective places. Fine, so we can just pull the Q6 and attach it to the LCD's E line. When a 1 appears there, LCD read the outputs from the flip-flops and have the correct data, right?
Yes, but only once! Since we're not using the 74174's CLR line to empty it once we've sent the first six bits, we have a problem. There are some ones and zeroes in there and we can't start strobing in the new six bits, because that would start pushing out the old data through the Q6 gate, which we tied to the E signal on the LCD! Any 1 that appears on Q6 will trigger the E line on the LCD and the LCD will see garbage — partly the shifted old data, partly the incoming new bits.
Myke Predko's solution is based on the realization that there are two distinct situations when Q6 may be high:
  1. when the E bit is in place and we want the LCD to act upon it — this is always the case when the shift register was previously empty;
  2. when we are clearing the shift register by strobing in six zeroes and we don't want the LCD to act upon any 1 that shows up on Q6.
These two situations can be discerned by looking at the D line. It will always be low in the second case since that is when we are pushing zeroes into the register. In the first place, it doesn't matter what state the D line is, because we are not strobing anything, so we might as well pull it high! Therefore, we can drive the E line on the LCD by the output from one AND gate that takes Q6 and D lines as inputs. The entire algorithm for driving the LCD using this circuit is then this:

To send a command or data byte:

  1. hold D low, raise and lower CLK six times;
  2. push 1 (raise D, raise CLK, wait, lower CLK);
  3. push RS (1 for text, 0 for command);
  4. push the four high data bits starting with the lowest one;
  5. raise D, wait, lower D;
  6. repeat from 1. to 5., pushing low four data bits in step 4.

Source Code

I modified the lcd.c and lcd.h that come with the NerdKits so they work with this two-wire interface. These are no longer compatible with the original NerdKits LCD wiring scheme! I added many functions and renamed some old ones for a more consistent feel. Lastly, I can only guarantee that they work on the older type of displays that shipped with NerdKits, namely the 2x24 ones. The mechanics of talking to bigger displays are pretty much the same and I attempted to model that in my code, but I can't say it works on differently-sized displays until I try it out myself. If you do, please let me know!

Printed Circuit Board

I set out to design the schematic and printed board in CadSoft's Eagle. It's my first Eagle project so forgive any glaring omissions. I actually have no clue if the wirepads I used are through-hole or not. Also, I don't know if the routing is any good. Should I have tried to keep GND and VCC routes as far as possible? Are the routes too close to each other? Etc. :)

If you are viewing this page on a screen with 96 DPI resolution, the thumbnail will appear in roughly 1:1 proportion.  Click the thumbnail for a larger image.

Eagle Files

Feel free to download and use Eagle project files as you see fit, but I won't answer to any damage to components, fingers, power sources and emotions that may arise from using them in any way. Just apply common sense: it's the guy's first board design.

  • Eagle project files and C code.
  • 2-wire.brd (board)

Credits

It was Steve a.k.a. mcai8sh4 who gave me the idea to make a PCB out of this and use it in testing and development. Cheers, mate! May your keg never run dry.

Comments