Controlling a character display with semi-graphical functions with a XE167 device

Application Note, V1.0, January 2008
AP16132
XE167
Controlling a 20 x 4 character display with
semi-graphical functions with a XE167
device.
Microcontrollers
Edition 2008-01
Published by
Infineon Technologies AG
81726 Munich, Germany
© 2008 Infineon Technologies AG
All Rights Reserved.
LEGAL DISCLAIMER
THE INFORMATION GIVEN IN THIS APPLICATION NOTE IS GIVEN AS A HINT FOR THE
IMPLEMENTATION OF THE INFINEON TECHNOLOGIES COMPONENT ONLY AND SHALL NOT BE
REGARDED AS ANY DESCRIPTION OR WARRANTY OF A CERTAIN FUNCTIONALITY, CONDITION OR
QUALITY OF THE INFINEON TECHNOLOGIES COMPONENT. THE RECIPIENT OF THIS APPLICATION
NOTE MUST VERIFY ANY FUNCTION DESCRIBED HEREIN IN THE REAL APPLICATION. INFINEON
TECHNOLOGIES HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND LIABILITIES OF ANY KIND
(INCLUDING WITHOUT LIMITATION WARRANTIES OF NON-INFRINGEMENT OF INTELLECTUAL
PROPERTY RIGHTS OF ANY THIRD PARTY) WITH RESPECT TO ANY AND ALL INFORMATION GIVEN
IN THIS APPLICATION NOTE.
Information
For further information on technology, delivery terms and conditions and prices please contact your nearest
Infineon Technologies Office (www.infineon.com).
Warnings
Due to technical requirements components may contain dangerous substances. For information on the types
in question please contact your nearest Infineon Technologies Office.
Infineon Technologies Components may be used in life-support devices or systems only with the express
written approval of Infineon Technologies, if a failure of such components can reasonably be expected to
cause the failure of that life-support device or system, or to affect the safety or effectiveness of that device or
system. Life support devices or systems are intended to be implanted in the human body, or to support
and/or maintain and sustain and/or protect human life. If they fail, it is reasonable to assume that the health
of the user or other persons may be endangered.
AP16132
Interfacing a semi-graphical display
AP16132
Revision History:
2008-01
Previous Version:
none
Page
V1.0
Subjects (major changes since last revision)
We Listen to Your Comments
Any information within this document that you feel is wrong, unclear or missing at all?
Your feedback will help us to continuously improve the quality of this document.
Please send your proposal (including a reference to this document) to:
[email protected]
Application Note
3
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
Table of Contents
Page
1
Introduction ...................................................................................................................................5
2
2.1
2.2
The hardware .................................................................................................................................6
The TM204 display module with the HD44780 controller ...............................................................6
The XE167’s parallel ports ............................................................................................................11
3
3.1
3.2
3.3
The software ................................................................................................................................17
Low level communication procedures ...........................................................................................17
Middle level operations .................................................................................................................20
High level application examples....................................................................................................25
4
Conclusions and future improvements ....................................................................................31
Application Note
4
V1.0, 2008-01
AP16132
Interfacing a GPS receiver
1
Introduction
This document explains how to interface a character-based 20x4 display with semi graphical functionalities
to an XE167 microcontroller using some I/O ports.
In this document the TM204 display module will be used: this device is a common cheap display module; it is
produced by many manufacturers.
The TM204 module includes a built-in controller that simplifies driving the display, moreover it integrates an
LED (or CCFL) backlight and the LCD color may vary according to the manufactures specifications.
Driving this display module requires no particular hardware, only few ports lines will be used, so you can
apply the code presented in this application note to an alternative Infineon microcontroller.
The scope of this application is to completely control the TM204 features such as strings printing, simple
graphics drawing and building simple animations: these functionalities can be used for a very wide range of
applications beginning from the visualization of various parameters of machinery to a smart debugging
system of source code, showing the status of the program.
In the following chapters first the hardware involved in this application note is described and then the
software programming; finally you’ll find some conclusions.
Required background: Basics of peripherals interfacing.
Application Note
5
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
2
The hardware
This chapter describes the display module used in this application note and how to connect it to the XE167
microcontroller.
2.1
The TM204 display module with the HD44780 controller
The TM204 module is a very widespread display module, it exists in versions built by various manufacturers
that differ in some details like the size, the LCD color and the backlight type. The characteristics that match
all these products is the built-in controller: it’s the HD44780 or a clone product like the KS0066, the
S6A0069, the SED1278, the ST7066 or the SPLC780A1; the protocol used to communicate to the HD44780
display has become a standard in the past years and now it is the most common controller used with
character displays.
Figure 1
The TM204 display module
The TM204 module allows the display of 20 characters per line on 4 different lines: this format is supported
by the HD44780 controller as well as other common formats such 8x2, 16x1, 16x2, 16x4, 20x2 or 24x2. The
display is so called semi-graphical because every character is composed by a matrix of 5x8 dots; the
controller has a built-in character map but it allows you to redefine some of these characters by editing the
dot matrix: with these personalized symbols you can create some graphical effects or you can make your
strings more impressive.
Therefore, controlling the behavior of the TM204 display module means controlling the HD44780 controller: it
communicate with the XE167 through a data bus and a control bus; the supported interface is the so called
“Motorola style” interface with a Read/Write signal (RW) and an Enable command (E). Data flows toward the
controller on an 8 bits data bus (but a 4 bits data bus could be used too) in the form of commands and it can
be read back too. Using commands to read and write data on the display avoids the need to use any kind of
address bus, only one line is reserved: the RS line (that corresponds to the A0 line). This defines if the actual
communication must be processed by the controller as a command or as a data: for example, writing a string
corresponds to send the “write a char” command and sends the characters to write.
Application Note
6
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 2
Block scheme of the TM204 module
In this application note the control signals necessary to communicate with the HD44780 controller will be
generated on the pins of the I/O ports: this procedure could be called “interface emulation” and it is the easier
way realize the communication.
An other way to do this is to connect the display module as a peripheral (or as a RAM bank) through the EBC
of the XE167 microcontroller: in this case the addressing of the HD44780 requires at least two memory
locations of 8 bits.
The next tables, taken from the HD44780 datasheet, show what are the time requirements for data and
commands reading/writing from/to the controller.
Application Note
7
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 3
HD44780 reading timings
Application Note
8
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 4
HD44780 writing timings
The other aspects that concern the communications between the HD44780 controller and the XE167 such
as how to print a string to the display and how to build a simple animation will be described in the Software
chapter.
As seen before, the TM204 module is equipped with an LED display backlight; typically it is powered on or
off depending on the specific application requirements but it could be a good idea to enhance your
application with an automatic backlight ignition according to the actual lighting conditions: this could be done
simply using a photodiode that drives the LED backlight directly or sampling the photodiode status with the
XE167 microcontroller and then driving the backlight separately; this second approach is preferable because
it gives you more control on the backlight status, for example in this case it is possible to enforce a software
hysteresis on the backlight ignition to avoid it useless stress or it is possible to drive the display module with
different graphics according with the lighting conditions or you can implement some particular politics of
power saving.
Another important issue is how to feed the power supply of the LCD: normally a display module is equipped
with two different supply lines, one of these is dedicated to supply the controller (called logic part supply) and
it requires a stable 5 Volts voltage, the other one is related to the supply of the LCD panel: to vary this
voltage value leads to a contrast adjustment of the display, this is useful to compensate a temperature
variation or a different angle of view. The best choice for this kind of display is to connect a trimmer between
the 5 Volts and the ground reference and feed the LCD part supply with the variable voltage that exits from
the wiper so you can adjust the contrast manually.
The next figure shows the complete setup that has been just described: note the amplification stage of the
photodiode that matches its voltage levels with the microcontroller parallel port ones; with this configuration it
isn’t necessary to acquire the photodiode voltage status with an analog to digital converter, the built-in trigger
present on every I/O pin of the XE167 microcontroller returns a logic level high or low when a specific voltage
Application Note
9
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
threshold has been crossed so the logic status of this input pin indicates if the environmental lighting
condition is light or darkness.
After processing, the lighting status exits from another microcontroller’s pin and activates a transistor used as
a switch that feeds directly the display backlight: the amount of current that flows toward the backlight LEDs
could be regulated with another trimmer used to set the display backlight brightness.
Figure 5
Connections diagram
Application Note
10
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
2.2
The XE167’s parallel ports
Before starting to communicate with the display module it’s important to know the characteristic of the
XE167’s I/O lines: this high level microcontroller is has with 116 I/O lines grouped into 13 ports (named
P0…P11 and P15) with some important features:
• Bit-addressability;
• Tri-stated input mode;
• Push-pull or open drain output mode;
• Programmable port driver control;
• I/O voltage range from 3.0 Volts to 5.5 Volts.
These ports have different width and they could be grouped by further advanced features, for example P5
and P15 are analog input ports, some ports have the selectable input threshold capability and others have a
power saving ability.
Since the XE167 microcontroller has a lot of built-in peripherals with a large amount of external signals,
every I/O pin has more than one functionality: typically a pin can be used as input for two different peripheral
modules or as an output for three of them (called alternate functions), it could be configured to be a specific
EBC or JTAG signal or a simple general purpose I/O pin.
Figure 6
Summary of the port functionalities
All the possible settings just described are conveniently configed by a small set of registers; they will be
presented next.
Application Note
11
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 7
The Px_POCON registers
The POCON registers define the port driver strength and the slew rate; the selection is done in groups of four
pins and it can be done for every I/O port.
Application Note
12
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 8
The Pn_OUT registers
When the ports are used in general purpose I/O mode the P_OUT register permit to set the logic voltage
value present on the pin, there is one of this for every port.
Figure 9
The Pn_IN registers
The P_IN registers contain the values currently read at the input pins, also if a port line is assigned as output.
Application Note
13
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 10
The Pn_IOCRx registers
This group of registers selects the digital output and the input driver characteristic, such as pull-up/down
devices, port direction, open-drain and alternate output selections; this can be done for each pin of the port
separately. The PC field coding is explained in the next figure.
Application Note
14
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 11
The I/O control register PC field
With this small set of registers we are able to completely control the status of the display connected to the
XE167 microcontroller: this will be described in the next chapter.
The easistr way to prototype your application is to use an Infineon’s Easy Kit application board: you can
simply access the microcontrollers I/O pins and test your application in a very quick way.
Application Note
15
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The hardware
Figure 12
The “Easy kit” application board
Application Note
16
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
3
The software
This chapter describes the software needed to configure the working display; it is divided into three logical
layers that will be presented from the bottom to the top.
3.1
Low level communication procedures
Before you write something on the display module you need to know how to communicate with it: It’s very
important to understand this first basic step.
Looking at figures 3 and 4 you can see that the control signals involved in the communication process must
be handled in a precise order and with specific timing requirements: this is the process called “interface
emulation”. The following table indicates the meaning of these signals.
Table 1
RS
RW
Meaning
0
0
Write a command on data port
1
0
Write some data on data port
0
1
Read the internal status flag (busy flag)
1
1
Read data from the controller
RS and RW control signals
In this way the logic levels present on these two lines leads to a different behavior of the HD44780 controller
and it gives a different meaning to the data that will be present on the data bus. After these two lines have
been correctly set, the E (enable) signal pulse triggers the selected operation on the data port; now, following
this simple practice we have all the elements to build three basic procedures: LCDwriteCtrl, LCDwriteData
and LCDreadData.
void LCDwriteCtrl(ubyte command)
{
wait60cycles();
DATA_PORT_OUT = command;
wait60cycles();
RW_LINE = 0;
// RW is low for the writing
wait60cycles();
RS_LINE = 0;
// RS low for commands
wait60cycles();
E_LINE = 1;
// E high
wait1ms();
E_LINE = 0;
// E low
wait60cycles();
}
void LCDwriteData(ubyte data)
{
DATA_PORT_OUT = data;
wait60cycles();
RW_LINE = 0;
// RW is low for the writing
wait60cycles();
RS_LINE = 1;
// RS is high for data
wait60cycles();
E_LINE = 1;
wait1ms();
E_LINE = 0;
wait60cycles();
}
Application Note
17
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
ubyte LCDreadData(void)
{
ubyte retVal = 0;
DATA_PORT_CTRL0 = IN_PULL_UP
DATA_PORT_CTRL1 = IN_PULL_UP;
DATA_PORT_CTRL2 = IN_PULL_UP;
DATA_PORT_CTRL3 = IN_PULL_UP;
DATA_PORT_CTRL4 = IN_PULL_UP;
DATA_PORT_CTRL5 = IN_PULL_UP;
DATA_PORT_CTRL6 = IN_PULL_UP;
DATA_PORT_CTRL7 = IN_PULL_UP;
wait60cycles();
RW_LINE = 1;
wait60cycles();
RS_LINE = 1;
wait60cycles();
E_LINE = 1;
wait1ms();
retVal = DATA_PORT_IN;
wait60cycles();
E_LINE = 0;
wait60cycles();
DATA_PORT_CTRL0 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL1 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL2 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL3 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL4 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL5 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL6 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL7 = OUT_GP_PUSH_PULL;
wait60cycles();
return retVal;
}
// set data port as input
// restore data port as output
In these simple procedures you have to note the delay of 1 ms that permits to the display controller “to feel”
the enable signal and than to trigger the selected operation: only 500 ns are strictly necessary but we use a
delay of 1 ms to be sure that the operation is completely executed.
Moreover we have used another little delay inserted between the changes of the status of the control lines:
this is not necessary but it is mandatory, especially for the high clock frequency operations, to wait for the
electrical stabilization of the line: this could be important if the cable that connects the display module with
the microcontroller is quite long.
Obviously the symbolic definitions used in these procedures refer to specific ports pins, in this example (see
figure 5) we have used the followings:
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
RS_LINE
RW_LINE
E_LINE
DATA_PORT_OUT
DATA_PORT_IN
DATA_PORT_CTRL0
DATA_PORT_CTRL1
DATA_PORT_CTRL2
DATA_PORT_CTRL3
DATA_PORT_CTRL4
DATA_PORT_CTRL5
DATA_PORT_CTRL6
DATA_PORT_CTRL7
RS_LINE_CTRL
RW_LINE_CTRL
E_LINE_CTRL
Application Note
P3_OUT_P3
P3_OUT_P4
P3_OUT_P5
P0_OUT
P0_IN
P0_IOCR00
P0_IOCR01
P0_IOCR02
P0_IOCR03
P0_IOCR04
P0_IOCR05
P0_IOCR06
P0_IOCR07
P3_IOCR03
P3_IOCR04
P3_IOCR05
18
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
3.2
Middle level operations
After we have seen how to communicate with the display controller we are ready to learn what commands it
understands; the following figure shows you the complete list of the controller’s command followed by a brief
description.
Figure 13
Command set of the TM204 display module
The “clear display” and “return home” commands are trivial but the “entry mode set” is important to set the
direction of the cursor, that has been moved automatically after every write operations, and to disable the
Application Note
19
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
shift of the entire screen. Another important command is the “display ON/OFF control” that permits to power
on or to power off the display, to decide if you want to show the cursor on it and if this cursor has to blink or
not.
The “cursor or display shift” command permits to select in what direction the cursor or the entire screen has
to shift whereas the “function set” command allows you to configure your specific display module setting, its
characters format, kind of interface and number of lines.
The “set CGRAM/DDRAM address” commands need to select a memory location to write to: the first of them
refer to the internal character generator RAM while the seconds point directly to the displayed data memory.
Other than these we have a command, “write data to RAM”, that permits to write the user data into the
specific location selected with the previous commands and a “read data from RAM” that allows to read the
memory content.
The last command we examine in figure 13 is the “read busy flag and address” command that gives you the
possibility to poll the controller status.
Now, looking at this command set, you can understand the next procedures without any difficult.
void LCDinitialize(void)
{
DATA_PORT_CTRL0 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL1 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL2 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL3 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL4 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL5 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL6 = OUT_GP_PUSH_PULL;
DATA_PORT_CTRL7 = OUT_GP_PUSH_PULL;
RW_LINE_CTRL = OUT_GP_PUSH_PULL;
E_LINE_CTRL = OUT_GP_PUSH_PULL;
RS_LINE_CTRL = OUT_GP_PUSH_PULL;
//data port
//RW
//E
//RS
0 --> write ; 1 --> read
active low
0 --> commands ; 1 --> data
DATA_PORT_OUT = 0x00;
RS_LINE = 0;
RW_LINE = 0;
E_LINE = 1;
wait10ms();
wait10ms();
LCDwriteCtrl(0x38);
wait10ms();
LCDwriteCtrl(0x38);
wait1ms();
LCDwriteCtrl(0x08);
wait1ms();
LCDwriteCtrl(0x06);
wait1ms();
LCDwriteCtrl(0x01);
wait10ms();
LCDwriteCtrl(0x0c);
wait1ms();
}
//function set
//function set
//disp off
//entry mode set
//display clear
//disp on
void LCDdispON(void)
{
LCDwriteCtrl(0x0c); //disp on
wait1ms();
}
void LCDdispOFF(void)
{
LCDwriteCtrl(0x08); //disp off
wait1ms();
}
Application Note
20
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
void LCDwriteChar(sbyte pchar)
{
LCDwriteData(pchar);
}
void LCDwriteString(sbyte *string)
{
uword inx=0;
while(string[inx] != '\0')
{
LCDwriteChar(string[inx]);
inx++;
}
}
void LCDhome(void)
{
LCDwriteCtrl(0x02); //send clear and return home command
wait10ms();
}
void LCDclear(void)
{
LCDwriteCtrl(0x01);
wait10ms();
}
//send clear command
In the initialization procedure we begin setting the data and the control lines to enable the communication
between the XE167 microcontroller and the display module; after that we send the “function set” command to
the controller specifying an 8 bit data interface, a 5 x 8 character size and 2 lines of text (the HD44780
controller handles the other two text lines as the continuation of the first two lines).
The next step is to power off the display and to disable the visualization of the cursor, then there is the
selection of the cursor movement direction: we enable its increments to the right and we disable the shift of
the entire display.
After that we clear the entire display and then we power it on: from this point it is ready for the writing
process.
The “dispON” and “dispOFF” procedures are trivial: you can use them to hide to the user the writing process
and the “clear” and “home” procedures are simple too, they refer to the commands just seen before.
The “writing” procedures lead to the “write data” primitive and they use the built-in character map that is
shown in figure 14; this map is contained in the HD44780 ROM memory.
Application Note
21
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
Figure 14
The HD44780 internal character table
Since the same controller is used in combination with displays of different shapes and sizes, before you start
to write something on the display you need to know where the DDRAM is mapped in the controller’s
addressing space; for the TM204 display module the four text lines are mapped in the DDRAM at:
•
•
•
•
Line 1: from 00h to 13h;
Line 2: from 40h to 53h;
Line 3: from 14h to 27h;
Line 4: from 54h to 67h.
Figure 15
DDRAM address map
Application Note
22
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
As described before, the HD44780 display controller allows you to create up to 8 custom characters: you can
do this by writing the character data to this CGRAM address range: 00h – 3Fh. Every custom character will
be defined sending eight bytes of data to the controller but, for every byte, only the first five bits will be
considered given that the character pixel matrix is composed by a 5 x 8 pixels. Summarizing that:
• Custom character 0: from 00h to 07h;
• Custom character 1: from 08h to 0Fh;
• Custom character 2: from 10h to 17h;
• Custom character 3: from 18h to 1Fh;
• Custom character 4: from 20h to 27h;
• Custom character 5: from 28h to 2Fh;
• Custom character 6: from 30h to 37h;
• Custom character 7: from 38h to 3Fh;
Following these rules and adding the specific command code to the local address we get the global address
value referred to the controller’s address space so the following procedures will be clear to understand.
void LCDgoToPos(ubyte line, ubyte pchar) //connected display is 4 x 20
{
switch (line)
// use set DDRAM address command
{
// lines order: 1 3 2 4
case 1:
LCDwriteCtrl(0x80+pchar-1);
break;
case 2:
LCDwriteCtrl(0xc0+pchar-1);
break;
case 3:
LCDwriteCtrl(0x94+pchar-1);
break;
case 4:
LCDwriteCtrl(0xd4+pchar-1);
break;
default: break;
}
}
void LCDdefineChar(ubyte charNo, ubyte data[8])
{
ubyte i;
LCDwriteCtrl(0x40 + (charNo << 3));
// set CGRAM address command
for(i = 0 ; i < 8 ; i++) LCDwriteData(data[i]);
}
void LCDloadArrowChars(void)
{
const ubyte upArrow[8]
= {0x04,0x0e,0x15,0x04,0x04,0x04,0x04,0x04};
const ubyte downArrow[8] = {0x04,0x04,0x04,0x04,0x04,0x15,0x0e,0x04};
const ubyte rightArrow[8] = {0x00,0x04,0x02,0x1f,0x02,0x04,0x00,0x00};
const ubyte leftArrow[8] = {0x00,0x04,0x08,0x1f,0x08,0x04,0x00,0x00};
const ubyte upRarrow[8]
= {0x00,0x07,0x03,0x05,0x08,0x10,0x00,0x00};
const ubyte upLarrow[8]
= {0x00,0x1c,0x18,0x14,0x02,0x01,0x00,0x00};
const ubyte downLarrow[8] = {0x00,0x00,0x01,0x02,0x14,0x18,0x1c,0x00};
const ubyte downRarrow[8] = {0x00,0x00,0x10,0x08,0x05,0x03,0x07,0x00};
LCDdefineChar(0,upArrow);
LCDdefineChar(1,downArrow);
LCDdefineChar(2,rightArrow);
LCDdefineChar(3,leftArrow);
LCDdefineChar(4,upRarrow);
LCDdefineChar(5,upLarrow);
LCDdefineChar(6,downLarrow);
LCDdefineChar(7,downRarrow);
}
Application Note
23
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
The last procedure is an example of how to define some custom characters following the rules just
described: in this case we have created a set of arrows that point in eight different directions.
Now we have all the elements to write some text on the display; in the next section we will try something of
higher level using our customized arrows.
3.3
High level application examples
Now you know how to write your strings on a display but you may want to do this in a more impressive way;
so you could try this blinking string procedure.
LCDinitialize();
LCDclear();
LCDgoToPos(2,2);
LCDwriteString("Infineon Tech. AG");
while(1)
{
LCDdispON();
wait100ms();
wait100ms();
LCDdispOFF();
wait100ms();
wait100ms();
}
But you can match static and blinking text with a bit of fantasy.
If you want to make your text as an advertising banner you can try this simple method for moving strings.
LCDinitialize();
LCDclear();
while(1)
{
wait100ms();
wait100ms();
LCDgoToPos(dispYold,dispXold);
LCDwriteString("
switch (direction)
{
case RIGHT:
{
dispX++;
if (dispX == 4)
break;
}
case DOWN:
{
dispY++;
if (dispY == 4)
break;
}
case LEFT:
{
dispX--;
if (dispX == 1)
break;
}
case UP:
{
dispY--;
if (dispY == 1)
break;
}
}
Application Note
");
direction = DOWN;
direction = LEFT;
direction = UP;
direction = RIGHT;
24
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
LCDgoToPos(dispY,dispX);
LCDwriteString("Infineon Tech. AG");
dispXold = dispX;
dispYold = dispY;
}
Of course you can find another way to do this, for example you can save some CPU time shifting the entire
screen instead of deleting and re-writing the same string.
Customized characters are very useful to build some simple graphics: look at this flag built with seven
different characters.
void LCDloadFlagChars(void)
{
const ubyte a1[8] = {0x00,0x00,0x0d,0x0e,0x0c,0x0c,0x0c,0x0c};
const ubyte a2[8] = {0x00,0x00,0x13,0x0c,0x08,0x08,0x08,0x08};
const ubyte a3[8] = {0x00,0x00,0x06,0x1a,0x12,0x12,0x12,0x12};
const ubyte b1[8] = {0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0e,0x0c};
const ubyte b2[8] = {0x08,0x08,0x08,0x08,0x08,0x19,0x0e,0x00};
const ubyte b3[8] = {0x12,0x12,0x12,0x12,0x12,0x16,0x18,0x00};
const ubyte c1[8] = {0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x00};
LCDdefineChar(0,a1);
LCDdefineChar(1,a2);
LCDdefineChar(2,a3);
LCDdefineChar(3,b1);
LCDdefineChar(4,b2);
LCDdefineChar(5,b3);
LCDdefineChar(6,c1);
}
//...main...
LCDinitialize();
LCDclear();
LCDloadFlagChars();
LCDgoToPos(1,8);
LCDwriteChar(0);
LCDwriteChar(1);
LCDwriteChar(2);
LCDgoToPos(2,8);
LCDwriteChar(3);
LCDwriteChar(4);
LCDwriteChar(5);
LCDgoToPos(3,8);
LCDwriteChar(6);
Figure 16
Example of a simple graphic
With our arrows defined before we can create a simple animation with only few lines of code: a rotating
arrow.
Application Note
25
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
// definitions for customized symbols
#define ARROW_U
0
#define ARROW_D
1
#define ARROW_R
2
#define ARROW_L
3
#define ARROW_UR
4
#define ARROW_UL
5
#define ARROW_DL
6
#define ARROW_DR
7
//…
LCDinitialize();
LCDclear();
LCDloadArrowChars();
while(1)
{
LCDgoToPos(2,10);
LCDwriteChar(ARROW_U);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_UR);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_R);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_DR);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_D);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_DL);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_L);
wait100ms();
LCDgoToPos(2,10);
LCDwriteChar(ARROW_UL);
wait100ms();
}
You can use your customized characters to build a gauge for any kind of quantities; look at these examples.
void LCDloadENGchars(void)
{
const ubyte frame[8] = {0x1f,0x11,0x11,0x11,0x11,0x11,0x11,0x1f};
const ubyte gauge1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f};
const ubyte gauge2[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x1f};
const ubyte gauge3[8] = {0x00,0x00,0x00,0x00,0x00,0x1f,0x1f,0x1f};
const ubyte gauge4[8] = {0x00,0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f};
const ubyte gauge5[8] = {0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f};
const ubyte gauge6[8] = {0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
const ubyte gauge7[8] = {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
LCDdefineChar(RPM_FRAME,frame);
LCDdefineChar(GAUGE_ENG_L1,gauge1);
LCDdefineChar(GAUGE_ENG_L2,gauge2);
LCDdefineChar(GAUGE_ENG_L3,gauge3);
LCDdefineChar(GAUGE_ENG_L4,gauge4);
LCDdefineChar(GAUGE_ENG_L5,gauge5);
LCDdefineChar(GAUGE_ENG_L6,gauge6);
LCDdefineChar(GAUGE_ENG_L7,gauge7);
}
Application Note
26
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
#define DISPLAY_NCHAR 20
#define DISPLAY_NLINE 4
#define
#define
#define
#define
#define
#define
#define
#define
RPM_FRAME
GAUGE_ENG_L1
GAUGE_ENG_L2
GAUGE_ENG_L3
GAUGE_ENG_L4
GAUGE_ENG_L5
GAUGE_ENG_L6
GAUGE_ENG_L7
#define CHAR_BLANK
#define CHAR_BLACK
0
1
2
3
4
5
6
7
0xfe
0xff
void gaugeExample(void)
{
//...
LCDgoToPos(1,1);
blackChars = (ubyte)(RPM*DISPLAY_NCHAR/maxRPM);
//RPM bar level calculation
for (i = 0 ; i < blackChars ; i++) LCDwriteChar(CHAR_BLACK);
for (i = blackChars ; i < DISPLAY_NCHAR ; i++) LCDwriteChar(RPM_FRAME);
Figure 17
Example of a level indicator 1
tempGaugeLevel = (ubyte)((engineTemp * 16)/ maxTemp);
switch (tempGaugeLevel)
{
case 0:
{
LCDgoToPos(3,19);
LCDwriteChar(CHAR_BLANK);
LCDgoToPos(4,19);
LCDwriteChar(CHAR_BLANK);
break;
}
case 8:
{
LCDgoToPos(3,19);
LCDwriteChar(CHAR_BLANK);
LCDgoToPos(4,19);
LCDwriteChar(CHAR_BLACK);
break;
}
case 16:
{
LCDgoToPos(3,19);
LCDwriteChar(CHAR_BLACK);
LCDgoToPos(4,19);
LCDwriteChar(CHAR_BLACK);
break;
}
default:
Application Note
27
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
The software
{
if (tempGaugeLevel < 8)
{
LCDgoToPos(3,19);
LCDwriteChar(CHAR_BLANK);
LCDgoToPos(4,19);
LCDwriteChar(tempGaugeLevel); //capitalize the character code here
}
else
{
LCDgoToPos(3,19);
LCDwriteChar(tempGaugeLevel-8);//capitalize the character code here
LCDgoToPos(4,19);
LCDwriteChar(CHAR_BLACK);
}
break;
}
} // end switch
Figure 18
Example of a level indicator 2
Application Note
28
V1.0, 2008-01
AP16132
Interfacing a semi-graphical display
Conclusions and future improvements
4
Conclusions and future improvements
This application note has described how to interface a TM204 display module with an XE167 microcontroller
using its parallel ports; this kind of display has a built-in controller that is accessed following specific rules
about timings, signals and commands: all these aspects have been clearly explained.
Add a display to your application! It could be necessary if you want to show any kind of size to the user; in
this case do it with style, using flashing strings or gauges. Otherwise why don’t you add a display to your
application however? It’s simple to connect and it may help you to debug code, to show the status of a
process, to report the statistics of a communication channel and many more, whatever that comes to mind!
To add a semi-graphical display module to your application is easy and cheap; and you remember that it is
portable to lower family Infineon’s microcontrollers, without any problems.
This application note has shown a possible use of a XE167 microcontroller but this is only a little subset of
the capabilities that the Infineon Technologies microcontrollers can deploy. This project could be taken as a
little brick to build a more complex application.
Future improvements of this project could be:
•
•
•
Writing an EBC enhance version;
Adding the support for displays of different sizes;
Adding the support for different display controllers.
Application Note
29
V1.0, 2008-01
http://www. inf ineon.com
Published by Infineon Technologies AG