Peter Fleury's LCD Library HOWTO

Atmel AVRPeter Fleury's character LCD library is a handy library that works on a large number of 2 to 4 line character LCD models.

When shopping for LCDs you will recognize the type that will work immediately when looking at datasheets. These models all have the same 16 pin parallel interface (3 or 5 power pins, 8 data pins, RS, R/W, E). They all share the same instruction set and have a method for writing to both the screen (DDRAM) and writing pixels to the characters (CGRAM).

If you have a character LCD model that seems similar to the above description, it's very likely that this library will work.

Getting Started

First off, check your voltage. To keep things simple, choose an LCD model that runs at the voltage of your circuit. If you can't find an LCD that runs at the required voltage, you may have to use a voltage level shifting device to change the logic level of all the communication lines. In this case, a serial LCD with fewer connections may be a better choice than this parallel option which uses seven connections to the microcontroller.

Extract lcdlibrary.zip. You will find the following files:

  • lcd.c
    Main library implementation.
  • lcd.h
    API and configuration.
  • test_lcd.c
    Small test program. Advances frames when PD2 is momentarily connected to ground.

Open lcd.h.

Configure MCU Speed

#define XTAL 1000000 /**< clock frequency in Hz, used to calculate delay timer */

Put the running clock speed of your AVR here. The default of 1Mhz is reasonable for most AVR models.

Configure Controller Type

#define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

If you know that you have a KS0073 type controller, set this to 1. If unsure, leave at 0 and as a troubleshooting step later remember that you may have this type of controller, so try rebuilding with this set to 1.

Configure Display

#define LCD_LINES 4 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 20 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */

My model has 4 rows and 20 columns. Adjust the first two values above to match your display.

For the line start values, check the datasheet of your display. Mine contained the following table:

Display Addresses
So the defaults of 0x00, 0x40, 0x14, 0x54 were correct for my model.

If you want the display to wrap when you write past the last display column, set LCD_WRAP_LINES to 1.

LCD_LINE_LENGTH is not used as far as I can tell.

Port Mapping

#define LCD_PORT PORTC /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 0 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 1 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 2 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 3 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT PORTB /**< port for RS line */
#define LCD_RS_PIN 0 /**< pin for RS line */
#define LCD_RW_PORT PORTB /**< port for RW line */
#define LCD_RW_PIN 1 /**< pin for RW line */
#define LCD_E_PORT PORTB /**< port for Enable line */
#define LCD_E_PIN 2 /**< pin for Enable line */

This is configured for the example circuit below. Configure to match your own circuit.

Example Circuit

LCD/AVR Schematic
LCD/AVR Schematic

The configuration in this schematic uses 8 AVR I/O pins to drive the LCD. Your circuit might use slightly more or less depending on your needs.

The potentiometer on the left controls the contrast and should be a small trim pot. Alternatively, you can go fully digital and use a digital potentiometer IC. Trim pots are nice because they can be adjusted without instructions and are available at all hobby and electronics component stores. If you pick a digital potentiometer, you could pick one with I2C serial capability and use Peter's i2cmaster library to easily drive it.

If you don't have a potentiometer, you can normally connect the contrast line to ground, which should result in full contrast. At full contrast, background pixels that aren't currently active will be visible, which is the point of the trimmer pot - you can adjust it so that you see text but not background squares. In a pinch, you could build a voltage divider with two resistors which would act like a potentiometer that was fixed at a single position.

The power lines VCC, GND and the backlight anode A are connected to the circuit's main power supply.

RS, R/W, E and D4-D7 are connected to the AVR and used for communications.

Note that this library only uses the 4 wire connection, and in 4 wire mode the top four connections D4-D7 are used and not the bottom four. This had me bashing my head against the wall for an hour trying to figure out why it wouldn't work with D0-D3. With it incorrectly wired like that, the busy flag constantly returned zero and so the device could never be written. The code hangs.

In addition to the basic LCD circuit I opted above to use a small transistor circuit to allow the microcontroller to switch the backlight on and off. My application is battery powered, so turning this off is key to conserve battery power. The circuit is from "Using a transistor as a switch" on http://www.kpsec.freeuk.com/trancirc.htm, see that page for details. The resistor value of 330 ohms was selected to limit the NPN base current to 10mA for 3v3 and about 15mA for 5v.

If you do not have or want backlight control, connect the backlight cathode K directly to ground.

You can also build a similar transistor circuit on the main GND pin of the display and use it to enable/disable the logic and foreground display of the device.

On the far right side of the example circuit, a button is shown between PD2 and ground. This is used in test_lcd.c test program to "advance frames" and fill the screen with new text.

For a complete code example, see test_lcd.c that comes with the source code package. It shows how to initialize the library, write text, clear screen, position cursor, and create a custom character graphic (the copyright © symbol).

Good luck!

Don&apos;t Fear The LCD!
Don't Fear The LCD!
 
 
 
 

Good site!

Хороший сайт :) Дизайн приятно очень смотрится ;) только кнопочек для добавления в закладки не хватает ...

 
 

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options