This is my initial version of a LCD C library for the Hitachi HD4478 compatible LCD displays, the library I hope to make a portable as possible. Only a few routines need to be edited to tell the library how to access the LCD via the system's IO. This example version is based on interfacing via Z-80 PIO
List of current commands in Library:
extern void delay(int j); Depending on the speed of the processor delays maybe needed to be increased, due to the slow processor speed inside the LCD unit.
The following three commands will contain location and how to read and write to the LCD via hardware being used:
void LCD_busy( void ); Check's busy flag on the LCD unit, check before sending new commands to the LCD display
void LCD_write( unsigned char a ); send a data byte to the LCD
void LCD_write_cmd( unsigned char a ); write a command byte to the LCD
unsigned char LCD_read( void ); read a data byte from the LCD
unsigned char LCD_read_cmd( void ); read a command data byte
These commands are not system dependent:
void LCD_print( unsigned char address, char *ptr ); Print a string of characters
char LCD_load_char( char address, unsigned char *ptr); load a custom character into one of 8 locations(0-7) .
void LCD_init(void); this is where you setup a custom initialization setting for the LCD.
Flags found in LCD_HD44780_LIB.h example usage: LCD_write_cmd( LCD_FUNCTION_SET | LCD_FUNCTION_SET_DATA_8BIT | LCD_FUNCTION_SET_LINES_2 | LCD_FUNCTION_SET_FONT5X7);
Other notes this was tested and compiled using Small device C compiler (sdcc)
extern delay system call to delay before a read or write to LCD.
The library expects you to have this defined in the calling routine.
/* LCD_HD44780_LIB.h */
/* Genric LCD Display Library for Hitachi HD44780 by Eric Stringer */
/* eric.stringer@gmail.com version 1.0 Dec 2016 */
/* Bit settings for LCD Command Functions */
#define LCD_CLEAR 0b00000001 // Clear display and return cursor home
#define LCD_HOME 0b00000010 // Cursor home
// These functions are writen as a group OR together
// Entry mode set
#define LCD_MODE 0b00000100 // indicate mode to be set.
#define LCD_SHIFT_OFF 0b00000000
#define LCD_SHIFT_ON 0b00000001
#define LCD_CUR_DEC 0b00000000
#define LCD_CUR_INC 0b00000010
// Display control
#define LCD_DISPLAY 0b00001000 // indicate Display control
#define LCD_DISPLAY_OFF 0b00000000
#define LCD_DISPLAY_ON 0b00000100
#define LCD_DISPLAY_CURSOR_OFF 0b00000000
#define LCD_DISPLAY_CURSOR_ON 0b00000010
#define LCD_DISPLAY_CURSOR_BLINK_OFF 0b00000000
#define LCD_DISPLAY_CURSOR_BLINK_ON 0b00000001
// Cursor display shift
#define LCD_DISPLAY_CURSOR 0b00010000
#define LCD_DISPLAY_CURSOR_MOVE 0b00000000
#define LCD_DISPLAY_CURSOR_SHIFT 0b00001000
#define LCD_DISPLAY_CURSOR_SHIFT_LEFT 0b00000000
#define LCD_DISPLAY_CURSOR_SHIFT_RIGHT 0b00000100
// Function set
#define LCD_FUNCTION_SET 0b00100000 // Function set
#define LCD_FUNCTION_SET_DATA_4BIT 0b00000000 //
#define LCD_FUNCTION_SET_DATA_8BIT 0b00010000 //
#define LCD_FUNCTION_SET_LINES_1 0b00000000 //
#define LCD_FUNCTION_SET_LINES_2 0b00001000 //
#define LCD_FUNCTION_SET_FONT5X7 0b00000000 //
#define LCD_FUNCTION_SET_FONT5X10 0b00000100 //
// Set CGRAM address
#define LCD_CGRAM_ADDRESS 0b01000000 //
// Set DDRAM address
#define LCD_DDRAM_ADDRESS 0b10000000 //
extern void delay(int j);
void LCD_busy( void );
void LCD_write( unsigned char a );
void LCD_write_cmd( unsigned char a );
unsigned char LCD_read( void );
unsigned char LCD_read_cmd( void );
void LCD_print( unsigned char address, char *ptr );
char LCD_load_char( char address, unsigned char *ptr);
void LCD_init(void);
/* Genric LCD Display Library for Hitachi HD44780 by Eric Stringer */
/* eric.stringer@gmail.com version 1.0 Dec 2016 */
/* Bit settings for LCD Command Functions */
#include "LCD_HD44780_LIB.h"
#include "Z80_IO.h"
void LCD_write( unsigned char a )
{
// Code is for Z80 PIO driving the LCD
// This is where you would change code to write
// to LCD via your interface configuration
//
Z80PIOA_REG = 0x0f; // set mode 0 byte output
Z80PIOB = 0x05;
Z80PIOA = a;
Z80PIOB = 0X04;
LCD_busy();
}
void LCD_write_cmd( unsigned char a )
{
// Code is for Z80 PIO driving the LCD
// This is where you would change code to write a command
// to LCD via your interface configuration
//
LCD_busy();
delay(10);
Z80PIOA_REG = 0x0f; // set mode 0 byte output
Z80PIOB = 0x01;
Z80PIOA = a;
Z80PIOB = 0X00;
}
unsigned char LCD_read( void )
{
// Code is for Z80 PIO driving the LCD
// This is where you would change code to write a command
// to LCD via your interface configuration
//
unsigned char a;
Z80PIOA_REG = 0x4f; // set mode 1 byte input
Z80PIOB = 0x06;
delay(10);
Z80PIOB = 0X07;
delay(10);
a = Z80PIOA;
delay(10);
Z80PIOB = 0x00;
return a;
}
unsigned char LCD_read_cmd( void )
{
// Code is for Z80 PIO driving the LCD
// This is where you would change code to write a command
// to LCD via your interface configuration
//
unsigned char a;
Z80PIOA_REG = 0x4f; // set mode 1 byte input
Z80PIOB = 0x02;
delay(10);
Z80PIOB = 0X03;
delay(10);
a = Z80PIOA;
delay(10);
Z80PIOB = 0x00;
return a;
}
void LCD_busy( void )
{
unsigned char a;
a = 0x80;
while( (0x80 & a) != 0 )
{
a = LCD_read_cmd();
}
Z80PIOB = 0x00;
}
/* Usage start address of character on display, Character(s) to be display */
void LCD_print( unsigned char address, char *ptr )
{
LCD_write_cmd( LCD_DDRAM_ADDRESS | address);
while ( *ptr != '\0' )
{
LCD_write( *ptr++ );
}
}
char LCD_load_char( char address, unsigned char *ptr)
{
int i;
if (address > 7 ) return -1;
LCD_write_cmd( LCD_CGRAM_ADDRESS + address * 8);
for(i = 0; i < 8; i++)
{
LCD_write( *ptr++ );
}
return 1;
}
void LCD_init(void)
{
LCD_write_cmd( LCD_FUNCTION_SET | LCD_FUNCTION_SET_DATA_8BIT | LCD_FUNCTION_SET_LINES_2 | LCD_FUNCTION_SET_FONT5X7);
LCD_write_cmd( LCD_DISPLAY | LCD_DISPLAY_ON | LCD_DISPLAY_CURSOR_ON | LCD_DISPLAY_CURSOR_BLINK_OFF );
LCD_write_cmd( LCD_MODE | LCD_CUR_INC );
LCD_write_cmd( LCD_DISPLAY_CURSOR | LCD_DISPLAY_CURSOR_SHIFT );
LCD_write_cmd( LCD_CLEAR );
}