Previous: Setting up the AvrUsb500 and avrdude
Next: Tutorial: Simple Gnome Application Using libglade and C/GTK+

AVR 3-Wire HD44780 LCD Interface (avr-gcc)

February 26th, 2006

I 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).

PC-1202A LCD 3-wire Interface to AVR ATMega8
[click to enlarge]

The circuit in action on my breadboard
[click to enlarge]

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



Categories
AVR Microcontrollers Robotics/Electronics

Related Posts


Technorati Tags

3 Responses to “AVR 3-Wire HD44780 LCD Interface (avr-gcc)”

RSS Subscription Comments RSS Feed

  1. David R Says:

    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.

  2. Johnny Says:

    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.

  3. Bob Ryan Says:

    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!

Leave a Reply