Graphic LCD Unit

This is a revised and expanded library unit for controlling KS107/108 type graphic LCD units. It calls upon two other library units for support: one to handle user-defined fonts, and the other for user-defined bitmaps. The download package contains all three.

Obviously, that's sample data within the bitmap unit, which you'll be replacing with that of your own. But by having the sample data there, you'll know the format.


This unit began life as the standard unit provided with PMP, originally written by Olivier Jauzelon and further developed by Philippe Paternotte. This included twelve commands. Another was rescued from their demo program. One additional command to draw boxes with rounded corners derives from old C code for the AVR by Fabian Maximilian Thiele. The remaining five commands are by the PIC Maniac.

A number of changes were made to the original KS107_KS108 library unit to ensure consistency of labels throughout, remove unused references, extend the versatility of the conditional compilation constants, improve the readability of the source code and simplify usage.

In particular, some of the the user-defined data types were deemed to add an unnecessary layer of complexity. Since these were all equivalent to booleans anyway, they were jettisoned, which greatly reduces the typing needed to use the various commands. It's intuitively obvious and easier to remember (as opposed to a new set of labels) that 1 means "filled" or "solid" or "show" or "on," while 0 means "not filled" or "empty" or "hide" or "off."

For emphasis, while I think user defined data types are great for many things (days of the week, port pin names, etc.), it was driving me crazy to recall and type new members when all I really wanted was a 0 or a 1. I mean, I know what those mean in many different settings!

Note that the old Rectangle command has been renamed to Box, and that the parameters now refer to the easier-to-use notion of width and height.

The existing conditional compilation constants were changed to make the port assignments a bit more flexible. It is now possible to deal with ports which may have input-only type pins to be skipped over. With the new arrangement, all data lines must still be on a single port and assigned in order (0 through 7). And all control lines must also be on a single port, but now they may be assigned in any order desired.

All of the fonts, reside within the single GLCD_FONTS unit now. You may select which one to use by means of a conditional compilation constant. See that unit for additional hints and tips.

Similarly, any graphic bitmaps you wish to display reside within the GLCD_BITMAPS unit. In this case, the parameter to the DisplayBitmap() command chooses which image to show. Also, you will need {$DEFINE BITMAPS} in your main program to signify you're using that unit. Again, refer to that unit for additional hints and tips.

Compilation Constants

The conditional compilation constants are (with example  values shown for the 16F88):

{$DEFINE GLCD_CTRL_PORT 'PORTA'} // control port
{$DEFINE GLCD_CS1 0}             // chip select 1 pin
{$DEFINE GLCD_CS2 1}             // chip select 2 pin
{$DEFINE GLCD_RST 2}             // reset pin
{$DEFINE GLCD_RW  3}             // read/write pin
{$DEFINE GLCD_DI  4}             // data/instr pin
{$DEFINE GLCD_EN  6}             // enable pin
{$DEFINE GLCD_FONT 1}            // font selection
{$DEFINE BITMAPS}                // use with bitmaps

About the Fonts Library Unit

The fonts unit contains the text character data for several fonts which  may be used on a graphical LCD. Feel free to add your own. The ones  here appeared anonymously in the PMP distribution package and are  presumably due to Olivier Jauzelon and/or Philippe Paternotte. This  repackaging into a single customizable file is by the PIC Maniac.

A useful tool for creating additional fonts is GLCD Font Creator 2,  which is available free of charge at the following site:

A font is selected by setting the conditional compilation constant GLCD_FONT in your main program equal to the font number:

0 = no font stored in program space
1 = full 8x8 DOS type font (256 characters)
2 = standard 5x7 text LCD font
3 = extended 5x7 text LCD font

If GLCD_FONT has a value of 0, then no font is stored, which saves program space. In this case, only bitmap and graphical commands are of use; text commands become unavailable.

Note that the fonts may have a varying number of printable characters, and hence may take more or less memory to hold. Check the equates for each to see what to expect.

About the Bitmaps Library Unit

This unit contains the bitmap graphic data used by the  command DisplayBitmap() in the GLCD_alt library unit.  It may contain as many bitmaps as your PIC has room for.

Each bitmap is 128 by 64 pixels in size. The free program  LCD Assistant may be used to convert a black and white  graphic to the bitmap data. See:

It takes a block of 1024 bytes for each bitmap image. The parameter in the command DisplayBitmap() indicates which block to display (0, 1, 2,...).

Obviously, the bitmap data is maintained globally. This is not very elegant, but parameter passing of ROM arrays seems to be problematic in the current version of PMP regardless of CONST, ROM, or ROMABLE attributes.

It should be clear that each bitmap consumes program space whether used or not, so only include those you plan on using.

If your program requires bitmaps, then set the conditional compilation constant {$DEFINE BITMAPS}. If no bitmaps are used, then leave this constant undefined so that program space is not consumed by the data.


Okay, here we go! There are many commands to play with here!

procedure GLCD_Init(mode : boolean);
Initialize the graphic LCD. Must be called before any other LCD access.
mode: 0 = leave LCD off after initialization, 1 = turn LCD on after initialization

procedure GLCD_WriteByte(mode : boolean; chips, data : byte);
Write a byte of data to the specified chip(s).
mode: 0 = write to instruction register, 1 = write to data register
chips: chips to write the data to (may be both at once)
data: the data byte to write

function GLCD_ReadByte(mode : boolean; chips : byte) : byte;
Read a byte of data from the specified chip.
mode: 0 = read from instruction register, 1 = read from data register
chips: the chip to be read from
return: data byte read from the chip

procedure GLCD_Cmd(cmd : byte);
Send a low level command to both chips.
cmd : the command to send

procedure PlotPixel(X, Y : byte; state : boolean);
Plot a single pixel.
(X, Y): coordinates of the pixel
state: 0 = off, 1 = on

function GetPixel(X, Y : byte) : boolean;
Get state (on or off) of a pixel in the display.
(X, Y): coordinates of the pixel
return: 0 = off, 1 = on

procedure PlotData(X, Y, data : byte; state : boolean);
Plot a complete data byte.
data: data to be plotted
state: 0 = off, 1 = on

procedure FillScreen(state : boolean);
Fill or clear the LCD screen.
state: 0 = clear, 1 = fill

procedure Line(X1, Y1, X2, Y2 : byte; state : boolean);
Draw a line using Bresenham's drawing algorithm.
(X1, Y1): start point
(X2, Y2): end point
state: 0 = off, 1 = on

procedure Box(X, Y, width, height : byte; fillMode, state : boolean);
(X, Y): coordinates of upper left corner
width, height: box dimensions
fillMode: 0 = not filled, 1 = filled
state: 0 = off, 1 = on }

procedure RoundedBox(X, Y, width, height, R : byte; state : boolean);
Draw a box with rounded corners.
(X, Y): coordinates of upper left corner
width, height: box dimensions
R: radius of the rounded corners
state: 0 = off, 1 = on }

procedure Circle(X, Y, radius : byte; fillMode, state : boolean);
(X, Y): center point of the circle
radius: radius of the circle
fillMode: 0 = not filled, 1 = filled
state: 0 = off, 1 = on

procedure Text(X, Y : byte; const St : string; state : boolean);
(X, Y): top left point of the text
St: the string to be displayed
state: 0 = off, 1 = on 

procedure CenteredText(const St : string; Y: BYTE; state: boolean);
St: the string to be displayed
Y: row on which to display it
state: 0 = off, 1 = on

procedure Negative;
Do a photographic negative of the entire screen: black <--> white

procedure Mirror;
Flip entire screen left to right

procedure Blind(speed : byte);
Venetian blind effect to clear entire screen.
speed: 1, 2 or 3 (slow, medium, fast)

procedure Wipe(speed : byte);
Wipe downward to clear entire screen.
 speed: 1, 2 or 3 (slow, medium, fast)

procedure DisplayBitmap(whichOne : byte; state : boolean);
Display one bitmap from the GLCD_Bitmaps library unit.
whichOne: the desired bitmap to display (0, 1, 2,...)
state: 0 = off, 1 = on }

As usual, be sure to peruse the source code for additional hints and tips.

Add Them to Your Library Collection

And here are the three new library units, "GLCD_alt.pas", "GLCD_Fonts" and "GLCD_Bitmap" all zipped together for you to download:

Be sure to read over the source codes for additional details on how to use them.

Try It Out

There are four exercises on this blog which can demonstrate these library units.  Go to them here

No comments:

Post a Comment