Anda di halaman 1dari 12

Hitachi Europe Ltd.

ISSUE

APPLICATION NOTE

: app059/1.0

DATE

: 9/6/97

Interfacing the H8 and the HD44780 LCD driver


In the following code example a H8 microcontroller (H8/3334Y - 8 bit, or H8/3048F - 16 bit) drives the HD44780 LCD
controller and a character display via general I/O ports. The code example provides a formatted printf-like output to any
character module that is based on HD44780. The total I/O requirement is one 8 bit data port and a 3 bit control port.
The hardware is implemented on the low cost evaluation board for the device, that is the EVB3334Y for the H8/3334Y
and the EVB3048F for the H8/3048F.
Please also see application note APPS/026/1.0 for a description of the interface to HD44780 based display driver. This
application note can be used for H8 processors that feature a E-clock interface, like H8/325.

Hardware Implementation
Two I/O ports of the H8 are used to interface with the LCD character module.
Device

Evaluation Board

8-bit data port

3-bit control port

H8/3334Y

EVB3334Y

Port4.0 to Port4.7

Port8.0 to Port8.2

H8/3048F

EVB3048F

PortB.0 to PortB.7

PortA.0 to PortA.2

H8/3334Y
Port 4 is a 8-bit general purpose I/O port and used to connect to the 8-bit data port of the HD44780. Port 8 is also a
general purpose I/0 port, of which Pins P8.0 to P8.2 are used to control the function of HD44780.
H8/3048
Port B is a 8-bit general purpose I/O port and used to connect to the 8-bit data port of the HD44780. Port A is also a
general purpose I/0 port, of which Pins PA.0 to PA.2 are used to control the function of HD44780.
In this case the LCD character module LM086ALN is used, which features a 16 characters by 2 line display including
back-light. All other LCD modules based on HD44780 can easily be adapted.
LCD Driver and Display LM086ALN
8 bit MCU

Port 8

H8/3334Y
P8,0

P8,1

RS

P8,2

R/W

P4,0

Port 4

DB0-DB8

LC D

16

LCD
II
40

40

IC

7
8

8
P4,7

14

LED Backlight
Vo

20k

10k

Vss

Vdd

Picture 1: Hardware implementation on EVB3334Y

1 of 11

Vled

Hitachi Europe Ltd.

ISSUE

: app059/1.0

Software Implementation
The following timing is realised for a normal read/write access to the HD44780:

RS

RW
140 ns min

450 ns min

E
320 ns max

DB0-DB7

Picture 2: Timing
The code example includes some functions to configure the character module and standard printf-like function to
provide a formatted output onto a character module. Depending on the linker settings the print_lcd function will realise
a full ANSI C formatted print function or a reduced version like small_printf or medium_printf , that is provided with
the compiler.
The following table shows how the code size and functionality of different printf-versions are related:
Function Name

Size

Features

_formatted_write

1.0

full ANSI-C printf

_medium_write

0.5

no formatting of floating point numbers

_small_write

0.25

only for integer numbers

In general, include the appropriate function in your linker control file (*.xcl) that is most relevant and code-space
efficient for your application.
Please notice:
EVB3334Y:
When working with the C-Spy debugging environment of the EVB3334Y, please remember to use the commands
calls off
realtime on
commands to allow a realtime execution with this program.

EVB3048F:

2 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

When working with the Hitachi Workbench, be sure that you switch off the intrinsic call option in the processor
configuration menu, so that no memory indirect function calls are used. Otherwise the code on the EVB3048F can only
be executed when directly downloaded into the Flash memory, but not from the working RAM.

LCD300.C
/************************************************************/
/* Interf. betw H8/3334Y a. HD444780 is done with two ports */
/* Port 4: Data port DB0 to DB7 connected to 44780
*/
/* Port 8: Control Port , only bit 0 to 3 are used
*/
/*
Port 8,0:
E-Signal
*/
/*
Port 8,1:
RS - Signal
*/
/*
Port 8,2:
R/W - Signal
*/
/************************************************************/
#include <ioh83337.h>
#include <inh83337.h>
#include <stdarg.h>
#include <stdio.h>
#include <icclbutl.h>
/***************************************************************************************
*****
List of implemented functions
*****************************
write_lcd
int
Write one byte of data or instruction to 44780
[DIVERSE]
rd_lcd
int
read one byte of data from 44780
[check_busy]
check_busy
int
Checks busy flag of HD44780 until write/read is possible
[DIVERSE]
reset_lcd
ext
reset 44780 by software
[main]
command_to_display
ext
sents a command instruction to 44780
[main]
init_lcd
ext
initialize lcd module according to init_table
[main]
lcd_put1char
sub
puts one character to 44780
[print_lcd]
print_lcd
ext
Formatted output to 44780
[main]
main
ext
main function
****************************************************************************************
******/
/***************************************/
/* some instructions for 44780 control */
/***************************************/
#define DISPLAY_ON
0xE
/* display on, cursor on, no blink */
#define RETURN_HOME
0x2
/* to first position on the display */
#define FUNCTION_SET
0x38
/* 8 bit interface, 5x7 dots, 2 lines */
#define CLEAR_DISPLAY
0x1
/* clears display and returns to home */
#define SET_ENTRY_MODE 0x2
/* set entry mode: increment +1, display shift */
#define DISPLAY_OFF
0x8
/* switch display off */
#define NEXT_LINE
0xc0
#define INSTRUCTION
0x0
#define DATA
0x1
/***************************************/
/* globals for cursor positioning
*/
/***************************************/
static int lcd_charcount = 1;
// Turn-On-Cursor Position: Top Left.
static int lcd_linecount = 1;
// First Line.

3 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

/***********************************************************************************/
/* begin of functions
*/
/***********************************************************************************/

/*************************************************
Name:
write_lcd
Abstract:
Write one byte of data or instruction to 44780
Should not be used for direct writing to Display (use lcd_put1char)
Parameters:
data= data value to be written to 44780
select= select data or instructions
equal 0 -> instruction write selected
equal 1 -> data write is selected
Return:
None
************************************************/
void write_lcd(unsigned char data, unsigned char select)
{
if(select == 1)
/* data selected */
P8DR =P8DR | 0x2;
/* set RS signal high */
else
/* instruction selected */
P8DR =P8DR & ~0x2;
/* set RS high */
P8DR
P8DR
P4DR
P8DR

&= ~0x4;
|= 0x1;
= data;
&= ~0x1;

/*
/*
/*
/*

set R/W low */


set E high */
write data byte to LCDII */
set E low */

}
/*************************************************
end of write_lcd
**************************************************/
/*************************************************
Name:
rd_lcd
Abstract:
read one byte of data from 44780
Parameters:
data= data value to be written to 44780
select= select data or instructions
equal 0 -> instruction write selected
equal 1 -> data write is selected
Return:
Data that was read from 44780
************************************************/
unsigned char rd_lcd (unsigned char select)
{
unsigned char i;
P4DDR = 0x0;
/* set data port to input */
if (select == 1)
P8DR |= 0x2;
else
P8DR &= ~0x2;

/*
/*
/*
/*

instruction read */
set rs high */
data read */
set rs low */

P8DR |= 0x4;
P8DR |= 0x1;

/* set R/W high */


/* set E high */

i = P4DR;
P8DR &= ~0x1;
P4DDR =0xff;
return (i);

/* read one byte from lcd */


/* set E low */
/* set data port to output */

}
/*************************************************
end of rd_lcd
**************************************************/
/*************************************************
Name:
check_busy
Abstract:
Checks busy flag of HD44780 until write/read is possible
Parameters:
None
Return:
None

4 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

************************************************/
void check_busy (void)
{
while (rd_lcd(INSTRUCTION) & 0x80)
;
}
/*************************************************
end of check_busy
**************************************************/
/*************************************************
Name:
reset_lcd
Abstract:
reset 44780 by software
Parameters:
none
Return:
none
************************************************/
void reset_lcd(void)
{
unsigned int i,j;
P8DDR = 0xff;
/* set control port to output */
for (i=0;i<3;i++)
{
for (j=0;j < 0xb000; j++)
/* wait loop >15 ms */
;
check_busy();
/* check if busy */
write_lcd(FUNCTION_SET,INSTRUCTION);
/* put out function set instruction to
LCD */
lcd_charcount = 1;
/* reset cursor position */
lcd_linecount = 1;
/* to upper left
*/
}
}
/*************************************************
end of reset_lcd
**************************************************/
/*************************************************
Name:
init_lcd
Abstract:
initialize lcd module according to init_table
Parameters:
none
Return:
none
************************************************/
void init_lcd(void)
{
static unsigned char init_table[5]=
{FUNCTION_SET,CLEAR_DISPLAY,DISPLAY_OFF,DISPLAY_ON,CLEAR_DISPLAY};
unsigned char i;
for (i=0;i<5;)
{
check_busy();
write_lcd(init_table[i++],INSTRUCTION);
}
lcd_charcount = 1;
/* reset cursor position */
lcd_linecount = 1;
/* to upper left
*/
}
/*************************************************
end of init_lcd
**************************************************/
/*************************************************
Name:
command_to_display
Abstract:
sents a command instruction to 44780
Parameters:
data = command to be sent
Return:
none
z************************************************/
void command_to_display(unsigned char data)
{
check_busy();
write_lcd(data,INSTRUCTION);

5 of 11

Hitachi Europe Ltd.


switch (data)
{
case RETURN_HOME
: ;
lcd_charcount = 1;
lcd_linecount = 1;
break;
case CLEAR_DISPLAY
: ;
lcd_charcount = 1;
lcd_linecount = 1;
break;
case NEXT_LINE
: ;
lcd_charcount = 1;
lcd_linecount = 2;
}

ISSUE

: app059/1.0

/* reset cursor position */


/* to upper left
*/
/* reset cursor position */
/* to upper left
*/
/* reset cursor position */
/* in line two.
*/

}
/*************************************************
end of command_to_display
**************************************************/

/*************************************************
Name:
lcd_put1char
Abstract:
puts one character to 44780
checks & updates cursor position for Display Type: 2 lines, 16 chars.
Parameters:
data= output character
*dummy = compiler warning on this line is ok (unused dummy)
Return:
none
************************************************/
//static
void lcd_put1char (char data, void *dummy)
{
check_busy();
// busy-ness as usual...
write_lcd(data,DATA);
// check, wait and then write.
lcd_charcount ++;

// update cursor position

if (lcd_charcount > 16)


{
lcd_charcount = 1;
if (lcd_linecount == 1)
{
lcd_linecount = 2;
command_to_display(NEXT_LINE);
}
else
{
lcd_linecount = 1;
command_to_display(RETURN_HOME);
}
}

// check cursor position range: 2 rows, 16 chars.


// cursor to the left
// if row 1
// move to row 2

// move to row 1

}
/*************************************************
end of lcd_put1char
**************************************************/
/*************************************************
Name:
print_lcd
Abstract:
Formatted output to 44780
Parameters:
standard printf parameter
Return:
number of characters
Library:
TYPE
va_list
FUNC
va_start
FUNC
va_start
FUNC
_formatted_write
************************************************/
int print_lcd (const char *format, ...)
{
va_list ap;
/* ap is of TYPE va_list
int nr_of_chars;

6 of 11

*/

Hitachi Europe Ltd.

ISSUE

va_start (ap, format);

: app059/1.0

/* Variable argument begin


/* format is [Library]
/* lcd_put1char writes to LCD!
nr_of_chars = _formatted_write (format, lcd_put1char, (void *)

*/
*/
*/
0, ap);

va_end (ap);
return (nr_of_chars);

*/
*/

/* Variable argument end


/* According to ANSI

}
/*************************************************
end of print_lcd
**************************************************/
/*************************************************
Name:
put_two_lines
Abstract:
puts first 32 chars (or less) of kette to LCD
Parameters:
kette = any array of chars
Return:
number of printed chars
Author:
Jan Riege
Last Changed:
961119 19:00
************************************************/
unsigned int put_two_lines (const char *kette, ...)
{
unsigned char i;
/* Counter */
for (i=0;i<5;i++)
/* Clear Display 5 Times */
{
check_busy();
write_lcd(CLEAR_DISPLAY,INSTRUCTION);
}
lcd_charcount = 1;
lcd_linecount = 1;

/* reset cursor position */


/* to upper left
*/

for (i= 0;(kette[i]!=0)&&(i<=31);i++)


lcd_put1char(kette[i],0);
return(i);

/* Write upper AND lower Line */

}
/*************************************************
end of put_two_lines
**************************************************/
/*************************************************
Name:
main_
Abstract:
main function
Parameters:
none
Return:
none
************************************************/
void main_(void)
{
unsigned char i;
unsigned long j;
unsigned char demotext1[] = "This is a test string";
unsigned char demotext2[] = "Hitachi test Hitachi test!";
reset_lcd();
init_lcd();
for (;1;) {
i = put_two_lines (demotext1);
printf("printed chars: %d ",i);
for (j=0;j < 0xb000; j++)
;

/* wait loop >15 ms */

i = put_two_lines (demotext2);
printf("printed chars: %d ",i);
for (j=0;j < 0xb000; j++)

/* wait loop >15 ms */

7 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

;
}
/*
for (i=0;i<10;i++)
for (j=0;j < 0xb000; j++)
;
command_to_display (CLEAR_DISPLAY);

/* wait loop >15 ms */

*/
/*
for (i=0;i<3;i++)
{
print_lcd(" this tests");
command_to_display (NEXT_LINE);
printf(" EVB3334Y, i= %d ",i);
print_lcd(" EVB3334Y, i= %d ",i);
command_to_display (RETURN_HOME);
}
*/
}
/*************************************************
end of
**************************************************/

/*************************************************
COMMENTS
ICCH83.PDF
GENERAL C LIBRARY DEFINITIONS
2-39
LOW-LEVEL ROUTINES - icclbutl.h
_formatted_read
Reads formatted data.
_formatted_write
Formats and writes data.
2-41
VARIABLE ARGUMENTS - stdarg.h
va_arg
Next argument in function call.
va_end
Ends reading function call arguments.
va_list
Argument list type.
va_start
Starts reading function call arguments.
**************************************************/

8 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

LCD300H.C
/************************************************************/
/* Interf. betw H8/3048F a. HD444780 is done with two ports */
/* Port B: Data port DB0 to DB7 connected to 44780
*/
/* Port A: Control Port , only bit 0 to 3 are used
*/
/*
Port A,0: E-Singnal
*/
/*
Port A,1: RS - Signal
*/
/*
Port A,2:
R/W - Signal
*/
/************************************************************/
#include <ioh83048.h>
#include <inh83048.h>
#include <stdarg.h>
#include <stdio.h>
#include <icclbutl.h>

/* some
#define
#define
#define
#define
#define
#define
#define
#define
#define

instructions for 44780 control */


DISPLAY_ON
0xE
/* display on, cursor on, no blink */
RETURN_HOME 0x2
/* to first position on the display */
FUNCTION_SET
0x38
/* 8 bit interface, 5x7 dots, 2 lines */
CLEAR_DISPLAY
0x1
/* clears display and returns to home */
SET_ENTRY_MODE
0x2
/* set entry mode: increment +1, display shift */
DISPLAY_OFF 0x8
/* switch display off */
NEXT_LINE
0xc0
INSTRUCTION 0x0
DATA
0x1

/* text to display */
static char textblock[7][21]=
{
"This is a test for ",
"HITACHI EVB3048F and",
"a character display ",
"EVB3048F is a low
",
"cost evaluation
",
"board with HLL
",
"debugging
"};

void write_lcd(unsigned char data, unsigned char select)


/*************************************************
Abstract:
Write data or instruction to 44780
Parameters: data= data value to be written to 44780
select= select data or instructions
equal 0 -> instruction write selected
equal 1 -> data write is selected
Return:
None
************************************************/
{
if(select == 1)
/* data selected */
PADR =PADR | 0x2; /* set RS signal high */
else
/* instruction selected */
PADR =PADR & ~0x2; /* set RS high */
PADR
PADR
PBDR
PADR

&= ~0x4;
/* set
|= 0x1; /* set E high
= data; /* write data
&= ~0x1;
/* set

R/W low */
*/
to LCDII */
E low */

}
unsigned char rd_lcd (unsigned char select) {
unsigned char i;
/*************************************************
Abstract: read one byte of data from 44780
Parameters: data= data value to be written to 44780

9 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

select= select data or instructions


equal 0 -> instruction write selected
equal 1 -> data write is selected
Return:
Data that was read from 44780
************************************************/
PBDDR = 0x0; /* set data port to input */
if (select == 1)
/* instruction read */
PADR |= 0x2;
/* set rs high */
else
PADR &= ~0x2;
/* set rs low */
PADR |= 0x4;
/* set R/W high */
PADR |= 0x1;
/* set E high */
i = PBDR;
/* read one byte from lcd */
PADR &= ~0x1;
/* set E low */
PBDDR =0xff;
/* set data port to output */
return (i);
}
void check_busy (void)
/*************************************************
Abstract: Checks busy flag of HD44780 until write/read is pooisble
Parameters: None
Return:
None
************************************************/
{
while (rd_lcd(INSTRUCTION) & 0x80);
}
void reset_lcd(void)
/*************************************************
Abstract:
reset 44780 by software
Parameters: none
Return:
none
************************************************/
{
unsigned int i,j;
PADDR = 0xff;
/* set control port to output */
for (i=0;i<3;i++)
{
for (j=0;j < 0xb000; j++)
;
/* wait loop >15 ms */
check_busy();
write_lcd(FUNCTION_SET,INSTRUCTION); /* put out function set instruction to
LCD */
}
}
void command_to_display(unsigned char data)
/*************************************************
Abstract: sents a command instruction to 44780
Parameters: data = command to be sent
Return:
none
************************************************/
{
check_busy();
write_lcd(data,INSTRUCTION);
}
static void put_one_char (char data, void *dummy)
/*************************************************
Abstract: puts one character to 44780
Parameters: data= output character
*dummy = compiler warning on this line is ok (unused dummy)
Return: none
************************************************/
{
check_busy();

10 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

write_lcd(data,DATA);
}
void init_lcd(void)
/*************************************************
Abstract: initialize lcd module according to init_table
Parameters: none
Return:
none
************************************************/
{
static unsigned char init_table[5]=
{FUNCTION_SET,CLEAR_DISPLAY,DISPLAY_OFF,DISPLAY_ON,CLEAR_DISPLAY};
unsigned char i;
for (i=0;i<5;)
{
check_busy();
write_lcd(init_table[i++],INSTRUCTION);
}
}
int print_lcd (const char *format, ...)
/*************************************************
Abstract:
Formatted output to 44780
Parameters:
standard printf parameter
Return:
number of characters
************************************************/
{
va_list ap;
int nr_of_chars;
va_start (ap, format);/* Variable argument begin */
nr_of_chars = _formatted_write (format, put_one_char, (void *) 0, ap);
va_end (ap);
/* Variable argument end */
return (nr_of_chars); /* According to ANSI */
}
void main(void)
/*************************************************
Abstract:
main function
Parameters:
none
Return:
none
************************************************/
{
unsigned int i;
reset_lcd();
init_lcd();
for(i=0;;i++)
{
print_lcd(" HITACHI ");
command_to_display (NEXT_LINE);
print_lcd("EVB3048F i= %d",i);
command_to_display (RETURN_HOME);
}
}

11 of 11

Hitachi Europe Ltd.

ISSUE

: app059/1.0

When using this document, keep the following in mind,


1, This document may, wholly or partially, be subject to change without notice.
2, All rights are reserved: No one is permitted to reproduce or duplicate, in any form, the whole or part of this document without Hitachis
permission.
3, Hitachi will not be held responsible for any damage to the user that may result from accidents or any other reasons during the operation
of the users unit according to this document.
4, Circuitry and other examples described herein are meant only to indicate the characteristics and performance of Hitachis semiconductor
products. Hitachi assumes no responsibility for any intellectual property claims or other problems that may result from applications based
on the examples therein.
5, No license is granted by implication or otherwise under any patents or other rights of any third party or Hitachi, Ltd.
6, MEDICAL APPLICATIONS: Hitachis products are not authorised for use in MEDICAL APPLICATIONS without the written
consent of the appropriate officer of Hitachis sales company. Such use includes, but is not limited to, use in life support systems. Buyers
of Hitachis products are requested to notify the relevant sales office when planning to use the products in MEDICAL APPLICATIONS.
Copyright Hitachi, Ltd.,1997. All rights reserved

12 of 11

Anda mungkin juga menyukai