LCD Project (Source Code)
The following is the source code for the LCD Project article. Refer to the complete article for implementation details and explanations.
LCD.C
LCD Project - Source Code: LCD.C
/*
** LCD.C - Example program to demonstrate use of LCD_4X20.C
**
** Copyright 1996 by Randy Rasa
** http://ee.cleversoul.com/
**
** Version 1.00, 05-17-96
**
** These routines may be used in any way you see fit ... no strings attached.
*/
#include
#include
#include
#include
#include "lcd_4x20.h"
void DisplayScreen (char *ptr);
void DisplayScreenWipeOld (char *ptr);
/*
** main() -- program starts here ...
*/
void main (void) {
char done = 0;
printf("nnLCD_4X20 Demonstration Program, v1.00nn");
// initialize the LCD module
printf ("Initializing LCD ...");
LCD_Init();
// display a simple menu, which is used to demonstrate
// the operation of the LCD module
while (!done) {
LCD_Clear();
LCD_DisplayStringCentered (2, "Ready");
printf("nn");
printf("1. Sample Title Screenn");
printf("2. Sample Multi-Page Screenn");
printf("3. Sample Menun");
printf("4. Sample Marqueen");
printf("5. Sample Flashingn");
printf("5. Sample Bar Graphn");
printf("Esc = Exitn");
switch (getch()) {
//
// display sample title screen (with "wipe" effects)
//
case '1':
{
char screen[] = " LCD_4X20.C "
" Demonstration "
" Program "
" Version 1.00 ";
LCD_DisplayScreen(screen);
delay(2000);
}
{
char screen[] = " Copyright 1996 By "
" Randy Rasa "
" "
" Enjoy! ";
LCD_WipeOffLR();
LCD_WipeOnRL(screen);
delay(2000);
}
break;
//
// display sample mult-page screen (with "arrows")
//
case '2':
{
char screen1[] = "This is a sample "
"multi-page screen. "
"Note the arrow in "
"the corners, which 1";
char screen2[] = "indicate that there�"
"is more text avail- "
"able to be viewed, "
"by pressing the 1";
char screen3[] = "arrow keys. The �"
"arrows only show up "
"when more screens "
"can be accessed. 1";
char screen4[] = "When the last and/ �"
"or first screen is "
"reached, the arrow "
"disappears. ";
char screen = 1;
char exit = 0;
printf(" '+' = Up Arrow, '-' = Down Arrow, or Esc ...n");
while (!exit) {
switch (screen) {
case 1: LCD_DisplayScreen(screen1); break;
case 2: LCD_DisplayScreen(screen2); break;
case 3: LCD_DisplayScreen(screen3); break;
case 4: LCD_DisplayScreen(screen4); break;
}
switch (getch()) {
case 27:
exit = 1;
break;
case 0:
switch (getch()) {
case 0x50:
screen++;
if (screen>4) screen = 4;
break;
case 0x48:
screen--;
if (screen<1) screen = 1;
break;
}
break;
default:
printf("code: %xn", getch());
}
}
}
break;
//
// display sample menu system
//
case '3':
{
char screen1[] = "---- MAIN MENU -----"
"~Option Number 1 "
" Option Number 2 "
" Option Number 3 1";
char screen2[] = "---- MAIN MENU -----"
" Option Number 1 "
"~Option Number 2 "
" Option Number 3 1";
char screen3[] = "---- MAIN MENU -----"
" Option Number 1 "
" Option Number 2 "
"~Option Number 3 1";
char screen4[] = "---- MAIN MENU -----"
" Option Number 2 �"
" Option Number 3 "
"~Option Number 4 1";
char screen5[] = "---- MAIN MENU -----"
" Option Number 3 �"
" Option Number 4 "
"~Option Number 5 ";
char screen = 1;
char exit = 0;
printf(" '+' = Up Arrow, '-' = Down Arrow, or Esc ...n");
LCD_CursorOn();
while (!exit) {
switch (screen) {
case 1: LCD_DisplayScreen(screen1); LCD_Cursor(2,1); break;
case 2: LCD_DisplayScreen(screen2); LCD_Cursor(3,1); break;
case 3: LCD_DisplayScreen(screen3); LCD_Cursor(4,1); break;
case 4: LCD_DisplayScreen(screen4); LCD_Cursor(4,1); break;
case 5: LCD_DisplayScreen(screen5); LCD_Cursor(4,1); break;
}
switch (getch()) {
case 27:
exit = 1;
break;
case 0:
switch (getch()) {
case 0x50:
screen++;
if (screen>5) screen = 5;
break;
case 0x48:
screen--;
if (screen<1) screen = 1;
break;
}
break;
default:
printf("code: %xn", getch());
}
}
LCD_CursorOff();
}
break;
//
// display sample "marquee"
//
case '4':
{
char screen[] = " "
"The top line of this"
"screen should be "
"scrolling away ... ";
char longline[] = " This is a very long line of text, "
"scrolling across the screen like a marquee. ";
char i = 0;
LCD_DisplayScreen(screen);
printf("Press any key to stop ...n");
while (!kbhit()) {
LCD_DisplayRow(1, longline + i++);
if (i > (strlen(longline)-20)) i = 0;
delay(250);
}
getch();
}
break;
//
// display sample "flashing"
//
case '5':
{
char screen1[] = "Use flashing text "
"to attract attention"
"to a word or phrase."
" Different Flashing ";
char screen2[] = "Use text "
"to attract attention"
"to a word or phrase."
"377377377377377"
"377377377377377"
"377377377377377"
"377377377377377";
while (!kbhit()) {
LCD_DisplayScreen(screen1);
delay(250);
LCD_DisplayScreen(screen2);
delay(250);
}
getch();
}
break;
//
// display sample "bar graph"
//
case '6':
{
char screen[] = " Sample Bar Graph "
" "
" "
"LO HI";
char bars[6] = { ' ', 0x04, 0x05, 0x06, 0x07, 0xff };
LCD_DisplayScreen(screen);
printf("Press any key to stop ...n");
while (!kbhit()) {
char i, j;
for (i=1; i<21; i++) { // ramp up
for (j=1; j<6; j++) {
LCD_Cursor(3,i);
LCD_DisplayCharacter(bars[j]);
delay(10);
}
}
for (i=20; i>=1; i--) { // ramp down
for (j=5; j>=1; j--) {
LCD_Cursor(3,i);
LCD_DisplayCharacter(bars[j-1]);
delay(10);
}
}
}
getch();
}
break;
//
// display "bye" message and exit
//
case 27:
LCD_Clear();
LCD_DisplayStringCentered (1, "Bye Now!");
LCD_DisplayStringCentered (3, "Ya'll Come Back Now, Hear?");
LCD_DisplayStringCentered (4, "Hear?");
done = 1;
break;
}
}
}
LCD_4X20.C
/*
** LCD.C -- 4x20 LCD Control Routines
**
** Copyright 1996 by Randy Rasa
** http://ee.cleversoul.com/
**
** Version 1.00, 05-17-96
**
** These routines may be used in any way you see fit ... no strings attached.
**
*/
#include "lcd_4x20.h"
#include
#include
/*
** Define user-defined character dot patterns
*/
const unsigned char LCD_CHAR_BAR1[] = {
0x10, // ---10000
0x10, // ---10000
0x10, // ---10000
0x10, // ---10000
0x10, // ---10000
0x10, // ---10000
0x10, // ---10000
0x10 // ---10000
};
const unsigned char LCD_CHAR_BAR2[] = {
0x18, // ---11000
0x18, // ---11000
0x18, // ---11000
0x18, // ---11000
0x18, // ---11000
0x18, // ---11000
0x18, // ---11000
0x18 // ---11000
};
const unsigned char LCD_CHAR_BAR3[] = {
0x1c, // ---11100
0x1c, // ---11100
0x1c, // ---11100
0x1c, // ---11100
0x1c, // ---11100
0x1c, // ---11100
0x1c, // ---11100
0x1c // ---11100
};
const unsigned char LCD_CHAR_BAR4[] = {
0x1e, // ---11110
0x1e, // ---11110
0x1e, // ---11110
0x1e, // ---11110
0x1e, // ---11110
0x1e, // ---11110
0x1e, // ---11110
0x1e // ---11110
};
const unsigned char LCD_CHAR_BAR5[] = {
0x1f, // ---11111
0x1f, // ---11111
0x1f, // ---11111
0x1f, // ---11111
0x1f, // ---11111
0x1f, // ---11111
0x1f, // ---11111
0x1f // ---11111
};
const unsigned char LCD_CHAR_UP_ARROW[] = {
0x1f, // ---11111
0x1b, // ---11011
0x11, // ---10001
0x0a, // ---01010
0x1b, // ---11011
0x1b, // ---11011
0x1b, // ---11011
0x1f // ---11111
};
const unsigned char LCD_CHAR_DOWN_ARROW[] = {
0x1f, // ---11111
0x1b, // ---11011
0x1b, // ---11011
0x1b, // ---11011
0x0a, // ---01010
0x11, // ---10001
0x1b, // ---11011
0x1f // ---11111
};
const unsigned char LCD_CHAR_TRADEMARK_T[] = {
0x1f, // ---11111
0x04, // ---00100
0x04, // ---00100
0x04, // ---00100
0x00, // ---00000
0x00, // ---00000
0x00, // ---00000
0x00 // ---00000
};
const unsigned char LCD_CHAR_TRADEMARK_M[] = {
0x11, // ---10001
0x1b, // ---11011
0x15, // ---10101
0x11, // ---10001
0x00, // ---00000
0x00, // ---00000
0x00, // ---00000
0x00 // ---00000
};
/*
** Local (Module-Level) Function Prototypes
*/
static void LCD_InitDriver (void);
static void LCD_WriteControl (unsigned char data);
static void LCD_WriteData (unsigned char data);
/* -------------------- High-Level LCD Routines ------------------------ */
/*
** LCD_Init: Initialize the LCD.
*/
void LCD_Init (void)
{
LCD_InitDriver();
LCD_Clear();
LCD_CursorOff();
//
// load user-defined characters into LCD
//
LCD_DefineChar (0, LCD_CHAR_UP_ARROW);
LCD_DefineChar (1, LCD_CHAR_DOWN_ARROW);
LCD_DefineChar (2, LCD_CHAR_TRADEMARK_T);
LCD_DefineChar (3, LCD_CHAR_TRADEMARK_M);
LCD_DefineChar (4, LCD_CHAR_BAR1);
LCD_DefineChar (5, LCD_CHAR_BAR2);
LCD_DefineChar (6, LCD_CHAR_BAR3);
LCD_DefineChar (7, LCD_CHAR_BAR4);
}
/*
** LCD_Clear: Clear the LCD screen (also homes cursor).
*/
void LCD_Clear (void)
{
LCD_WriteControl(0x01);
}
/*
** LCD_Home: Position the LCD cursor at row 1, col 1.
*/
void LCD_Home (void)
{
LCD_WriteControl(0x02);
}
/*
** LCD_DisplayCharacter: Display a single character,
** at the current cursor location.
*/
void LCD_DisplayCharacter (char a_char)
{
LCD_WriteData (a_char);
}
/*
** LCD_DisplayString: Display a string at the specified row and column.
*/
void LCD_DisplayString (char row, char column, char *string)
{
LCD_Cursor (row, column);
while (*string)
LCD_DisplayCharacter (*string++);
}
/*
** LCD_DisplayStringCentered: Display a string centered on the specified row.
*/
void LCD_DisplayStringCentered (char row, char *string)
{
char len = strlen (string);
if (len <= 20) {
// if the string is less than one line, center it ...
char i;
LCD_Cursor (row, 1);
for (i=0; i<20; i++)
LCD_DisplayCharacter (' ');
LCD_DisplayString(row,((20 - len) / 2)+1,string);
}
else {
// if the string is more than one line, display first 20 characters
char temp[21];
strncpy(temp, string, 20);
temp[20] = 0;
LCD_DisplayString(row,1,temp);
}
}
/*
** LCD_Cursor: Position the LCD cursor at "row", "column".
*/
void LCD_Cursor (char row, char column)
{
switch (row) {
case 1: LCD_WriteControl (0x80 + column - 1); break;
case 2: LCD_WriteControl (0xc0 + column - 1); break;
case 3: LCD_WriteControl (0x94 + column - 1); break;
case 4: LCD_WriteControl (0xd4 + column - 1); break;
default: break;
}
}
/*
** LCD_DisplayScreen: Display an entire screen (80 characters).
**
** inputs: ptr = pointer to a string containing the entire screen
**
** example:
** char screen[] = "01234567890123456789"
** " This is a test of "
** "LCD_DisplayScreen()."
** " How's it look? ";
** DisplayScreen(screen);
**
*/
void LCD_DisplayScreen (char *ptr)
{
LCD_DisplayRow(1,ptr+ 0);
LCD_DisplayRow(2,ptr+20);
LCD_DisplayRow(3,ptr+40);
LCD_DisplayRow(4,ptr+60);
}
/*
** LCD_WipeOnLR: Display an entire screen (80 characters) by
** "wiping" it on (left to right).
**
** inputs: ptr = pointer to a string containing the entire screen
**
*/
void LCD_WipeOnLR (char *ptr)
{
// "wipe" on new screen
char i;
for (i=0; i<20; i++) {
LCD_Cursor(1,i+1);
LCD_DisplayCharacter(*(ptr+ 0+i));
LCD_Cursor(2,i+1);
LCD_DisplayCharacter(*(ptr+20+i));
LCD_Cursor(3,i+1);
LCD_DisplayCharacter(*(ptr+40+i));
LCD_Cursor(4,i+1);
LCD_DisplayCharacter(*(ptr+60+i));
}
}
/*
** LCD_WipeOnLR: Display an entire screen (80 characters) by
** "wiping" it on (right to left).
**
** inputs: ptr = pointer to a string containing the entire screen
**
*/
void LCD_WipeOnRL (char *ptr)
{
// "wipe" on new screen
char i;
for (i=20; i>0; i--) {
LCD_Cursor(1,i);
LCD_DisplayCharacter(*(ptr+ 0+i-1));
LCD_Cursor(2,i);
LCD_DisplayCharacter(*(ptr+20+i-1));
LCD_Cursor(3,i);
LCD_DisplayCharacter(*(ptr+40+i-1));
LCD_Cursor(4,i);
LCD_DisplayCharacter(*(ptr+60+i-1));
}
}
/*
** LCD_WipeOffLR: "Wipe" screen left-to-right.
*/
void LCD_WipeOffLR (void)
{
// "wipe" off old screen (left to right)
char i;
for (i=1; i<21; i++) {
#define BLOCK 0xff
LCD_Cursor(1,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(2,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(3,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(4,i);
LCD_DisplayCharacter(BLOCK);
}
}
/*
** LCD_WipeOffRL: "Wipe" screen right-to-left.
*/
void LCD_WipeOffRL (void)
{
// "wipe" off old screen (right to left)
char i;
for (i=20; i>0; i--) {
#define BLOCK 0xff
LCD_Cursor(1,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(2,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(3,i);
LCD_DisplayCharacter(BLOCK);
LCD_Cursor(4,i);
LCD_DisplayCharacter(BLOCK);
}
}
/*
** LCD_DisplayRow: Display a string at the specified row.
*/
void LCD_DisplayRow (char row, char *string)
{
char i;
LCD_Cursor (row, 1);
for (i=0; i<20; i++)
LCD_DisplayCharacter (*string++);
}
/*
** LCD_CursorLeft: Move the cursor left by one character.
*/
void LCD_CursorLeft (void)
{
LCD_WriteControl (0x10);
}
/*
** LCD_CursorRight: Move the cursor right by one character.
*/
void LCD_CursorRight (void)
{
LCD_WriteControl (0x14);
}
/*
** LCD_CursorOn: Turn the cursor on.
*/
void LCD_CursorOn (void)
{
LCD_WriteControl (0x0d);
}
/*
** LCD_CursorOff: Turn the cursor off.
*/
void LCD_CursorOff (void)
{
LCD_WriteControl (0x0c);
}
/*
** LCD_DisplayOff: Turn Off LCD.
*/
void LCD_DisplayOff (void)
{
LCD_WriteControl(0x08);
}
/*
** LCD_DisplayOn: Turn On LCD.
*/
void LCD_DisplayOn (void)
{
LCD_WriteControl(0x0c);
}
/*
** LCD_DefineCharacter: Define dot pattern for user-defined character.
**
** inputs: address = address of character (0x00-0x07)
** pattern = pointer to 8-byte array containing the dot pattern
*/
void LCD_DefineChar (char address, const unsigned char *pattern)
{
char i;
LCD_WriteControl(0x40 + (address << 3));
for (i=0; i<8; i++) {
LCD_WriteData(*pattern++);
}
}
/* -------------------- Low-Level LCD Routines ------------------------ */
/*
** Define addresses of LCD hardware.
**
** LPT1 = 0x0378
** LPT2 = 0x0278
*/
#define LPT 0x0378
#define LCD_DATA_ADDRESS LPT+0
#define LCD_CONTROL_ADDRESS LPT+2
/*
** LCD_InitDriver: Initialize the LCD driver.
*/
static void LCD_InitDriver (void)
{
LCD_WriteControl(0x38);
LCD_WriteControl(0x38);
LCD_WriteControl(0x38);
LCD_WriteControl(0x06);
LCD_WriteControl(0x0c);
}
/*
** LCD_WriteControl: Write a control instruction to the LCD
*/
static void LCD_WriteControl (unsigned char data)
{
outport(LCD_CONTROL_ADDRESS,0x03); // RS=0, R/W=0, E=0
outport(LCD_DATA_ADDRESS,data);
outport(LCD_CONTROL_ADDRESS,0x02); // RS=0, R/W=0, E=1
outport(LCD_CONTROL_ADDRESS,0x03); // RS=0, R/W=0, E=0
outport(LCD_CONTROL_ADDRESS,0x01); // RS=0, R/W=1, E=0
delay(10); // 10ms delay
}
/*
** LCD_WriteData: Write one byte of data to the LCD
*/
static void LCD_WriteData (unsigned char data)
{
outport(LCD_CONTROL_ADDRESS,0x07); // RS=1, R/W=0, E=0
outport(LCD_DATA_ADDRESS,data);
outport(LCD_CONTROL_ADDRESS,0x06); // RS=1, R/W=0, E=1
outport(LCD_CONTROL_ADDRESS,0x07); // RS=1, R/W=0, E=0
outport(LCD_CONTROL_ADDRESS,0x05); // RS=1, R/W=1, E=0
delay(1); // 1ms delay
}
LCD_4X20.H
/*
** LCD_4X20.H -- 4x20 LCD Routines
**
** Version 1.00, 05-17-96
**
*/
#ifndef __LCD_H
#define __LCD_H
void LCD_Init (void);
void LCD_DefineChar (char address, const unsigned char *pattern);
void LCD_DisplayOff (void);
void LCD_DisplayOn (void);
void LCD_Clear (void);
void LCD_Home (void);
void LCD_Cursor (char row, char column);
void LCD_CursorLeft (void);
void LCD_CursorRight (void);
void LCD_CursorOn (void);
void LCD_CursorOff (void);
void LCD_DisplayCharacter (char a_char);
void LCD_DisplayString (char row, char column, char *string);
void LCD_DisplayStringCentered (char row, char *string);
void LCD_DisplayScreen (char *ptr);
void LCD_DisplayRow (char row, char *string);
void LCD_WipeOnLR (char *ptr);
void LCD_WipeOnRL (char *ptr);
void LCD_WipeOffLR (void);
void LCD_WipeOffRL (void);
#endif
This source code is provided as-is, with no warranties or guarantees.