The Hardware
This LCD module uses a Hitachi 44780 LCD controller. This is a very common interface and many manufacturers use this same behavior (or something close). The interface to the LCD is parallel 4 or 8 bits, and three control lines. In this implementation, we used 8 bits. Therefore, the total number of lines from the micro used is 11. See the connection schematic here.
The actual LCD board was purchased from All Electronics. There is no identifying information on the board, but as noted the LCD controller chip is clearly a Hitachi 44780. All Electronics has been kind enough to archive PDFs of the documentation for these devices, even though they appear to be no longer sold. Their documentation can be found here.
The LCD contrast is set using a 10k potentiometer, and the backlight requires an appropriate resistor (we used a 12 ohm)..
The Defines
The following defines are used. They are needed as a guide, but really can be moved all around.
#define lcd_data0 (1<<0) // PA0 #define lcd_data1 (1<<1) // PA1 #define lcd_data2 (1<<2) // PA2 #define lcd_data3 (1<<3) // PA3 #define lcd_data4 (1<<4) // PA4 #define lcd_data5 (1<<5) // PA5 #define lcd_data6 (1<<6) // PA6 #define lcd_data7 (1<<7) // PA7 #define led (1<<8) // PA8 #define lcd_rs (1<<9) //PA9 is register select (data=h, instruction=l) #define lcd_rw (1<<10) // PA10 is Read/Write (read=h, write=l) #define lcd_en (1<<11) // PA11 is enable (hi->low edge)
The Enable
The LCD controller's "EN" line is used to latch in data from the data bus. The latch happens on the falling edge, so typically we leave the line high and pulse low when we want to LCD to see the data that has been presented on the data lines.
// call to have lcd latch the current data
void lcd_latch(void)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, lcd_en );
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, lcd_en );
wait();
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, lcd_en );
}
Instruction vs Data
There is only one data bus, so how does the LCD controller know if the presented data is for display or an instruction? The "RS" line. If RS is help low, the data is seen as an instruction. If RS is high data is seen as something for the LCD screen. There are two helper functions below to control the switching into these modes.
// call to have latched data seen a instructions
void start_instruction(void)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, lcd_en ); // set enable
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, lcd_rw ); // set read/write
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, lcd_rs ); // set register select
}
// call to have latched data seen as text
void start_text(void)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, lcd_en ); // set enable
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, lcd_rw ); // set read/write
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, lcd_rs ); // set register select
}
Initialization Code
void lcd_init (void)
{
start_instruction();
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); //
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x38); // 2nd row 5x7
lcd_latch();
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); //
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x0e); //
lcd_latch();
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); //
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x06); //
lcd_latch();
start_text();
}
Writing to the LCD
In the sample code below, the code values for the characters (close to ASCII, find these in the LCD documentation here) are sent to the data lines and each byte latched in.
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); // AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x43 ); // send 'C' lcd_latch(); AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); // AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x4f ); // send 'O' lcd_latch(); AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); // AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x4f ); // send 'O' lcd_latch(); AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, 0xff); // AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0x4c ); // send 'L' lcd_latch();

