Professional Documents
Culture Documents
App 5910
App 5910
ISSUE
APPLICATION NOTE
: app059/1.0
DATE
: 9/6/97
Hardware Implementation
Two I/O ports of the H8 are used to interface with the LCD character module.
Device
Evaluation Board
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
1 of 11
Vled
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
_medium_write
0.5
_small_write
0.25
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
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
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;
/*
/*
/*
/*
}
/*************************************************
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;
i = P4DR;
P8DR &= ~0x1;
P4DDR =0xff;
return (i);
}
/*************************************************
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
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
ISSUE
: app059/1.0
}
/*************************************************
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 ++;
// 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
*/
ISSUE
: app059/1.0
*/
*/
*/
0, ap);
va_end (ap);
return (nr_of_chars);
*/
*/
}
/*************************************************
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;
}
/*************************************************
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++)
;
i = put_two_lines (demotext2);
printf("printed chars: %d ",i);
for (j=0;j < 0xb000; j++)
7 of 11
ISSUE
: app059/1.0
;
}
/*
for (i=0;i<10;i++)
for (j=0;j < 0xb000; j++)
;
command_to_display (CLEAR_DISPLAY);
*/
/*
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
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
/* 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
"};
&= ~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
ISSUE
: app059/1.0
10 of 11
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
ISSUE
: app059/1.0
12 of 11