Alternate LCD Library Unit

This is a slightly extended PMP library unit to manipulate a text LCD. There are only three minor differences from the stock unit provided with PMP and this new one, described below.

To be clear, this newish unit, called "LCD_alt.pas" is an extension of "LCD.pas" which you already have in your installation. You should be able to run any older programs you've written with it, plus many new ones to take advantage of its additional features.


First, I reformatted the code, and corrected English spellings and grammar to make it easier to read. I hope this might encourage you to extend things further.

The remaining two changes deal with the LCD initialization. If you poke around various electronic forums, you will discover dozens and dozens of folks wondering why their LCD displays are only showing a top row of black boxes. The reason is that the unit isn't being properly initialized or that the timings aren't quite right.

First off, some older LCD displays (especially surplus ones that many DIY-ers use) might be sufficiently slow in their response to require longer delay times between commands. The culprits are almost always the delay times for the normal and home commands.

So, I added two conditional compilation features, one to set the normal  command delay constant, and the other to set the lengthier home command  delay constant. If not defined, then default values in the original library unit will be used. By passing in alternate values from the main program, the programmer need not change the library unit in any fashion. For example, you could use these in your main program:

{$DEFINE LCD_WAIT_DELAY_NORMAL 53} // microseconds
{$DEFINE LCD_WAIT_DELAY_HOME 3000} // microseconds

And then, the stock library unit can be made much more robust by following the suggestions in, "Character Mode Liquid Crystal Display Module Initialization by Instruction - 4-bit data interface" by Donald Weiman. Out of the countless sources I researched on the Web, this is the one which really nailed it for all LCD units.

I believe with these changes, simple as they are, that the alternate LCD library is now up to scratch with any text LCD

Compilation Constants

So you'll have everything in one place, here then are the compilation constants you can indicate in your programs (lifted from the stock PMP library unit source code):

Width definition:
LCD_WIDTH = n; default is 16; possible values are: 8, 16, 20, 32.

Number of lines:
LCD_LINES = n; default is 2; possible values are: 1, 2, 4.

Control port to use:
LCD_CTRL_PORT = port; default is GPIO for PIC10/12 and PORTB otherwise;  possible values are PORTA..PORTn, LATA..LATn.

The control bits are specified by:

LCD_BIT_RS = n; RS signal bit position; default is 4.

LCD_BIT_E = n; E signal bit position; default is 5.

LCD_BIT_WR = n; WR signal bit position (if used); default is 6.

Read mode is possible if WR is not permanently grounded:

LCD_READ; default is no. Forced as no if using a PIC10/PIC12.

Data bus width:
LCD_BITS = n; default is 4; possible values are: 4, 8.

If using the 4-bit data bus, then its position in the data port is given by:

LCD_4BITS_UPPER; default is lower bits.

Data port to use:
LCD_DATA_PORT = port; default is GPIO for PIC10/12, otherwise it is PORTB  if 4-bit mode, PORTC otherwise; possible values are PORTA..PORTn,

And with the two new defines mentioned above, we finally have:

WAIT_DELAY_NORMAL = n; in microseconds
LCD_WAIT_DELAY_HOME = n; in microseconds

Here's what a setup might look like in a real program:

{$DEFINE LCD_BITS 4}              // LCD in 4-bit mode
{$DEFINE LCD_WIDTH 16}            // LCD is 16 characters wide
{$DEFINE LCD_LINES 2}             // LCD is 2 lines high
{$DEFINE LCD_4BITS_UPPER}         // data on B.4 through B.7
{$DEFINE LCD_CTRL_PORT 'PORTB'}   // LCD control bits on PORTB
{$DEFINE LCD_BIT_RS 2}            // RS on B.2
{$DEFINE LCD_BIT_E 3}             // E on B.3


Here's a listing of all the commands available. Again, these write-ups are taken directly from the PMP source code.

procedure LCD_Init;
{ Initialize LCD system: must be called before any other operation }

procedure LCD_GotoXY(XPos, YPos: byte);
{ Cursor addressing (first line / column = 1); does not affect cursor on/off }

procedure LCD_Write_Char(Ch: char);
{ Write a character to LCD with row/col management (CR & LF managed too) }

procedure LCD_Clear;
{ Clear display and set cursor to home position (1, 1) }

procedure LCD_Clear_EOL;
 { Clear from current position to end of line }

procedure LCD_Clear_Line(YPos: byte);
{ Clear the given line number; sets the cursor to leftmost position (1) }

function LCD_X: byte;
{ Returns current X position }

function LCD_Y: byte;
{ Returns current Y position }

procedure LCD_Home;
 { Cursor to home position (1, 1); does not affect text }

Add It to Your Library Unit Collection

So here's the new library unit, "LCD_alt.pas" for you to download:

Be sure to read over the source code for additional details on how to use it. The next unit to be described, "A2D_alt.pas" gives a demo program you can try this out on if it's new to you. Click the link below to find it.

No comments:

Post a Comment