stk504_lcd.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00024 // Include files.
00025 #include "stk504_lcd.h" // Contains Prototypes, Segment Definitions, and __flash lookup tables
00026 #include "defines.h"            // Contains General Defines
00027 #include <iom3290.h>            // Contains device specific definitions
00028 #include <inavr.h>      // Included to be able to use intrinsic functions e.g. __delay_cycles();
00029 
00030 
00031 volatile union _LCD_status LCD_status = {0x01};      
00032 unsigned char LCD_timer = LCD_TIMER_SEED;       
00033 unsigned char LCD_displayData[LCD_REGISTER_COUNT];   
00034 
00036 __flash unsigned int LCD_character_table[] =
00037 {
00038         0x0000,         // '*' (?)
00039         0x0000,         // '+'
00040         0x0000,         // ',' (Not defined)
00041         0x0000,         // '-'
00042         0x0000,         // '.' (Not defined)
00043         0x0000,         // '/' (Not defined)
00044         0x93C5,         // '0'
00045         0x80C0,         // '1'
00046         0x1994,         // '2'
00047         0x9894,         // '3'
00048         0x8891,         // '4'
00049         0x9815,         // '5'
00050         0x9915,         // '6'
00051         0x8084,         // '7'
00052         0x9995,         // '8'
00053         0x9895,         // '9'
00054         0x0000,         // ':' (Not defined)
00055         0x0000,         // ';' (Not defined)
00056         0x0000,         // '<' (Not defined)
00057         0x0000,         // '=' (Not defined)
00058         0x0000,         // '>' (Not defined)
00059         0x0000,         // '?' (Not defined)
00060         0x0000,         // '@' (Not defined)
00061         0x8995,         // 'A' (+ 'a')
00062         0xB8A4,         // 'B' (+ 'b')
00063         0x1105,         // 'C' (+ 'c')
00064         0xB0A4,         // 'D' (+ 'd')
00065         0x1915,         // 'E' (+ 'e')
00066         0x0915,         // 'F' (+ 'f')
00067         0x9905,         // 'G' (+ 'g')
00068         0x8991,         // 'H' (+ 'h')
00069         0x2020,         // 'I' (+ 'i')
00070         0x9180,         // 'J' (+ 'j')
00071         0x0551,         // 'K' (+ 'k')
00072         0x1101,         // 'L' (+ 'l')
00073         0x81C3,         // 'M' (+ 'm')
00074         0x8583,         // 'N' (+ 'n')
00075         0x9185,         // 'O' (+ 'o')
00076         0x0995,         // 'P' (+ 'p')
00077         0x9585,         // 'Q' (+ 'q')
00078         0x0D95,         // 'R' (+ 'r')
00079         0x1406,         // 'S' (+ 's')
00080         0x2024,         // 'T' (+ 't')
00081         0x9181,         // 'U' (+ 'u')
00082         0x0341,         // 'V' (+ 'v')
00083         0x8781,         // 'W' (+ 'w')
00084         0x0642,         // 'X' (+ 'x')
00085         0x2042,         // 'Y' (+ 'y')
00086         0x1244,         // 'Z' (+ 'z')
00087         0x0000,         // '[' (Not defined)
00088         0x0000,         // '\' (Not defined)
00089         0x0000,         // ']' (Not defined)
00090         0x0000,         // '^' (Not defined)
00091         0x0000          // '_' (Not defined)
00092 };
00093 
00095 __flash unsigned char LCD_digit_table[] =
00096 {
00097         0xF0,           // '*' (Degree symbol)
00098         0x00,           // '+' (Not defined)
00099         0x00,           // ',' (Not defined)
00100         0x10,           // '-'
00101         0x00,           // '.' (Not defined)
00102         0x00,           // '/' (Not defined)
00103         0xEE,           // '0'
00104         0x44,           // '1'
00105         0xDA,           // '2'
00106         0xD6,           // '3'
00107         0x74,           // '4'
00108         0xB6,           // '5'
00109         0xBE,           // '6'
00110         0xC4,           // '7'
00111         0xFE,           // '8'
00112         0xF6,           // '9'
00113         0x00,           // ':' (Not defined)
00114         0x00,           // ';' (Not defined)
00115         0x00,           // '<' (Not defined)
00116         0x00,           // '=' (Not defined)
00117         0x00,           // '>' (Not defined)
00118         0x00,           // '?' (Not defined)
00119         0x00,           // '@' (Not defined)
00120         0xFC,           // 'A'
00121         0x3E,           // 'B'
00122         0xAA,           // 'C'
00123         0x5E,           // 'D'
00124         0xBA,           // 'E'
00125         0xB8,           // 'F'
00126 };      
00127 
00128 
00129 /******************************************************************************************
00130 *
00131 *       Function name : LCD_PutChar( unsigned char c, unsigned char digit )
00132 *
00133 ******************************************************************************************/
00134 void LCD_PutChar( unsigned char c, unsigned char digit )
00139 {
00140         unsigned int seg, segMask;
00141         unsigned char i;
00142         unsigned char mask, nibble, nibbleMask;
00143         unsigned char *ptr;
00144 
00145    if ( digit == 0 || digit >=8)
00146    {
00147       return; //digit is out og range.
00148    }
00149 
00150         //Lookup character table for segment data.
00151         if ( (c >= '*') && (c <= 'z') )
00152         {
00153                 if ( c >= 'a' ) c &= ~0x20; // c is in character_table. Convert to upper if necessarry.
00154                 c -= '*';
00155                 if ( c > 0x35 )
00156                 {
00157                    return;     // c points outside array.
00158                 }
00159                 else
00160                 {
00161                   seg = LCD_character_table[c];
00162                 }       
00163         }
00164         else
00165         {
00166           return;               //ASCII code out of range.
00167         }
00168 
00169         // Adjust mask according to digit
00170         segMask = 0x4008;  // masking out two bits not part of the segment.
00171 
00172         i = digit-1;            //i used as pointer offset.
00173         if ( i >= 8 )           //Test if LCD digit is out of range.
00174                 return;
00175         i >>= 1;
00176         ptr = LCD_displayData + i;      // Point to the first relevant LCDDR; i = {0,0,1,1,2,2}
00177 
00178         i = 4;                  //i used as loop counter.
00179         do
00180         {
00181           nibble = seg & 0x000F;
00182           nibbleMask = segMask & 0x000F;
00183                 
00184           seg >>= 4;
00185           segMask >>= 4;
00186         
00187           if ( digit & 0x01 )
00188           {
00189             mask = 0xF0 | nibbleMask;
00190           }
00191           else
00192           {
00193             nibble <<= 4;
00194             mask = 0x0F | ( nibbleMask <<4 );
00195           }
00196           *ptr = (*ptr & mask) | nibble;  //Write new bit values.
00197           ptr += 5;
00198         } while ( --i );
00199 }
00200 
00201 
00202 /******************************************************************************************
00203 *
00204 *       Function name : LCD_PutDigit( unsigned char c, unsigned char digit )
00205 *
00206 ******************************************************************************************/
00207 void LCD_PutDigit( unsigned char c, unsigned char digit )
00215 {
00216   unsigned char i, j, seg;
00217   unsigned char mask, lastnibblemask, lookupdata;
00218   unsigned char *ptr;
00219 
00220 //special case for digit = 0
00221   if (digit == 0)
00222   {
00223       LCD_SetSeg( G8, 0 );
00224       LCD_SetSeg( BC8, 0 );
00225       if ( c == '-' )
00226       {
00227          LCD_SetSeg( G8, 1 );
00228       }
00229       else
00230       {
00231          if ( c == '1' )
00232          {
00233             LCD_SetSeg ( BC8, 1 );
00234          }
00235       }
00236       return;
00237    }
00238 
00239     if ( (c >= '*') && (c <= 'F') && (digit <= 4))
00240     {
00241       c -= '*';                                         
00242       lookupdata = LCD_digit_table[c];    // c is in character_table.
00243     }
00244     else
00245     {
00246       return;                             // ASCII code out of range.
00247     }
00248 
00249     ptr = LCD_displayData + 19;           // Point to the first relevant LCDDR; 19, 14, 9, 4
00250 
00251     for (j=0; j<4 ;j++)                   // Read out the 4 half-nibbles from lookupdata.
00252     {
00253       mask = 0xC0;
00254       lastnibblemask = 0x40;
00255       seg = ( lookupdata & mask );        // Variable lookupdata contains:
00256                                           //   msb| A | B | F | G | E | C | D |   |lsb (7seg)
00257 
00258       //Shift half-nibble and masks into correct location.
00259       for (i = digit-1; i>0; i--)
00260       {
00261          seg >>= 2;
00262          mask >>= 2;
00263          lastnibblemask >>= 2;
00264       }
00265       if (j == 3) //need special mask for the last half nibble since it contains only one valid bit.
00266       {
00267          mask = mask & ~lastnibblemask;
00268       }
00269 
00270       *ptr = (*ptr & ~mask) | seg;  //Write new bit values.
00271                 ptr -= 5;
00272       lookupdata <<= 2;             //Prepare for next two bits.
00273    }
00274 }
00275 
00276 
00277 /******************************************************************************************
00278 *
00279 *       Function name : LCD_AllSegments( unsigned char input )
00280 *
00281 ******************************************************************************************/
00282 void LCD_AllSegments( unsigned char input )
00286 {
00287         unsigned char i;
00288         unsigned char *ptr;
00289 
00290         if( input )               // If input == TRUE
00291                 input = 0xFF;     // set segments to 0xFF.
00292                                   // (else set segments to 0x00)
00293         ptr = LCD_displayData;
00294         i = 20;
00295         do                        // Fill the display buffer.
00296         {
00297                 *ptr++ = input;   // Set/clear the bits in all LCD registers.
00298         } while ( --i );
00299 }
00300 
00301 
00302 
00303 /******************************************************************************************
00304 *
00305 *       Function name : LCD_SetSeg(unsigned char symbol, unsigned char input)
00306 *
00307 ******************************************************************************************/
00308 void LCD_SetSeg(unsigned char symbol, unsigned char input)
00313 {
00314   unsigned char offset;                 
00315   unsigned char setbit;
00316   unsigned char *ptr;
00317 
00318   // Symbol format = bbbnnnnn where b is bit[0..7] and n is offset[0..19]
00319   // Valid symbols are defined in stk504_lcd.h
00320   setbit = (symbol >> 5);
00321   offset = (symbol & 0x1F);
00322   if ( offset >= 20 )
00323   {
00324    return;  //data out of range of the LCD registers
00325   }
00326   ptr = LCD_displayData + offset;       // Point to the relevant LCDDR
00327   if ( input )
00328   {
00329       *ptr = (*ptr) | ( 1 << setbit);   // Set bit
00330   }
00331   else
00332   {
00333       *ptr = (*ptr) & ~( 1 << setbit);  // Clear bit
00334   }
00335 }
00336 
00337 
00338 /******************************************************************************************
00339 *
00340 *       Function name : LCD_BarSeg ( unsigned char value )
00341 *
00342 ******************************************************************************************/
00343 void LCD_BarSeg ( unsigned char value )
00347 {
00348   unsigned char mask, i, n, m;
00349   unsigned char *ptr;
00350   mask = 0x80;
00351 
00352   ptr = LCD_displayData + 18;   // Point to the first relevant LCDDR; i = {0,0,1,1,2,2}
00353 
00354   for(n=0; n<4 ; n++)
00355   {
00356     i=0;
00357     for(m=0; m<2; m++)
00358     {
00359       i |= ( value & mask );
00360       i >>= 1;
00361       value <<= 1;  // Shift next bits into position
00362     }
00363     // At this point high variable i high nibble contain  | 0 | sn | sn+1 | 0 | starting with LSBs
00364     *ptr = i | (*ptr & 0x9F);     // 0x9F is mask to erase old bit values in
00365     ptr -= 5;                     // next segment register.
00366   }
00367 }
00368 
00369 
00370 /******************************************************************************************
00371 *
00372 *       Function name : LCD_Update(void)
00373 *
00374 ******************************************************************************************/
00375 void LCD_Update(void)
00380 {
00381    unsigned char *src, *dest;
00382    unsigned char i;
00383 
00384    i = 20;
00385    dest = &pLCDREG;
00386    src = LCD_displayData;
00387    do
00388    {
00389       *dest++ = *src++;
00390    } while ( --i );
00391 }
00392 
00393 
00394 /******************************************************************************************
00395 *
00396 *       Function name : LCD_init(void)
00397 *
00398 ******************************************************************************************/
00399 void LCD_init(void)
00402 {
00403 
00404   LCD_AllSegments( FALSE );                     // Clear segment buffer.
00405   PRR &= ~(1<<PRLCD);            // Make sure LCD isn't disabled in power reduction register
00406   LCDCRA = (1<<LCDEN);                          // Enable LCD.
00407 
00408   LCD_CONTRAST_LEVEL(LCD_INITIAL_CONTRAST);     //Set the LCD contrast level.
00409 
00410 // Select asynchronous clock source, enable all COM pins and enable all segment pins.
00411   LCDCRB = (1<<LCDCS) | (1<<LCDMUX1) | (1<<LCDMUX0) | (1<<LCDPM3)| (1<<LCDPM2) | (1<<LCDPM1)| (1<<LCDPM0);
00412   LCDFRR = (1<<LCDPS0);                         // Set LCD prescaler to CLK(lcd)/64 = 64Hz.
00413 
00414   LCDCRA |= (1<<LCDIE);                         //Enable LCD_Start_frame interrupt.
00415 
00416 }
00417 
00418 
00419 /******************************************************************************
00420 *
00421 *   LCD Interrupt Routine
00422 *
00423 *******************************************************************************/
00424 #pragma vector = LCD_vect
00425 __interrupt void LCD_vect_interrupt( void )
00428 {
00429   unsigned char i;
00430   unsigned char *src, *dest;
00431 
00432   LCD_timer--;
00433   if( LCD_timer == 0 )
00434   {
00435     if( LCD_status.updateRequired == TRUE )
00436     {
00437 //      PINB = 0x40;
00438 
00439       LCD_timer = LCD_TIMER_SEED;
00440       LCD_status.updateComplete = TRUE;   // Set the ucLCD_ScrollReady to true.
00441       LCD_status.updateRequired = FALSE;  // No furter update necessary until
00442                                           //  another function changes buffer contents.
00443       // Latch display data buffer to I/O segment registers.
00444       i = 20;
00445       dest = &pLCDREG;
00446       src = LCD_displayData;
00447       do
00448       {
00449         *dest++ = *src++;
00450       } while ( --i );
00451     }
00452     else
00453     {
00454       LCD_timer = 1;                      //If LCD timer allows update of the LCD, but update is blocked
00455                                           // by LCD_status.updateRequired == FALSE the LCD_timer is preloaded
00456                                           // with smallest timer seed to ensure fastest LCD update.
00457       LCD_status.updateComplete = FALSE;  //Block for further access to the LCD_displayData until
00458                                           // LCD update has been performed.
00459     }
00460   }
00461 }
00462 
00463 // END //

Generated on Fri Feb 17 11:16:38 2006 for AVR063 LCD Driver for the STK504 by  doxygen 1.4.5