AVR 3-Wire HD44780 LCD Interface (avr-gcc)
February 26th, 2006I purchased a Powertip PC-1202A 12x2 LCD with backlight from Wright Hobbies a while back since it was only $7.95. I will be using it often for various projects with robotics and microcontrollers. The problem was, I didn't want to take up all my IO pins on my processor just with the LCD interfacing. I found some circuits for 3-wire and 2-wire interfaces. I went with the 3-wire interface (4 if you want the AVR to control the backlight) and wrote my own little set of routines for controlling the LCD.
Now, there are many great LCD routines out there (see Resources), however, I wanted to learn how to control the LCD myself and I couldn't quickly find an avr-gcc library that supported this 3-wire interface. The code I used is based on descriptions, tutorials, and AVR ASM or PIC ASM code from various locations on the internet (see Resources).
The code I have written for interfacing with the LCD (lcd.c and lcd.h) is minimal. I have written it to be somewhat generic--that is, it should work with any HD44780 based parallel LCD. However, I haven't studied the datasheet to ensure I'm allowing proper delays and I have only tested it with the Powertip PC-1202A LCD (See Resources for datasheet and vendors). At this point in time, it only supports the following functionality:
- Initialize Display
- Turn on/off backlight
- Load a byte into the 74HCT164 shift register
- Send the byte in the '164 as a command to the LCD
- Send the byte in the '164 as a character to the LCD
- Send a character to the LCD
- Move the cursor to a specified position (row and column)
- Increment the cursor position
- Decrement the cursor position
As you can see, I haven't put in any support for sending strings. This is because I'm not familiar enough with the ins and outs of AVR programming and am not sure how I want to implement that in terms of program (flash) memory vs. eeprom memory etc. As I use this code for projects, these issues will come up and I will modify these files and update them herre on the website. So as of now, to load a string into the LCD, you have to do it one character at a time.
Circuit Description
Below is the schematic diagram for the circuit I'm using. The circuit is derived from Stefan Heinzmann's circuit which is a 3-wire interface to a PIC12C508 microcontroller (see Resources).
The AvrUsb500 connector is not necessary. That's just my in-circuit connector for programming AVRs using the AvrUsb500 programmer. You can omit that if you have other means of programming your AVRs. The LCD uses PORTD of the ATMega8. PD7 is "dashed" in the schematic because that is an optional connection. That is for the backlight. You could optionally pull it high or low manually to enable/disable the backlight respectively. You could also use a '555 timer to setup a "one shot" with the E signal to turn on the backlight for a predetermined amount of time after the LCD is written to.
The way this works, is the E pin at PD4 is held low, "disabling" the LCD. The DS/RS at PD5 serves two purposes: DS when E is low and RS when E is high. As DS, the byte is shifted out one bit at a time into the '164 with the CLOCK signal at PD6. Once the byte is loaded into the '164, the E signal is pulsed to move that byte into the LCD in 8-bit parallel mode. Before strobing E, the DS/RS line at PD5 is set high if the data in the '164 is a character and is set low if the data in the '164 is a command. Thus, the DS/RS line is operating as RS for the duration that the E is high.
Download Project Files
Download lcd_pc1202a.tar.gz
This tarball contains the following files to build pc1202a.hex, a program for the ATMega8 that outputs "Micah" to line one of the LCD and "Carrick" to the second line.
- circuit.png - the schematic diagram shown above
- gpl.txt - GPL license information
- main.c - the test program
- lcd.h - header for the LCD routines
- lcd.c - LCD routines
- Makefile - the Makefile that builds pc1202a.hex and optionally programs the chip using the AvrUsb500
Resources
- Powertip PC-1202A LCD Datasheet
- Powertip PC-1202A LCD from Wright Hobbies - $7.95
- Powertip PC-1202A LCD from Electronics Goldmine - $7.95
- Stefan Heinzmann's original PIC12C508 3-wire Interface
- avr-libc Reference Documentation
- Peter Fleury's "Interfacing a HD44780 Based LCD to an AVR"
- Myke Predko's "LCD Interfacing Reference Page"
- Hitachi HD44780 Datasheet
Categories
Popular Posts
RSS Feeds
Archives

January 16th, 2008 at 11:17 am
As a tip, you can use SPI for interfacing to the shift register. It makes sending data to the shift register faster & simpler, since it can be done via the AVR's SPI hardware, instead of manually 'bit-banging' the data/clock lines. Simply connect MOSI to the data line on the shift register, and SCK to the clock line on the shift register.
April 13th, 2008 at 4:47 am
Hello,
I'm test it!
All it Ok, but I try to write a function, it don't work, I have black caracteres (5x7) on LCD.
void lcd_puts(const char *s)
{
register char *c;
while ( (c = *s++) ) {
lcd_putc(c);
}
}/* lcd_puts */
Can you help me ?
Tanks.
July 16th, 2008 at 6:12 pm
Johnny,
Have you made the proper adjustments in the Makefile? I was having similar results running this code on a tiny13 until I changed the MCU to attiny13. Working great with 16x2 LCD now!