• Main Page
  • Related Pages
  • Files
  • File List
  • Globals

lcd.c

Go to the documentation of this file.
00001 
00015 #include <avr/io.h>
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 #include <util/delay.h>
00020 #include "lcd.h"
00021 #include "buzzer.h"
00022 
00023 #define DISPLAY_bp 4
00024 #define BACKLIGHT_bp 5
00025 
00027 char display_buffer[LCD_ROWS][LCD_COLS+1];
00028 
00030 char input_buffer[LCD_ROWS][INPUT_BUFFER_SIZE+1]= { 
00031         "********************\0",
00032         "**  UART-Display  **\0",
00033         "**by Ernst Abrazzo**\0",
00034         "********************\0"
00035         };
00036 
00038 uint8_t buffer_index=0;
00039 
00041 uint8_t char_index=0;
00042 
00044 uint8_t formfeed=0;
00045 
00047 uint8_t escape=0;
00048 
00050 uint8_t bell=0;
00051 
00053 uint8_t firstchar=0;
00054 
00056 uint8_t scroll=0;
00057 
00059 char remap[256] = {
00060           0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
00061          16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
00062          32,  33,  34,  35, 162,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
00063          48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
00064         160,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
00065          80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90, 250, 251, 252,  29, 196,
00066          96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
00067         112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 253, 254, 255, 206, 127,
00068         128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
00069         144, 145, 146, 147, 148, 149,  45,  45, 152, 153, 154, 155, 156, 157, 158, 159,
00070         160,  40, 162,  64, 164, 163, 254,  95, 168, 169, 170, 171, 172, 173, 174, 175,
00071         128, 140, 130, 131, 180, 143, 182, 183, 184, 185, 186, 187, 139, 138, 190,  96,
00072         192, 193, 194, 195,  91, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
00073         208, 209, 210, 211, 212, 213,  92, 215, 216, 217, 218, 219,  94, 221, 222, 190,
00074         127, 225, 226, 227, 123, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
00075         240, 125, 242, 243, 244, 245, 124, 247, 248, 249, 250, 251, 126, 253, 254, 255
00076 };
00077 
00078 void print_buffer(void) {
00079         uint8_t i;
00080         i=buffer_index;
00081 
00082         lcd_clear();
00083 
00084         if(scroll) {
00085                 #ifdef LCD_LINE1
00086                 lcd_setadr(LCD_LINE1);
00087                 lcd_puts(display_buffer[i]);
00088                 i=( (i+1) & 3);
00089                 #endif
00090                 
00091                 #ifdef LCD_LINE2
00092                 lcd_setadr(LCD_LINE2);
00093                 lcd_puts(display_buffer[i]);
00094                 i=( (i+1) & 3);
00095                 #endif
00096                 
00097                 #ifdef LCD_LINE3
00098                 lcd_setadr(LCD_LINE3);
00099                 lcd_puts(display_buffer[i]);
00100                 i=( (i+1) & 3);
00101                 #endif
00102                 
00103                 #ifdef LCD_LINE4
00104                 lcd_setadr(LCD_LINE4);
00105                 lcd_puts(display_buffer[i]);
00106                 #endif
00107 
00108         } else {        
00109                 #ifdef LCD_LINE1
00110                 lcd_setadr(LCD_LINE1);
00111                 lcd_puts(input_buffer[i]);
00112                 i=( (i+1) & 3);
00113                 #endif
00114                 
00115                 #ifdef LCD_LINE2
00116                 lcd_setadr(LCD_LINE2);
00117                 lcd_puts(input_buffer[i]);
00118                 i=( (i+1) & 3);
00119                 #endif
00120                 
00121                 #ifdef LCD_LINE3
00122                 lcd_setadr(LCD_LINE3);
00123                 lcd_puts(input_buffer[i]);
00124                 i=( (i+1) & 3);
00125                 #endif
00126                 
00127                 #ifdef LCD_LINE4
00128                 lcd_setadr(LCD_LINE4);
00129                 lcd_puts(input_buffer[i]);
00130                 #endif
00131         }
00132 }
00133 
00134 void lcd_scroll(void) {
00135         static uint8_t line[4]={0,0,0,0};
00136         
00137         uint8_t i=0;
00138         uint8_t tmp,len;
00139         
00140         for(i=0; i<4; i++) {
00141                 
00142                 len = strlen(input_buffer[i]);
00143                 
00144                 if(len<LCD_COLS) {
00145                         line[i]=0;
00146                 }
00147                 
00148                 tmp = strlcpy(display_buffer[i], input_buffer[i]+line[i], LCD_COLS+1);
00149                 
00150                 if(len>LCD_COLS) {
00151                         line[i]++;
00152                         line[i] = line[i]%len;
00153                         if(tmp<LCD_COLS) {
00154                                 strlcpy(display_buffer[i]+tmp,input_buffer[i], LCD_COLS-tmp+1);
00155                         }
00156                 }
00157         }
00158         print_buffer();
00159 }
00160 
00169 void push_char(uint8_t data) {
00170         if(scroll) {
00171                 if(char_index<INPUT_BUFFER_SIZE) {
00172                         input_buffer[buffer_index][char_index] = data;
00173                         char_index++;
00174                 }
00175         } else {
00176                 if(char_index<LCD_COLS) {
00177                         input_buffer[buffer_index][char_index] = data;
00178                         char_index++;
00179                 } else {
00180                         input_buffer[buffer_index][char_index-1] = 0x15;
00181                 }
00182         }
00183         formfeed=0;
00184         firstchar=0;
00185 }
00186 
00187 int lcd_putchar(char data, FILE *stream) {
00188         if(formfeed) {                                                  // Formfeed introduces special sequences consisting of \f (formfeed)
00189                                                                                         // and two following ASCI-Symbols, in order to dipslay symbols
00190                                                                                         // which are not available on keyboard
00191                 switch(firstchar) {                             
00192                         case 0:                                                 // 
00193                                 firstchar = data;
00194                                 break;
00195                         
00196                         case '<':
00197                                 switch(data) {
00198                                         case '-':                               // \f<- : Pfeil nach links
00199                                                 push_char(0xE1);        
00200                                                 break;
00201                                         case '|':                               // \f<| : Return-Zeichen
00202                                                 push_char(0x1C);
00203                                                 break;
00204                                         case 'b':                               // \f<b : Dicker Pfeil nach links
00205                                                 push_char(0x11);
00206                                                 break;
00207                                         case '<':                               // \f<< : Doppelpfeil nach links
00208                                                 push_char(0x14);
00209                                                 break;
00210                                                 
00211                                         default:        
00212                                                 push_char('A'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00213                                                 break;
00214                                 }
00215                                 break;
00216                                 
00217                         case '>':
00218                                 switch(data) {
00219                                         case 'b':                               // \f>b : Dicker Pfeil nach rechts
00220                                                 push_char(0x10);
00221                                                 break;
00222                                         case '>':                               // \f>> : Doppelpfeil nach rechts
00223                                                 push_char(0x15);
00224                                                 break;
00225                                                 
00226                                         default:        
00227                                                 push_char('B'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00228                                                 break;
00229                                 }
00230                                 break;
00231                         
00232                         case '^':
00233                                 switch(data) {
00234                                         case '|':                               // \f^| : Pfeil nach oben
00235                                                 push_char(0xDE);
00236                                                 break;
00237                                         case '\\':                              // \f^\\ : Pfeil nach links-oben
00238                                                 push_char(0x16);
00239                                                 break;
00240                                         case '^':                               // \f^^ : Doppelfpeil nach oben
00241                                                 push_char(0x12);
00242                                                 break;  
00243                                         case 'b':                               // \f^b : Dicker Pfeil nach oben
00244                                                 push_char(0x1A);
00245                                                 break;
00246                                         case '0':                               // \f^* : Hochgestellte Ziffer
00247                                         case '1':                               
00248                                         case '2':
00249                                         case '3':
00250                                         case '4':
00251                                         case '5':
00252                                         case '6':
00253                                         case '7':
00254                                         case '8':
00255                                         case '9':
00256                                                 push_char(0x80-'0'+data);
00257                                                 break;
00258                                                 
00259                                                 
00260                                         default:
00261                                                 push_char('C'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00262                                                 break;
00263                                 }
00264                                 break;
00265                         
00266                         case 'v':
00267                                 switch(data) {
00268                                         case '|':                               // \fv| : Pfeil nach unten
00269                                                 push_char(0xE0);
00270                                                 break;
00271                                         case '/':                               // \fv/ : Pfeil nach links-unten
00272                                                 push_char(0x18);
00273                                                 break;
00274                                         case 'v':                               // \fvv : Doppelpfeil nach unten
00275                                                 push_char(0x13);
00276                                                 break;
00277                                         case 'b':                               // \fvb : Dicker Pfeil nach unten
00278                                                 push_char(0x1B);
00279                                                 break;
00280                                         
00281                                         default: 
00282                                                 push_char('D'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00283                                                 break;
00284                                 }
00285                                 break;
00286                         
00287                         case '/':
00288                                 switch(data) {
00289                                         case '^':                               // \f/^ : Pfeil nach rechts-oben
00290                                                 push_char(0x17);
00291                                                 break;
00292                                         
00293                                         default: 
00294                                                 push_char('E'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00295                                                 break;
00296                                 }
00297                                 break;
00298                         
00299                         case '\\':                                              
00300                                 switch(data) {
00301                                         case 'v':                               // \f\\v : Pfeil nach rechts-unten
00302                                                 push_char(0x19);
00303                                                 break;
00304                                         
00305                                         default: 
00306                                                 push_char('F'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00307                                                 break;
00308                                 }
00309                                 break;
00310                         
00311                         case '-':                                               
00312                                 switch(data) {
00313                                         case '>':                               // \f-> : Pfeil nach rechts
00314                                                 push_char(0xDF);
00315                                                 break;
00316                                         
00317                                         default: 
00318                                                 push_char('G'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00319                                                 break;
00320                                 }
00321                                 break;
00322                                 
00323                         case '|':                                               
00324                                 switch(data) {
00325                                         case 'v':                               // \fv| : Pfeil nach unten
00326                                                 push_char(0xE0);
00327                                                 break;
00328                                         case '^':                               // \f^| : Pfeil nach oben
00329                                                 push_char(0xDE);
00330                                                 break;
00331                                         case '1':                               // \f|* : Progressbar
00332                                                 push_char(0xD4);        
00333                                                 break;
00334                                         case '2':
00335                                                 push_char(0xD3);
00336                                                 break;
00337                                         case '3':
00338                                                 push_char(0xD2);
00339                                                 break;
00340                                         case '4':
00341                                                 push_char(0xD1);
00342                                                 break;
00343                                         case '5':
00344                                                 push_char(0xD0);
00345                                                 break;
00346                                         
00347                                         default: 
00348                                                 push_char('H'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00349                                                 break;
00350                                 }
00351                                 break;
00352                                 
00353                         
00354                         default:        
00355                                 push_char('I'); // Müllzeichen aufs display schreiben, um zu signalisieren dass die Sequenz ungültig war
00356                                 break;
00357                 }
00358                                 
00359                 return 0;
00360         }
00361         
00362         if(escape) {                                                    // Escape-sequence (\e) introduces specialsequences consisting of \e and 
00363                                                                                         // one following ASCI-symbol, on order to control some display-properties.
00364                 switch(data) {
00365                         case 'S':                                               // \eS enables scrolling-mode for line-length above 20 (displayed) symbols
00366                                 scroll=1;
00367                                 escape=0;
00368                                 break;
00369                         case 's':                                               // \es disables scrolling-mode for line-length above 20 (displayed) symbols
00370                                 scroll=0;
00371                                 escape=0;
00372                                 break;                          
00373                         case 'i':                                               // \ei re-initilizes the display-IC
00374                                 lcd_init();
00375                                 _delay_ms(5);
00376                                 escape=0;
00377                                 break;
00378                                 
00379                         case 'L':                                               // \eL switch Backlight on
00380                                 PORTB &= ~(1<<BACKLIGHT_bp);
00381                                 escape=0;
00382                                 break;
00383                                 
00384                         case 'l':                                               // \el switch Backlight off
00385                                 PORTB |= (1<<BACKLIGHT_bp);
00386                                 escape=0;
00387                                 break;
00388                                 
00389                         default:                                                //  Handle non-valid escape-sequences
00390                                 escape=0;
00391                                 break;
00392                 }
00393                 return 0;
00394         }
00395         
00396         if(bell) {
00397                 switch(data){
00398                         case '1':
00399                                 buzzer_start(50);
00400                                 break;
00401                         case '2':
00402                                 buzzer_start(200);
00403                                 break;
00404                         case '3':
00405                                 buzzer_start(1000);
00406                                 break;
00407                 }
00408                 bell=0;
00409                 return 0;
00410         }
00411         
00412         switch(data) {                                                  // Handle all cases which can occure, if there has no special case happened bevore and a character is received. 
00413                 case '\r':                                                      // \r carriage return detected. Shift lines one lines to the top an insert received string into bottom line in the buffer.
00414                 case '\n':                                                      // \n so do,if newline detected. 
00415                         input_buffer[buffer_index][char_index] = 0;
00416                         buffer_index = ( (buffer_index +1) % LCD_ROWS );
00417                         char_index=0;
00418                         if(data=='\r') print_buffer();  // in addition to the commands above, print buffer to display in case of \r
00419                         break;
00420                         
00421                 case '\e':                                                      // \e escape-sequence detected
00422                         escape=1;
00423                         break;
00424                 case '\f':                                                      // \f formfeed-sequence detected
00425                         formfeed=1;
00426                         break;
00427                         
00428                 case '\a':                                                      // \a beep
00429                         bell=1;
00430                         break;
00431                         
00432                         
00433                 default:
00434                         push_char(remap[(uint8_t)data]);  // If none of the above mentioned exceptiones came true, remap received character. 
00435                         break;
00436         }
00437         
00438         return 0;
00439 }

Generated on Thu Feb 23 2012 13:31:37 for UartDisplay by  doxygen 1.7.2