RSS Feed Email Facebook Twitter Stumbleupon Google Bookmark

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.


blog comments powered by Disqus