

   1.
      #define use_portb_lcd TRUE
   2.
       
   3.
      #define LCD_OFF 0x08
   4.
      #define CURSOR_ON 0x0E
   5.
      #define CURSOR_OFF 0x0C
   6.
      #define BLINK_ON 0x0D
   7.
      #define BLINK_OFF 0x0C
   8.
      #define SHIFT_LEFT 0x1C
   9.
      #define SHIFT_RIGHT 0x18
  10.
      #define CURSOR_RIGHT 0x14
  11.
      #define CURSOR_LEFT 0x10
  12.
      #define CGRAM 0x40
  13.
       
  14.
       
  15.
      struct lcd_pin_map {
  16.
                BOOLEAN rs;
  17.
                BOOLEAN rw;
  18.
                BOOLEAN enable;
  19.
                BOOLEAN unused;
  20.
                int     data : 4;
  21.
             } lcd;
  22.
       
  23.
       
  24.
      #if defined use_portb_lcd
  25.
        #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
  26.
        #define set_tris_lcd(x) set_tris_b(x)
  27.
      #else
  28.
        #locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
  29.
        #define set_tris_lcd(x) set_tris_d(x)
  30.
      #endif
  31.
       
  32.
       
  33.
      #define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
  34.
      #define lcd_line_two 0x40    // LCD RAM address for the second line
  35.
       
  36.
       
  37.
      BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
  38.
                                  // These bytes need to be sent to the LCD
  39.
                                  // to start it up.
  40.
       
  41.
       
  42.
                                  // The following are used for setting
  43.
                                  // the I/O port direction register.
  44.
       
  45.
      struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
  46.
      struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
  47.
       
  48.
       
  49.
       
  50.
      BYTE lcd_read_byte() {
  51.
           BYTE low,high;
  52.
           set_tris_lcd(LCD_READ);
  53.
           lcd.rw = 1;
  54.
           delay_cycles(1);
  55.
           lcd.enable = 1;
  56.
           delay_cycles(1);
  57.
           high = lcd.data;
  58.
           lcd.enable = 0;
  59.
           delay_cycles(1);
  60.
           lcd.enable = 1;
  61.
           delay_us(1);
  62.
           low = lcd.data;
  63.
           lcd.enable = 0;
  64.
           set_tris_lcd(LCD_WRITE);
  65.
           return( (high<<4) | low);
  66.
      }
  67.
       
  68.
       
  69.
      void lcd_send_nibble( BYTE n ) {
  70.
           lcd.data = n;
  71.
           delay_cycles(1);
  72.
           lcd.enable = 1;
  73.
           delay_us(2);
  74.
           lcd.enable = 0;
  75.
      }
  76.
       
  77.
       
  78.
      void lcd_send_byte( BYTE address, BYTE n ) {
  79.
       
  80.
           lcd.rs = 0;
  81.
           while ( bit_test(lcd_read_byte(),7) ) ;
  82.
           lcd.rs = address;
  83.
           delay_cycles(1);
  84.
           lcd.rw = 0;
  85.
           delay_cycles(1);
  86.
           lcd.enable = 0;
  87.
           lcd_send_nibble(n >> 4);
  88.
           lcd_send_nibble(n & 0xf);
  89.
      }
  90.
       
  91.
       
  92.
      void lcd_init() {
  93.
         BYTE i;
  94.
         set_tris_lcd(LCD_WRITE);
  95.
         lcd.rs = 0;
  96.
         lcd.rw = 0;
  97.
         lcd.enable = 0;
  98.
         delay_ms(15);
  99.
         for(i=1;i<=3;++i) {
 100.
            lcd_send_nibble(3);
 101.
            delay_ms(5);
 102.
         }
 103.
         lcd_send_nibble(2);
 104.
         for(i=0;i<=3;++i)
 105.
            lcd_send_byte(0,LCD_INIT_STRING[i]);
 106.
      }
 107.
       
 108.
       
 109.
      void lcd_gotoxy( BYTE x, BYTE y) {
 110.
        BYTE address;
 111.
       
 112.
        if(y!=1)
 113.
          address=lcd_line_two;
 114.
        else
 115.
          address=0;
 116.
        address+=x-1;
 117.
        lcd_send_byte(0,0x80|address);
 118.
      }
 119.
       
 120.
      void lcd_putc( char c) {
 121.
        switch (c) {
 122.
          case '\f'   : lcd_send_byte(0,1);
 123.
                        delay_ms(2);
 124.
                                                break;
 125.
          case '\n'   : lcd_gotoxy(1,2);        break;
 126.
          case '\b'   : lcd_send_byte(0,0x10);  break;
 127.
          default     : lcd_send_byte(1,c);     break;
 128.
        }
 129.
      }
 130.
       
 131.
      char lcd_getc( BYTE x, BYTE y) {
 132.
        char value;
 133.
       
 134.
         lcd_gotoxy(x,y);
 135.
         while ( bit_test(lcd_read_byte(),7) );
 136.
         lcd.rs=1;
 137.
         value = lcd_read_byte();
 138.
         lcd.rs=0;
 139.
         return(value);
 140.
      }
 141.
       
 142.
      void lcd_command(byte cmd)
 143.
      {
 144.
      lcd_send_byte(0, cmd);
 145.
      }