Main Page   Data Structures   File List   Data Fields   Globals  

lcd.c

Go to the documentation of this file.
00001 /*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'lcd.c'
00005 // Title        : Character LCD driver for HD44780/SED1278 displays
00006 //                  (usable in mem-mapped, or I/O mode)
00007 // Author       : Pascal Stang
00008 // Created      : 11/22/2000
00009 // Revised      : 4/30/2002
00010 // Version      : 1.1
00011 // Target MCU   : Atmel AVR series
00012 // Editor Tabs  : 4
00013 //
00014 // This code is distributed under the GNU Public License
00015 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00016 //
00017 //*****************************************************************************
00018 
00019 #include <avr/io.h>
00020 #include <avr/pgmspace.h>
00021 
00022 #include "global.h"
00023 
00024 #include "lcd.h"
00025 
00026 // custom LCD characters
00027 static unsigned char __attribute__ ((progmem)) LcdCustomChar[] =
00028 {
00029     0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
00030     0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
00031     0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
00032     0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
00033     0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
00034     0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
00035     0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
00036     0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block
00037     0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars
00038     0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow
00039     0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow
00040     0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow
00041     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character
00042     0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00, // 13. animated play icon frame 0
00043     0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00, // 14. animated play icon frame 1
00044     0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00, // 15. animated play icon frame 2
00045     0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00, // 16. animated play icon frame 3
00046 };
00047 
00048 /*************************************************************/
00049 /********************** LOCAL FUNCTIONS **********************/
00050 /*************************************************************/
00051 
00052 #define LCD_DELAY       asm volatile ("nop"); asm volatile ("nop")
00053 
00054 void lcdInitHW(void)
00055 {
00056     // initialize I/O ports
00057     // if I/O interface is in use
00058 #ifdef LCD_PORT_INTERFACE
00059     // initialize LCD control lines
00060     cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00061     cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00062     cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00063     // initialize LCD control lines to output
00064     sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
00065     sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
00066     sbi(LCD_CTRL_DDR, LCD_CTRL_E);
00067     // initialize LCD data port to input
00068     // initialize LCD data lines to pull-up
00069     #ifdef LCD_DATA_4BIT
00070         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);     // set data I/O lines to input (4bit)
00071         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00072     #else
00073         outb(LCD_DATA_DDR, 0x00);                       // set data I/O lines to input (8bit)
00074         outb(LCD_DATA_POUT, 0xFF);                      // set pull-ups to on (8bit)
00075     #endif
00076 #endif
00077 }
00078 
00079 void lcdBusyWait(void)
00080 {
00081     // wait until LCD busy bit goes to zero
00082     // do a read from control register
00083 #ifdef LCD_PORT_INTERFACE
00084     cbi(LCD_CTRL_PORT, LCD_CTRL_RS);                // set RS to "control"
00085     #ifdef LCD_DATA_4BIT
00086         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
00087         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00088     #else
00089         outb(LCD_DATA_DDR, 0x00);                   // set data I/O lines to input (8bit)
00090         outb(LCD_DATA_POUT, 0xFF);                  // set pull-ups to on (8bit)
00091     #endif
00092     sbi(LCD_CTRL_PORT, LCD_CTRL_RW);                // set R/W to "read"
00093     sbi(LCD_CTRL_PORT, LCD_CTRL_E);                 // set "E" line
00094     LCD_DELAY;                              // wait
00095     while(inp(LCD_DATA_PIN) & 1<<LCD_BUSY)
00096     {
00097         cbi(LCD_CTRL_PORT, LCD_CTRL_E);     // clear "E" line
00098         LCD_DELAY;                                  // wait
00099         LCD_DELAY;                                  // wait
00100         sbi(LCD_CTRL_PORT, LCD_CTRL_E);     // set "E" line
00101         LCD_DELAY;                                  // wait
00102         LCD_DELAY;                                  // wait
00103         #ifdef LCD_DATA_4BIT                        // do an extra clock for 4 bit reads
00104             cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00105             LCD_DELAY;                              // wait
00106             LCD_DELAY;                              // wait
00107             sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00108             LCD_DELAY;                              // wait
00109             LCD_DELAY;                              // wait
00110         #endif
00111     }
00112     cbi(LCD_CTRL_PORT, LCD_CTRL_E);         // clear "E" line
00113     //  leave data lines in input mode so they can be most easily used for other purposes
00114 #else
00115     // memory bus read
00116     // sbi(MCUCR, SRW);         // enable RAM waitstate
00117     // wait until LCD busy bit goes to zero
00118     while(*(volatile unsigned char *) (LCD_CTRL_ADDR) & 1<<LCD_BUSY);
00119     // cbi(MCUCR, SRW);         // disable RAM waitstate
00120 #endif
00121 }
00122 
00123 void lcdControlWrite(u08 data) 
00124 {
00125 // write the control byte to the display controller
00126 #ifdef LCD_PORT_INTERFACE
00127     lcdBusyWait();                          // wait until LCD not busy
00128     cbi(LCD_CTRL_PORT, LCD_CTRL_RS);            // set RS to "control"
00129     cbi(LCD_CTRL_PORT, LCD_CTRL_RW);            // set R/W to "write"
00130     #ifdef LCD_DATA_4BIT
00131         // 4 bit write
00132         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00133         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
00134         outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );  // output data, high 4 bits
00135         LCD_DELAY;                              // wait
00136         LCD_DELAY;                              // wait
00137         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00138         LCD_DELAY;                              // wait
00139         LCD_DELAY;                              // wait
00140         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00141         outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );    // output data, low 4 bits
00142         LCD_DELAY;                              // wait
00143         LCD_DELAY;                              // wait
00144         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00145     #else
00146         // 8 bit write
00147         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00148         outb(LCD_DATA_DDR, 0xFF);               // set data I/O lines to output (8bit)
00149         outb(LCD_DATA_POUT, data);              // output data, 8bits
00150         LCD_DELAY;                              // wait
00151         LCD_DELAY;                              // wait
00152         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00153     #endif
00154     //  leave data lines in input mode so they can be most easily used for other purposes
00155     #ifdef LCD_DATA_4BIT
00156         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);     // set data I/O lines to input (4bit)
00157         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00158     #else
00159         outb(LCD_DATA_DDR, 0x00);           // set data I/O lines to input (8bit)
00160         outb(LCD_DATA_POUT, 0xFF);          // set pull-ups to on (8bit)
00161     #endif
00162 #else
00163     // memory bus write
00164     sbi(MCUCR, SRW);            // enable RAM waitstate
00165     lcdBusyWait();              // wait until LCD not busy
00166     *(volatile unsigned char *) (LCD_CTRL_ADDR) = data;
00167     cbi(MCUCR, SRW);            // disable RAM waitstate
00168 #endif
00169 }
00170 
00171 u08 lcdControlRead(void)
00172 {
00173 // read the control byte from the display controller
00174     register u08 data;
00175 #ifdef LCD_PORT_INTERFACE
00176     lcdBusyWait();              // wait until LCD not busy
00177     #ifdef LCD_DATA_4BIT
00178         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);     // set data I/O lines to input (4bit)
00179         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00180     #else
00181         outb(LCD_DATA_DDR, 0x00);           // set data I/O lines to input (8bit)
00182         outb(LCD_DATA_POUT, 0xFF);          // set pull-ups to on (8bit)
00183     #endif
00184     cbi(LCD_CTRL_PORT, LCD_CTRL_RS);        // set RS to "control"
00185     sbi(LCD_CTRL_PORT, LCD_CTRL_RW);        // set R/W to "read"
00186     #ifdef LCD_DATA_4BIT
00187         // 4 bit read
00188         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00189         LCD_DELAY;                      // wait
00190         LCD_DELAY;                      // wait
00191         data = inb(LCD_DATA_PIN)&0xF0;  // input data, high 4 bits
00192         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00193         LCD_DELAY;                      // wait
00194         LCD_DELAY;                      // wait
00195         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00196         LCD_DELAY;                      // wait
00197         LCD_DELAY;                      // wait
00198         data |= inb(LCD_DATA_PIN)>>4;   // input data, low 4 bits
00199         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00200     #else
00201         // 8 bit read
00202         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00203         LCD_DELAY;                      // wait
00204         LCD_DELAY;                      // wait
00205         data = inb(LCD_DATA_PIN);       // input data, 8bits
00206         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00207     #endif
00208     //  leave data lines in input mode so they can be most easily used for other purposes
00209 #else
00210     sbi(MCUCR, SRW);            // enable RAM waitstate
00211     lcdBusyWait();              // wait until LCD not busy
00212     data = *(volatile unsigned char *) (LCD_CTRL_ADDR);
00213     cbi(MCUCR, SRW);            // disable RAM waitstate
00214 #endif
00215     return data;
00216 }
00217 
00218 void lcdDataWrite(u08 data) 
00219 {
00220 // write a data byte to the display
00221 #ifdef LCD_PORT_INTERFACE
00222     lcdBusyWait();                          // wait until LCD not busy
00223     sbi(LCD_CTRL_PORT, LCD_CTRL_RS);        // set RS to "data"
00224     cbi(LCD_CTRL_PORT, LCD_CTRL_RW);        // set R/W to "write"
00225     #ifdef LCD_DATA_4BIT
00226         // 4 bit write
00227         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00228         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
00229         outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );  // output data, high 4 bits
00230         LCD_DELAY;                              // wait
00231         LCD_DELAY;                              // wait
00232         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00233         LCD_DELAY;                              // wait
00234         LCD_DELAY;                              // wait
00235         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00236         outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );    // output data, low 4 bits
00237         LCD_DELAY;                              // wait
00238         LCD_DELAY;                              // wait
00239         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00240     #else
00241         // 8 bit write
00242         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00243         outb(LCD_DATA_DDR, 0xFF);           // set data I/O lines to output (8bit)
00244         outb(LCD_DATA_POUT, data);          // output data, 8bits
00245         LCD_DELAY;                              // wait
00246         LCD_DELAY;                              // wait
00247         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00248     #endif
00249     //  leave data lines in input mode so they can be most easily used for other purposes
00250     #ifdef LCD_DATA_4BIT
00251         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);     // set data I/O lines to input (4bit)
00252         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00253     #else
00254         outb(LCD_DATA_DDR, 0x00);           // set data I/O lines to input (8bit)
00255         outb(LCD_DATA_POUT, 0xFF);          // set pull-ups to on (8bit)
00256     #endif
00257 #else
00258     // memory bus write
00259     sbi(MCUCR, SRW);            // enable RAM waitstate
00260     lcdBusyWait();              // wait until LCD not busy
00261     *(volatile unsigned char *) (LCD_DATA_ADDR) = data;
00262     cbi(MCUCR, SRW);            // disable RAM waitstate
00263 #endif
00264 }
00265 
00266 u08 lcdDataRead(void)
00267 {
00268 // read a data byte from the display
00269     register u08 data;
00270 #ifdef LCD_PORT_INTERFACE
00271     lcdBusyWait();              // wait until LCD not busy
00272     #ifdef LCD_DATA_4BIT
00273         outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);     // set data I/O lines to input (4bit)
00274         outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);   // set pull-ups to on (4bit)
00275     #else
00276         outb(LCD_DATA_DDR, 0x00);           // set data I/O lines to input (8bit)
00277         outb(LCD_DATA_POUT, 0xFF);          // set pull-ups to on (8bit)
00278     #endif
00279     sbi(LCD_CTRL_PORT, LCD_CTRL_RS);        // set RS to "data"
00280     sbi(LCD_CTRL_PORT, LCD_CTRL_RW);        // set R/W to "read"
00281     #ifdef LCD_DATA_4BIT
00282         // 4 bit read
00283         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00284         LCD_DELAY;                              // wait
00285         LCD_DELAY;                              // wait
00286         data = inb(LCD_DATA_PIN)&0xF0;  // input data, high 4 bits
00287         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00288         LCD_DELAY;                              // wait
00289         LCD_DELAY;                              // wait
00290         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00291         LCD_DELAY;                              // wait
00292         LCD_DELAY;                              // wait
00293         data |= inb(LCD_DATA_PIN)>>4;           // input data, low 4 bits
00294         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00295     #else
00296         // 8 bit read
00297         sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00298         LCD_DELAY;                              // wait
00299         LCD_DELAY;                              // wait
00300         data = inb(LCD_DATA_PIN);           // input data, 8bits
00301         cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00302     #endif
00303     //  leave data lines in input mode so they can be most easily used for other purposes
00304 #else
00305     // memory bus read
00306     sbi(MCUCR, SRW);            // enable RAM waitstate
00307     lcdBusyWait();              // wait until LCD not busy
00308     data = *(volatile unsigned char *) (LCD_DATA_ADDR);
00309     cbi(MCUCR, SRW);            // disable RAM waitstate
00310 #endif
00311     return data;
00312 }
00313 
00314 
00315 
00316 /*************************************************************/
00317 /********************* PUBLIC FUNCTIONS **********************/
00318 /*************************************************************/
00319 
00320 void lcdInit()
00321 {
00322     // initialize hardware
00323     lcdInitHW();
00324     // LCD function set
00325     lcdControlWrite(LCD_FUNCTION_DEFAULT);
00326     // clear LCD
00327     lcdControlWrite(1<<LCD_CLR);
00328     // set entry mode
00329     lcdControlWrite(1<<LCD_ENTRY_MODE | 1<<LCD_ENTRY_INC);
00330     // set display to on
00331     //lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY | 1<<LCD_ON_BLINK);
00332     lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY );
00333     // move cursor to home
00334     lcdControlWrite(1<<LCD_HOME);
00335     // set data address to 0
00336     lcdControlWrite(1<<LCD_DDRAM | 0x00);
00337 
00338     // load the first 8 custom characters
00339     lcdLoadCustomChar((u08*)LcdCustomChar,0,0);
00340     lcdLoadCustomChar((u08*)LcdCustomChar,1,1);
00341     lcdLoadCustomChar((u08*)LcdCustomChar,2,2);
00342     lcdLoadCustomChar((u08*)LcdCustomChar,3,3);
00343     lcdLoadCustomChar((u08*)LcdCustomChar,4,4);
00344     lcdLoadCustomChar((u08*)LcdCustomChar,5,5);
00345     lcdLoadCustomChar((u08*)LcdCustomChar,6,6);
00346     lcdLoadCustomChar((u08*)LcdCustomChar,7,7);
00347 }
00348 
00349 void lcdHome(void)
00350 {
00351     // move cursor to home
00352     lcdControlWrite(1<<LCD_HOME);
00353 }
00354 
00355 void lcdClear(void)
00356 {
00357     // clear LCD
00358     lcdControlWrite(1<<LCD_CLR);
00359 }
00360 
00361 void lcdGotoXY(u08 x, u08 y)
00362 {
00363     register u08 DDRAMAddr;
00364 
00365     // remap lines into proper order
00366     switch(y)
00367     {
00368     case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
00369     case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
00370     case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
00371     case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
00372     default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
00373     }
00374 
00375     // set data address
00376     lcdControlWrite(1<<LCD_DDRAM | DDRAMAddr);
00377 }
00378 
00379 void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum)
00380 {
00381     register u08 i;
00382     u08 saveDDRAMAddr;
00383 
00384     // backup the current cursor position
00385     saveDDRAMAddr = lcdControlRead() & 0x7F;
00386 
00387     // multiply the character index by 8
00388     lcdCharNum = (lcdCharNum<<3);   // each character occupies 8 bytes
00389     romCharNum = (romCharNum<<3);   // each character occupies 8 bytes
00390 
00391     // copy the 8 bytes into CG (character generator) RAM
00392     for(i=0; i<8; i++)
00393     {
00394         // set CG RAM address
00395         lcdControlWrite((1<<LCD_CGRAM) | (lcdCharNum+i));
00396         // write character data
00397         lcdDataWrite( PRG_RDB(lcdCustomCharArray+romCharNum+i) );
00398     }
00399 
00400     // restore the previous cursor position
00401     lcdControlWrite(1<<LCD_DDRAM | saveDDRAMAddr);
00402 
00403 }
00404 
00405 void lcdPrintData(char* data, u08 nBytes)
00406 {
00407     register u08 i;
00408 
00409     // check to make sure we have a good pointer
00410     if (!data) return;
00411 
00412     // print data
00413     for(i=0; i<nBytes; i++)
00414     {
00415         lcdDataWrite(data[i]);
00416     }
00417 }
00418 
00419 void lcdProgressBar(u16 progress, u16 maxprogress, u08 length)
00420 {
00421     u08 i;
00422     u16 pixelprogress;
00423     u08 c;
00424 
00425     // draw a progress bar displaying (progress / maxprogress)
00426     // starting from the current cursor position
00427     // with a total length of "length" characters
00428     // ***note, LCD chars 0-5 must be programmed as the bar characters
00429     // char 0 = empty ... char 5 = full
00430 
00431     // total pixel length of bargraph equals length*PROGRESSPIXELS_PER_CHAR;
00432     // pixel length of bar itself is
00433     pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
00434     
00435     // print exactly "length" characters
00436     for(i=0; i<length; i++)
00437     {
00438         if( ((i*PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
00439         {
00440             // this is a partial or empty block
00441             if( ((i*PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
00442             {
00443                 // this is an empty block
00444                 // use space character?
00445                 c = 0;
00446             }
00447             else
00448             {
00449                 // this is a partial block
00450                 c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
00451             }
00452         }
00453         else
00454         {
00455             // this is a full block
00456             c = 5;
00457         }
00458         
00459         // write character to display
00460         lcdDataWrite(c);
00461     }
00462 
00463 }
00464 

Generated on Tue Feb 4 20:18:37 2003 for Procyon AVRlib by doxygen1.3-rc2