- 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 }