| 1269 | 
        kakl | 
        1 | 
        /* --------------------------------------------------------------------------- | 
      
      
         | 
         | 
        2 | 
         * AVR_MLIB - HD 44780 LCD Display Driver | 
      
      
         | 
         | 
        3 | 
         * www.mlab.cz miho 2008 | 
      
      
         | 
         | 
        4 | 
         * --------------------------------------------------------------------------- | 
      
      
         | 
         | 
        5 | 
         * LCD display driver for standard Hitachi 1/2/4 line character LCD modules | 
      
      
         | 
         | 
        6 | 
         * for AVR processors. It uses 4 or 8 bit interface without readback. | 
      
      
         | 
         | 
        7 | 
         * In the Examples section there is a demo application for this library. | 
      
      
         | 
         | 
        8 | 
         * --------------------------------------------------------------------------- | 
      
      
         | 
         | 
        9 | 
         * 00.00 2008/03/28 First Version | 
      
      
         | 
         | 
        10 | 
         * --------------------------------------------------------------------------- | 
      
      
         | 
         | 
        11 | 
         */ | 
      
      
         | 
         | 
        12 | 
          | 
      
      
         | 
         | 
        13 | 
        #include "lcd_hd44780.h" | 
      
      
         | 
         | 
        14 | 
          | 
      
      
         | 
         | 
        15 | 
        // Check Defined Values and use Default Values if possible | 
      
      
         | 
         | 
        16 | 
        // ------------------------------------------------------- | 
      
      
         | 
         | 
        17 | 
        // 1 / 2 / 4 Line | 
      
      
         | 
         | 
        18 | 
        #ifndef LCD_CHARS | 
      
      
         | 
         | 
        19 | 
        	#if LCD_LINES > 2 | 
      
      
         | 
         | 
        20 | 
        		#error "LCD: Undefined LCD_CHARS" | 
      
      
         | 
         | 
        21 | 
        	#else | 
      
      
         | 
         | 
        22 | 
        		// Dafault Value | 
      
      
         | 
         | 
        23 | 
        		#define LCD_CHARS 20 | 
      
      
         | 
         | 
        24 | 
        	#endif | 
      
      
         | 
         | 
        25 | 
        #endif | 
      
      
         | 
         | 
        26 | 
          | 
      
      
         | 
         | 
        27 | 
        #ifndef LCD_LINE_1 | 
      
      
         | 
         | 
        28 | 
        	// Address of the 1st char on the 1st line | 
      
      
         | 
         | 
        29 | 
        	#define LCD_LINE_1	0 | 
      
      
         | 
         | 
        30 | 
        #endif | 
      
      
         | 
         | 
        31 | 
          | 
      
      
         | 
         | 
        32 | 
        #ifndef LCD_LINE_2 | 
      
      
         | 
         | 
        33 | 
        	// Address of the 1st char on the 2nd line | 
      
      
         | 
         | 
        34 | 
        	#define LCD_LINE_2	64			 | 
      
      
         | 
         | 
        35 | 
        #endif | 
      
      
         | 
         | 
        36 | 
          | 
      
      
         | 
         | 
        37 | 
        #ifndef LCD_LINE_3 | 
      
      
         | 
         | 
        38 | 
        	// Address of the 1st char on the 3rd line | 
      
      
         | 
         | 
        39 | 
        	#define LCD_LINE_3	LCD_CHARS	 | 
      
      
         | 
         | 
        40 | 
        #endif | 
      
      
         | 
         | 
        41 | 
          | 
      
      
         | 
         | 
        42 | 
        #ifndef LCD_LINE_4 | 
      
      
         | 
         | 
        43 | 
        	// Address of the 1st char on the 4th line | 
      
      
         | 
         | 
        44 | 
        	#define LCD_LINE_4	(LCD_LINE_2 + LCD_CHARS) | 
      
      
         | 
         | 
        45 | 
        #endif | 
      
      
         | 
         | 
        46 | 
          | 
      
      
         | 
         | 
        47 | 
        // Data Interface | 
      
      
         | 
         | 
        48 | 
        #if LCD_INTERFACE_BITS == 4 | 
      
      
         | 
         | 
        49 | 
        	#define LCD_DATA_MASK	(0x0F << LCD_DATA_BIT) | 
      
      
         | 
         | 
        50 | 
        #elif LCD_INTERFACE_BITS==8 | 
      
      
         | 
         | 
        51 | 
        	#define LCD_DATA_MASK	(0xFF << LCD_DATA_BIT) | 
      
      
         | 
         | 
        52 | 
        #else | 
      
      
         | 
         | 
        53 | 
        	#error "LCD: Wrong Value: LCD_INTERFACE_BITS" | 
      
      
         | 
         | 
        54 | 
        #endif | 
      
      
         | 
         | 
        55 | 
          | 
      
      
         | 
         | 
        56 | 
        #if LCD_DATA_MASK > 0xFF | 
      
      
         | 
         | 
        57 | 
        	#error "LCD: Value too Big: LCD_DATA_BIT" | 
      
      
         | 
         | 
        58 | 
        #endif | 
      
      
         | 
         | 
        59 | 
          | 
      
      
         | 
         | 
        60 | 
        #define LCD_E_PORT			PORT(LCD_E) | 
      
      
         | 
         | 
        61 | 
        #define LCD_E_DDR			DDR(LCD_E) | 
      
      
         | 
         | 
        62 | 
          | 
      
      
         | 
         | 
        63 | 
        #define LCD_RS_PORT			PORT(LCD_RS) | 
      
      
         | 
         | 
        64 | 
        #define LCD_RS_DDR			DDR(LCD_RS) | 
      
      
         | 
         | 
        65 | 
          | 
      
      
         | 
         | 
        66 | 
        #define LCD_DATA_PORT		PORT(LCD_DATA) | 
      
      
         | 
         | 
        67 | 
        #define LCD_DATA_DDR		DDR(LCD_DATA) | 
      
      
         | 
         | 
        68 | 
          | 
      
      
         | 
         | 
        69 | 
        #ifdef LCD_RW | 
      
      
         | 
         | 
        70 | 
        #define LCD_RW_PORT			PORT(LCD_RW) | 
      
      
         | 
         | 
        71 | 
        #define LCD_RW_DDR			DDR(LCD_RW) | 
      
      
         | 
         | 
        72 | 
        #endif | 
      
      
         | 
         | 
        73 | 
          | 
      
      
         | 
         | 
        74 | 
          | 
      
      
         | 
         | 
        75 | 
        // LCD Chip Commands | 
      
      
         | 
         | 
        76 | 
        // ----------------- | 
      
      
         | 
         | 
        77 | 
          | 
      
      
         | 
         | 
        78 | 
        // Comand Clear LCD Display | 
      
      
         | 
         | 
        79 | 
        #define LCD_HD44780_CLR 		0x01 | 
      
      
         | 
         | 
        80 | 
          | 
      
      
         | 
         | 
        81 | 
        // Command Home Cursor | 
      
      
         | 
         | 
        82 | 
        #define LCD_HD44780_HOME		0x02 | 
      
      
         | 
         | 
        83 | 
          | 
      
      
         | 
         | 
        84 | 
        // Command Entry Mode (increment/decrement, shift/no shift) | 
      
      
         | 
         | 
        85 | 
        #define LCD_HD44780_ENTMODE(inc, shift) \ | 
      
      
         | 
         | 
        86 | 
        	(0x04 | ((inc)? 0x02: 0) | ((shift)? 1: 0)) | 
      
      
         | 
         | 
        87 | 
          | 
      
      
         | 
         | 
        88 | 
        #define LCD_HD44780_ENTMODE_DEF		LCD_HD44780_ENTMODE(1,0)	// Increment Position, No Shift | 
      
      
         | 
         | 
        89 | 
          | 
      
      
         | 
         | 
        90 | 
        // Command Display Controll (display on/off, cursor on/off, cursor blinking on/off) | 
      
      
         | 
         | 
        91 | 
        #define LCD_HD44780_DISPCTL(disp, cursor, blink) \ | 
      
      
         | 
         | 
        92 | 
        	(0x08 | ((disp)? 0x04: 0) | ((cursor)? 0x02: 0) | ((blink)? 1: 0)) | 
      
      
         | 
         | 
        93 | 
          | 
      
      
         | 
         | 
        94 | 
        #define LCD_HD44780_CURSORON		LCD_HD44780_DISPCTL(1,1,0)	// on, cursor on,  | 
      
      
         | 
         | 
        95 | 
        #define LCD_HD44780_CURSOROFF		LCD_HD44780_DISPCTL(1,0,0)	// on, cursor off | 
      
      
         | 
         | 
        96 | 
          | 
      
      
         | 
         | 
        97 | 
        // Command Cursor or Display Shift (shift display/cursor, left/right) | 
      
      
         | 
         | 
        98 | 
        #define LCD_HD44780_SHIFT(shift, right) \ | 
      
      
         | 
         | 
        99 | 
        	(0x10 | ((shift)? 0x08: 0) | ((right)? 0x04: 0)) | 
      
      
         | 
         | 
        100 | 
          | 
      
      
         | 
         | 
        101 | 
        #define LCD_HD44780_CURSORLEFT		LCD_HD44780_SHIFT(0,0) | 
      
      
         | 
         | 
        102 | 
        #define LCD_HD44780_CURSORRIGHT		LCD_HD44780_SHIFT(0,1) | 
      
      
         | 
         | 
        103 | 
          | 
      
      
         | 
         | 
        104 | 
        // Command Function Set ( 4/8-bit interface / 1 or 2 lines ) | 
      
      
         | 
         | 
        105 | 
        #define LCD_HD44780_4BIT1LINE	0x20	// 4-bit 1-line  font 5x7 | 
      
      
         | 
         | 
        106 | 
        #define LCD_HD44780_4BIT2LINES	0x28	// 4-bit 2-lines font 5x7 | 
      
      
         | 
         | 
        107 | 
        #define LCD_HD44780_8BIT1LINE	0x30	// 8-bit 1-line  font 5x7 | 
      
      
         | 
         | 
        108 | 
        #define LCD_HD44780_8BIT2LINES	0x38	// 8-bit 2-lines font 5x7 | 
      
      
         | 
         | 
        109 | 
          | 
      
      
         | 
         | 
        110 | 
        // Select Apropriate Mode | 
      
      
         | 
         | 
        111 | 
        #if LCD_INTERFACE_BITS==4 | 
      
      
         | 
         | 
        112 | 
        	#if LCD_LINES == 1 | 
      
      
         | 
         | 
        113 | 
        		#define LCD_HD44780_FNSET	LCD_HD44780_4BIT1LINE	// 4-bit 1-line | 
      
      
         | 
         | 
        114 | 
        	#else | 
      
      
         | 
         | 
        115 | 
        		#define LCD_HD44780_FNSET	LCD_HD44780_4BIT2LINES	// 4-bit 2-lines | 
      
      
         | 
         | 
        116 | 
        	#endif | 
      
      
         | 
         | 
        117 | 
        #elif LCD_INTERFACE_BITS==8 | 
      
      
         | 
         | 
        118 | 
        	#if LCD_LINES == 1  | 
      
      
         | 
         | 
        119 | 
        		#define LCD_HD44780_FNSET	LCD_HD44780_8BIT1LINE	// 8-bit 1-line | 
      
      
         | 
         | 
        120 | 
        	#else | 
      
      
         | 
         | 
        121 | 
        		#define LCD_HD44780_FNSET	LCD_HD44780_8BIT2LINES	// 8-bit 2-lines | 
      
      
         | 
         | 
        122 | 
        	#endif | 
      
      
         | 
         | 
        123 | 
        #endif | 
      
      
         | 
         | 
        124 | 
          | 
      
      
         | 
         | 
        125 | 
          | 
      
      
         | 
         | 
        126 | 
        // User Defined Chars | 
      
      
         | 
         | 
        127 | 
        // ------------------ | 
      
      
         | 
         | 
        128 | 
          | 
      
      
         | 
         | 
        129 | 
        // Definitions only.  | 
      
      
         | 
         | 
        130 | 
        // Because these definitions may be sent to lcd via printf,  | 
      
      
         | 
         | 
        131 | 
        // it is impossible to contain 0 bytes (end of string in C)  | 
      
      
         | 
         | 
        132 | 
        // so we ored 0x80 to each byte | 
      
      
         | 
         | 
        133 | 
          | 
      
      
         | 
         | 
        134 | 
        #define LCD_CHAR_SPACE  "\x80\x80\x80\x80\x80\x80\x80\x80"      /* space (blank char)        */ | 
      
      
         | 
         | 
        135 | 
        #define LCD_CHAR_BAT100 "\x8E\x9F\x9F\x9F\x9F\x9F\x9F\x1F"      /* symbol battery full       */ | 
      
      
         | 
         | 
        136 | 
        #define LCD_CHAR_BAT50  "\x8E\x9F\x91\x91\x93\x97\x9F\x1F"      /* symbol baterry half       */ | 
      
      
         | 
         | 
        137 | 
        #define LCD_CHAR_BAT0   "\x8E\x9F\x91\x91\x91\x91\x91\x1F"      /* symbol baterry empty      */ | 
      
      
         | 
         | 
        138 | 
        #define LCD_CHAR_UP     "\x80\x84\x8E\x95\x84\x84\x84\x80"      /* symbol arrow up           */ | 
      
      
         | 
         | 
        139 | 
        #define LCD_CHAR_DOWN   "\x80\x84\x84\x84\x95\x8E\x84\x80"      /* symbol arrow down         */ | 
      
      
         | 
         | 
        140 | 
        #define LCD_CHAR_LUA    "\x84\x8E\x91\x91\x9F\x91\x91\x80"      /* A s carkou                */ | 
      
      
         | 
         | 
        141 | 
        #define LCD_CHAR_LLA    "\x81\x82\x8E\x81\x9F\x91\x8F\x80"      /* a s carkou                */ | 
      
      
         | 
         | 
        142 | 
        #define LCD_CHAR_HUC    "\x8A\x8E\x91\x90\x90\x91\x8E\x80"      /* C s hackem                */ | 
      
      
         | 
         | 
        143 | 
        #define LCD_CHAR_HLC    "\x8A\x84\x8E\x90\x90\x91\x8E\x80"      /* c s hackem                */ | 
      
      
         | 
         | 
        144 | 
        #define LCD_CHAR_HUD    "\x8A\x9C\x92\x91\x91\x92\x9C\x80"      /* D s hackem                */ | 
      
      
         | 
         | 
        145 | 
        #define LCD_CHAR_HLD    "\x85\x83\x8D\x93\x91\x91\x8F\x80"      /* d s hackem                */ | 
      
      
         | 
         | 
        146 | 
        #define LCD_CHAR_LUE    "\x84\x9F\x90\x90\x9E\x90\x9F\x80"      /* E s carkou                */ | 
      
      
         | 
         | 
        147 | 
        #define LCD_CHAR_LLE    "\x81\x82\x8E\x91\x9F\x90\x8E\x80"      /* e s carkou                */ | 
      
      
         | 
         | 
        148 | 
        #define LCD_CHAR_HUE    "\x8A\x9F\x90\x9E\x90\x90\x9F\x80"      /* E s hackem                */ | 
      
      
         | 
         | 
        149 | 
        #define LCD_CHAR_HLE    "\x8A\x84\x8E\x91\x9F\x90\x8E\x80"      /* e s hackem                */ | 
      
      
         | 
         | 
        150 | 
        #define LCD_CHAR_LUI    "\x84\x8E\x84\x84\x84\x84\x8E\x80"      /* I s carkou                */ | 
      
      
         | 
         | 
        151 | 
        #define LCD_CHAR_LLI    "\x82\x84\x80\x8C\x84\x84\x8E\x80"      /* i s carkou                */ | 
      
      
         | 
         | 
        152 | 
        #define LCD_CHAR_HUN    "\x8A\x95\x91\x99\x95\x93\x91\x80"      /* N s hackem                */ | 
      
      
         | 
         | 
        153 | 
        #define LCD_CHAR_HLN    "\x8A\x84\x96\x99\x91\x91\x91\x80"      /* n s hackem                */ | 
      
      
         | 
         | 
        154 | 
        #define LCD_CHAR_LUO    "\x84\x8E\x91\x91\x91\x91\x8E\x80"      /* O s carkou                */ | 
      
      
         | 
         | 
        155 | 
        #define LCD_CHAR_LLO    "\x82\x84\x8E\x91\x91\x91\x8E\x80"      /* o s carkou                */ | 
      
      
         | 
         | 
        156 | 
        #define LCD_CHAR_HUR    "\x8A\x9E\x91\x9E\x94\x92\x91\x80"      /* R s hackem                */ | 
      
      
         | 
         | 
        157 | 
        #define LCD_CHAR_HLR    "\x8A\x84\x96\x99\x90\x90\x90\x80"      /* r s hackem                */ | 
      
      
         | 
         | 
        158 | 
        #define LCD_CHAR_HUS    "\x8A\x8F\x90\x8E\x81\x81\x9E\x80"      /* S s hackem                */ | 
      
      
         | 
         | 
        159 | 
        #define LCD_CHAR_HLS    "\x8A\x84\x8E\x90\x8E\x81\x9E\x80"      /* s s hackem                */ | 
      
      
         | 
         | 
        160 | 
        #define LCD_CHAR_HUT    "\x8A\x9F\x84\x84\x84\x84\x84\x80"      /* T s hackem                */ | 
      
      
         | 
         | 
        161 | 
        #define LCD_CHAR_HLT    "\x8A\x8C\x9C\x88\x88\x89\x86\x80"      /* t s hackem                */ | 
      
      
         | 
         | 
        162 | 
        #define LCD_CHAR_LUU    "\x82\x95\x91\x91\x91\x91\x8E\x80"      /* U s carkou                */ | 
      
      
         | 
         | 
        163 | 
        #define LCD_CHAR_LLU    "\x82\x84\x91\x91\x91\x93\x8D\x80"      /* u s carkou                */ | 
      
      
         | 
         | 
        164 | 
        #define LCD_CHAR_CUU    "\x86\x97\x91\x91\x91\x91\x8E\x80"      /* U s krouzkem              */ | 
      
      
         | 
         | 
        165 | 
        #define LCD_CHAR_CLU    "\x86\x86\x91\x91\x91\x91\x8E\x80"      /* u s krouzkem              */ | 
      
      
         | 
         | 
        166 | 
        #define LCD_CHAR_LUY    "\x82\x95\x91\x8A\x84\x84\x84\x80"      /* Y s carkou                */ | 
      
      
         | 
         | 
        167 | 
        #define LCD_CHAR_LLY    "\x82\x84\x91\x91\x8F\x81\x8E\x80"      /* y s carkou                */ | 
      
      
         | 
         | 
        168 | 
        #define LCD_CHAR_HUZ    "\x8A\x9F\x81\x82\x84\x88\x9F\x80"      /* Z s hackem                */ | 
      
      
         | 
         | 
        169 | 
        #define LCD_CHAR_HLZ    "\x8A\x84\x9F\x82\x84\x88\x9F\x80"      /* z s hackem                */ | 
      
      
         | 
         | 
        170 | 
          | 
      
      
         | 
         | 
        171 | 
          | 
      
      
         | 
         | 
        172 | 
        // Program | 
      
      
         | 
         | 
        173 | 
        // ------- | 
      
      
         | 
         | 
        174 | 
          | 
      
      
         | 
         | 
        175 | 
          | 
      
      
         | 
         | 
        176 | 
        static int8_t lcd_posx;		// Mirror Register with Position X (1..LCD_CHARS) | 
      
      
         | 
         | 
        177 | 
        #if LCD_LINES > 1 | 
      
      
         | 
         | 
        178 | 
        static int8_t lcd_posy;		// Mirror Register with Position Y (1..LCD_LINES) | 
      
      
         | 
         | 
        179 | 
        #endif | 
      
      
         | 
         | 
        180 | 
          | 
      
      
         | 
         | 
        181 | 
          | 
      
      
         | 
         | 
        182 | 
        // Send a Nibble or Byte to the LCD COntroller | 
      
      
         | 
         | 
        183 | 
        static void | 
      
      
         | 
         | 
        184 | 
        lcd_send_nibble(uint8_t rs, uint8_t data) | 
      
      
         | 
         | 
        185 | 
        { | 
      
      
         | 
         | 
        186 | 
        	// Select Register or Data | 
      
      
         | 
         | 
        187 | 
        	if (rs) | 
      
      
         | 
         | 
        188 | 
        		LCD_RS_PORT |= (1<<LCD_RS_BIT); | 
      
      
         | 
         | 
        189 | 
         	else | 
      
      
         | 
         | 
        190 | 
        		LCD_RS_PORT &= ~(1<<LCD_RS_BIT); | 
      
      
         | 
         | 
        191 | 
          | 
      
      
         | 
         | 
        192 | 
        	// Put 4bit/8bit data | 
      
      
         | 
         | 
        193 | 
          	LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_DATA_MASK) | ((data<<LCD_DATA_BIT)&LCD_DATA_MASK); | 
      
      
         | 
         | 
        194 | 
         	_delay_us(1);	// Data Setup Time | 
      
      
         | 
         | 
        195 | 
          | 
      
      
         | 
         | 
        196 | 
        	// Click Enable on and off | 
      
      
         | 
         | 
        197 | 
        	LCD_E_PORT |= 1<<LCD_E_BIT; | 
      
      
         | 
         | 
        198 | 
         	_delay_us(1); | 
      
      
         | 
         | 
        199 | 
        	LCD_E_PORT &= ~(1<<LCD_E_BIT); | 
      
      
         | 
         | 
        200 | 
        	_delay_us(40); | 
      
      
         | 
         | 
        201 | 
        } | 
      
      
         | 
         | 
        202 | 
          | 
      
      
         | 
         | 
        203 | 
          | 
      
      
         | 
         | 
        204 | 
        // Send a Byte to the LCD Controller | 
      
      
         | 
         | 
        205 | 
        #if LCD_INTERFACE_BITS == 4 | 
      
      
         | 
         | 
        206 | 
        static void | 
      
      
         | 
         | 
        207 | 
        lcd_send_byte(uint8_t rs, uint8_t data) | 
      
      
         | 
         | 
        208 | 
        { | 
      
      
         | 
         | 
        209 | 
         	lcd_send_nibble(rs, data >> 4);		// High Order Data | 
      
      
         | 
         | 
        210 | 
         	lcd_send_nibble(rs, data);			// Low Order Data | 
      
      
         | 
         | 
        211 | 
        } | 
      
      
         | 
         | 
        212 | 
        #else | 
      
      
         | 
         | 
        213 | 
        	#define lcd_send_byte lcd_send_nibble | 
      
      
         | 
         | 
        214 | 
        #endif | 
      
      
         | 
         | 
        215 | 
          | 
      
      
         | 
         | 
        216 | 
          | 
      
      
         | 
         | 
        217 | 
        // Send a Command to the LCD Controller (RS=0) | 
      
      
         | 
         | 
        218 | 
        #define lcd_send_cmd(n)		lcd_send_byte(0, (n)) | 
      
      
         | 
         | 
        219 | 
          | 
      
      
         | 
         | 
        220 | 
          | 
      
      
         | 
         | 
        221 | 
        // Send a Data Byte to the LCD Controller (RS=1) | 
      
      
         | 
         | 
        222 | 
        #define lcd_send_data(n)	lcd_send_byte(1, (n)) | 
      
      
         | 
         | 
        223 | 
          | 
      
      
         | 
         | 
        224 | 
          | 
      
      
         | 
         | 
        225 | 
        // Goto Home | 
      
      
         | 
         | 
        226 | 
        void  | 
      
      
         | 
         | 
        227 | 
        lcd_home() | 
      
      
         | 
         | 
        228 | 
        { | 
      
      
         | 
         | 
        229 | 
        	lcd_send_cmd(LCD_HD44780_HOME);		// Zero Cursor Position and Offset | 
      
      
         | 
         | 
        230 | 
        	#if LCD_LINES > 1 | 
      
      
         | 
         | 
        231 | 
        		lcd_posx=lcd_posy=1; | 
      
      
         | 
         | 
        232 | 
        	#else | 
      
      
         | 
         | 
        233 | 
        		lcd_posx=1; | 
      
      
         | 
         | 
        234 | 
        	#endif | 
      
      
         | 
         | 
        235 | 
          	_delay_ms(2); | 
      
      
         | 
         | 
        236 | 
        } | 
      
      
         | 
         | 
        237 | 
          | 
      
      
         | 
         | 
        238 | 
          | 
      
      
         | 
         | 
        239 | 
        // Clear Display | 
      
      
         | 
         | 
        240 | 
        void  | 
      
      
         | 
         | 
        241 | 
        lcd_clear() | 
      
      
         | 
         | 
        242 | 
        { | 
      
      
         | 
         | 
        243 | 
        	lcd_send_cmd(LCD_HD44780_CLR);		// Clear Memory | 
      
      
         | 
         | 
        244 | 
          	_delay_ms(2); | 
      
      
         | 
         | 
        245 | 
        } | 
      
      
         | 
         | 
        246 | 
          | 
      
      
         | 
         | 
        247 | 
          | 
      
      
         | 
         | 
        248 | 
        // Switch Cursor On | 
      
      
         | 
         | 
        249 | 
        void | 
      
      
         | 
         | 
        250 | 
        lcd_cursor_on() | 
      
      
         | 
         | 
        251 | 
        { | 
      
      
         | 
         | 
        252 | 
        	lcd_send_cmd(LCD_HD44780_CURSORON); | 
      
      
         | 
         | 
        253 | 
        } | 
      
      
         | 
         | 
        254 | 
          | 
      
      
         | 
         | 
        255 | 
          | 
      
      
         | 
         | 
        256 | 
        // Switch Cursor Off | 
      
      
         | 
         | 
        257 | 
        void | 
      
      
         | 
         | 
        258 | 
        lcd_cursor_off() | 
      
      
         | 
         | 
        259 | 
        { | 
      
      
         | 
         | 
        260 | 
        	lcd_send_cmd(LCD_HD44780_CURSOROFF); | 
      
      
         | 
         | 
        261 | 
        } | 
      
      
         | 
         | 
        262 | 
          | 
      
      
         | 
         | 
        263 | 
          | 
      
      
         | 
         | 
        264 | 
        // Clear Display and Goto Home with no Cursor | 
      
      
         | 
         | 
        265 | 
        void | 
      
      
         | 
         | 
        266 | 
        lcd_clear_home() | 
      
      
         | 
         | 
        267 | 
        { | 
      
      
         | 
         | 
        268 | 
        	lcd_clear();		// Clear Memory | 
      
      
         | 
         | 
        269 | 
        	lcd_home();			// Zero Cursor Position and Offset | 
      
      
         | 
         | 
        270 | 
        	lcd_cursor_off();	// No Cursor | 
      
      
         | 
         | 
        271 | 
        } | 
      
      
         | 
         | 
        272 | 
          | 
      
      
         | 
         | 
        273 | 
          | 
      
      
         | 
         | 
        274 | 
        // Move to Position (1,1 is the first position) | 
      
      
         | 
         | 
        275 | 
        void lcd_gotoxy(uint8_t x, uint8_t y) | 
      
      
         | 
         | 
        276 | 
        { | 
      
      
         | 
         | 
        277 | 
        	uint8_t Adr; | 
      
      
         | 
         | 
        278 | 
          | 
      
      
         | 
         | 
        279 | 
        	Adr=x-1; | 
      
      
         | 
         | 
        280 | 
        	#if LCD_LINES > 1 | 
      
      
         | 
         | 
        281 | 
        	switch (y) | 
      
      
         | 
         | 
        282 | 
        	{ | 
      
      
         | 
         | 
        283 | 
        		case 2: | 
      
      
         | 
         | 
        284 | 
        			Adr+=LCD_LINE_2; | 
      
      
         | 
         | 
        285 | 
        			break; | 
      
      
         | 
         | 
        286 | 
        		#if LCD_LINES > 2 | 
      
      
         | 
         | 
        287 | 
        		case 3: | 
      
      
         | 
         | 
        288 | 
        			Adr+=LCD_LINE_3; | 
      
      
         | 
         | 
        289 | 
        			break; | 
      
      
         | 
         | 
        290 | 
        		case 4: | 
      
      
         | 
         | 
        291 | 
        			Adr+=LCD_LINE_4; | 
      
      
         | 
         | 
        292 | 
        			break; | 
      
      
         | 
         | 
        293 | 
        		#endif | 
      
      
         | 
         | 
        294 | 
        	} | 
      
      
         | 
         | 
        295 | 
        	#endif | 
      
      
         | 
         | 
        296 | 
          | 
      
      
         | 
         | 
        297 | 
        	lcd_send_cmd(0x80 | (Adr & 0x7F) ); | 
      
      
         | 
         | 
        298 | 
        	lcd_posx=x; | 
      
      
         | 
         | 
        299 | 
        	#if LCD_LINES > 1 | 
      
      
         | 
         | 
        300 | 
        	lcd_posy=y; | 
      
      
         | 
         | 
        301 | 
        	#endif | 
      
      
         | 
         | 
        302 | 
        } | 
      
      
         | 
         | 
        303 | 
          | 
      
      
         | 
         | 
        304 | 
          | 
      
      
         | 
         | 
        305 | 
        // Increment Position | 
      
      
         | 
         | 
        306 | 
        void  | 
      
      
         | 
         | 
        307 | 
        lcd_inc_pos() | 
      
      
         | 
         | 
        308 | 
        { | 
      
      
         | 
         | 
        309 | 
        	// Next Position | 
      
      
         | 
         | 
        310 | 
        	lcd_posx++; | 
      
      
         | 
         | 
        311 | 
          | 
      
      
         | 
         | 
        312 | 
        	// Correct End of Line | 
      
      
         | 
         | 
        313 | 
        	#if LCD_LINES == 1 | 
      
      
         | 
         | 
        314 | 
        		if (lcd_posx > 40) | 
      
      
         | 
         | 
        315 | 
        			lcd_posx = 1; | 
      
      
         | 
         | 
        316 | 
        	#elif LCD_LINES == 2 | 
      
      
         | 
         | 
        317 | 
        		if (lcd_posx > 40) | 
      
      
         | 
         | 
        318 | 
        		{ | 
      
      
         | 
         | 
        319 | 
        			lcd_posx = 1; | 
      
      
         | 
         | 
        320 | 
        			lcd_posy++;		// on the Next Line | 
      
      
         | 
         | 
        321 | 
        		} | 
      
      
         | 
         | 
        322 | 
        	#elif LCD_LINES > 2 | 
      
      
         | 
         | 
        323 | 
        		if ( ((lcd_posy & 1) && (lcd_posx > LCD_CHARS))	// Odd Lines are Short | 
      
      
         | 
         | 
        324 | 
        			|| (lcd_posx > 40-LCD_CHARS) )				// Memory is up to 40 Bytes | 
      
      
         | 
         | 
        325 | 
        		{ | 
      
      
         | 
         | 
        326 | 
        			lcd_posx = 1;	// Position 1 | 
      
      
         | 
         | 
        327 | 
        			lcd_posy++;		// on the Next Line | 
      
      
         | 
         | 
        328 | 
        		} | 
      
      
         | 
         | 
        329 | 
        	#endif | 
      
      
         | 
         | 
        330 | 
          | 
      
      
         | 
         | 
        331 | 
        	// Correct End of Last Line | 
      
      
         | 
         | 
        332 | 
        	#if LCD_LINES > 1 | 
      
      
         | 
         | 
        333 | 
        	if (lcd_posy > LCD_LINES) | 
      
      
         | 
         | 
        334 | 
        	{ | 
      
      
         | 
         | 
        335 | 
        		lcd_posy = 1; | 
      
      
         | 
         | 
        336 | 
        	} | 
      
      
         | 
         | 
        337 | 
        	#endif | 
      
      
         | 
         | 
        338 | 
        } | 
      
      
         | 
         | 
        339 | 
          | 
      
      
         | 
         | 
        340 | 
        // Decrement Position | 
      
      
         | 
         | 
        341 | 
        void | 
      
      
         | 
         | 
        342 | 
        lcd_dec_pos() | 
      
      
         | 
         | 
        343 | 
        { | 
      
      
         | 
         | 
        344 | 
        	// Correct Beginning of Line | 
      
      
         | 
         | 
        345 | 
        	if (--lcd_posx==0)						// Step Left | 
      
      
         | 
         | 
        346 | 
        	{										// If Beginning of the Line | 
      
      
         | 
         | 
        347 | 
        		#if LCD_LINES > 1 | 
      
      
         | 
         | 
        348 | 
        			if(--lcd_posy==0);				// Step Up | 
      
      
         | 
         | 
        349 | 
        				lcd_posy = LCD_LINES;		// If we are on Top Go to the Bottom | 
      
      
         | 
         | 
        350 | 
        		#endif | 
      
      
         | 
         | 
        351 | 
        		#if LCD_LINES <= 2 | 
      
      
         | 
         | 
        352 | 
        			lcd_posx = 40;				 | 
      
      
         | 
         | 
        353 | 
        		#else | 
      
      
         | 
         | 
        354 | 
        			if(lcd_posy & 1)				// If Odd Line (the Short One) | 
      
      
         | 
         | 
        355 | 
        				lcd_posx = LCD_CHARS;		// Set End of the Short Line | 
      
      
         | 
         | 
        356 | 
        			else							// Else | 
      
      
         | 
         | 
        357 | 
        				lcd_posx = 40-LCD_CHARS;	// Set End of Long Line | 
      
      
         | 
         | 
        358 | 
        		#endif | 
      
      
         | 
         | 
        359 | 
        	} | 
      
      
         | 
         | 
        360 | 
        } | 
      
      
         | 
         | 
        361 | 
          | 
      
      
         | 
         | 
        362 | 
        // Move Cursor Left | 
      
      
         | 
         | 
        363 | 
        void | 
      
      
         | 
         | 
        364 | 
        lcd_cursor_left() | 
      
      
         | 
         | 
        365 | 
        { | 
      
      
         | 
         | 
        366 | 
        	lcd_send_cmd(LCD_HD44780_CURSORLEFT); | 
      
      
         | 
         | 
        367 | 
        	lcd_dec_pos(); | 
      
      
         | 
         | 
        368 | 
        } | 
      
      
         | 
         | 
        369 | 
          | 
      
      
         | 
         | 
        370 | 
          | 
      
      
         | 
         | 
        371 | 
        // Move Cursor Right | 
      
      
         | 
         | 
        372 | 
        void | 
      
      
         | 
         | 
        373 | 
        lcd_cursor_right() | 
      
      
         | 
         | 
        374 | 
        { | 
      
      
         | 
         | 
        375 | 
        	lcd_send_cmd(LCD_HD44780_CURSORRIGHT); | 
      
      
         | 
         | 
        376 | 
        	lcd_inc_pos(); | 
      
      
         | 
         | 
        377 | 
        } | 
      
      
         | 
         | 
        378 | 
          | 
      
      
         | 
         | 
        379 | 
          | 
      
      
         | 
         | 
        380 | 
        // Init LCD Display | 
      
      
         | 
         | 
        381 | 
        void | 
      
      
         | 
         | 
        382 | 
        lcd_init(void) | 
      
      
         | 
         | 
        383 | 
        { | 
      
      
         | 
         | 
        384 | 
        	// Port Init Direction | 
      
      
         | 
         | 
        385 | 
        	LCD_E_PORT  &= ~_BV(LCD_E_BIT);			// Enable off | 
      
      
         | 
         | 
        386 | 
        	LCD_E_DDR  |= _BV(LCD_E_BIT);			// Enable as Output | 
      
      
         | 
         | 
        387 | 
          	LCD_RS_DDR |= _BV(LCD_RS_BIT);			// Register Select as Output | 
      
      
         | 
         | 
        388 | 
        	#ifdef LCD_RW | 
      
      
         | 
         | 
        389 | 
        		LCD_RW_DDR |= _BV(LCD_RW_BIT);		// Read Write as Output | 
      
      
         | 
         | 
        390 | 
        	#endif | 
      
      
         | 
         | 
        391 | 
            LCD_DATA_DDR |= LCD_DATA_MASK;			// Data as Output | 
      
      
         | 
         | 
        392 | 
          | 
      
      
         | 
         | 
        393 | 
        	// Initial Delay | 
      
      
         | 
         | 
        394 | 
          	_delay_ms(40);		// Delay for Vcc | 
      
      
         | 
         | 
        395 | 
          | 
      
      
         | 
         | 
        396 | 
        	// Sync 8/4 bit Interface | 
      
      
         | 
         | 
        397 | 
        	#if LCD_INTERFACE_BITS == 4 | 
      
      
         | 
         | 
        398 | 
        	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4);	// 8 bit mode - sync nibble/byte | 
      
      
         | 
         | 
        399 | 
          		_delay_ms(4.1); | 
      
      
         | 
         | 
        400 | 
        	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4); | 
      
      
         | 
         | 
        401 | 
          		_delay_us(100); | 
      
      
         | 
         | 
        402 | 
        	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4); | 
      
      
         | 
         | 
        403 | 
        		// Set 4 bit mode | 
      
      
         | 
         | 
        404 | 
          		lcd_send_nibble(0, LCD_HD44780_FNSET >> 4); | 
      
      
         | 
         | 
        405 | 
        	#elif  LCD_INTERFACE_BITS == 8 | 
      
      
         | 
         | 
        406 | 
        	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE);		// 8 bit mode - sync nibble/byte | 
      
      
         | 
         | 
        407 | 
          		_delay_ms(4.1); | 
      
      
         | 
         | 
        408 | 
        		lcd_send_nibble(0, LCD_HD44780_8BIT1LINE); | 
      
      
         | 
         | 
        409 | 
          		_delay_us(100); | 
      
      
         | 
         | 
        410 | 
        	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE); | 
      
      
         | 
         | 
        411 | 
        	#endif | 
      
      
         | 
         | 
        412 | 
          | 
      
      
         | 
         | 
        413 | 
        	// Set and Init | 
      
      
         | 
         | 
        414 | 
        	lcd_send_cmd(LCD_HD44780_FNSET);  		// 4/8 bits 1/2 lines	 | 
      
      
         | 
         | 
        415 | 
        	lcd_send_cmd(LCD_HD44780_ENTMODE_DEF);	// increment/decrement, shift/no shift | 
      
      
         | 
         | 
        416 | 
        	lcd_clear_home();						// display on, no cursor, clear and home | 
      
      
         | 
         | 
        417 | 
        } | 
      
      
         | 
         | 
        418 | 
          | 
      
      
         | 
         | 
        419 | 
          | 
      
      
         | 
         | 
        420 | 
        // LCD Char Output | 
      
      
         | 
         | 
        421 | 
        int | 
      
      
         | 
         | 
        422 | 
        lcd_putc(char c) | 
      
      
         | 
         | 
        423 | 
        { | 
      
      
         | 
         | 
        424 | 
        	static uint8_t mode=0; | 
      
      
         | 
         | 
        425 | 
          | 
      
      
         | 
         | 
        426 | 
        	switch (c) | 
      
      
         | 
         | 
        427 | 
        	{ | 
      
      
         | 
         | 
        428 | 
        		case '\f':	 | 
      
      
         | 
         | 
        429 | 
        			lcd_clear_home();       // Clear Display | 
      
      
         | 
         | 
        430 | 
        			break; | 
      
      
         | 
         | 
        431 | 
          | 
      
      
         | 
         | 
        432 | 
        		case '\n':	 | 
      
      
         | 
         | 
        433 | 
        			#if LCD_LINES > 1 | 
      
      
         | 
         | 
        434 | 
        				if (lcd_posy <= LCD_LINES)	// Go to the Next Line | 
      
      
         | 
         | 
        435 | 
        					lcd_posy++; | 
      
      
         | 
         | 
        436 | 
        			#endif | 
      
      
         | 
         | 
        437 | 
          | 
      
      
         | 
         | 
        438 | 
         		case '\r':	 | 
      
      
         | 
         | 
        439 | 
        			#if LCD_LINES > 1 | 
      
      
         | 
         | 
        440 | 
        				lcd_gotoxy(1,lcd_posy);		// Go to the Beginning of the Line | 
      
      
         | 
         | 
        441 | 
        			#else | 
      
      
         | 
         | 
        442 | 
        				lcd_home(); | 
      
      
         | 
         | 
        443 | 
        			#endif | 
      
      
         | 
         | 
        444 | 
        			break; | 
      
      
         | 
         | 
        445 | 
          | 
      
      
         | 
         | 
        446 | 
        		case '\b': | 
      
      
         | 
         | 
        447 | 
        			lcd_cursor_left();		// Cursor (Position) Move Back | 
      
      
         | 
         | 
        448 | 
        			break; | 
      
      
         | 
         | 
        449 | 
          | 
      
      
         | 
         | 
        450 | 
        		default: | 
      
      
         | 
         | 
        451 | 
        			if (mode==0 && c=='\v')	// Startr of Definition String | 
      
      
         | 
         | 
        452 | 
        			{ | 
      
      
         | 
         | 
        453 | 
        				mode=1;				// Mode Next Char will be Defined Char  | 
      
      
         | 
         | 
        454 | 
        				break; | 
      
      
         | 
         | 
        455 | 
        			} | 
      
      
         | 
         | 
        456 | 
        			if (mode==1)			// First Char is Position Number | 
      
      
         | 
         | 
        457 | 
        			{ | 
      
      
         | 
         | 
        458 | 
        				lcd_send_cmd(0x40 | ((c & 0x07)<<3) );	// Set CGRAM Address | 
      
      
         | 
         | 
        459 | 
        				mode++;				// Mode Define Char Patern | 
      
      
         | 
         | 
        460 | 
        				break; | 
      
      
         | 
         | 
        461 | 
        			} | 
      
      
         | 
         | 
        462 | 
        			if (mode==2 && c=='\v')	// End of Definition String | 
      
      
         | 
         | 
        463 | 
        			{ | 
      
      
         | 
         | 
        464 | 
        				mode=0; | 
      
      
         | 
         | 
        465 | 
        				#if LCD_LINES > 1 | 
      
      
         | 
         | 
        466 | 
        					lcd_gotoxy(lcd_posx,lcd_posy); | 
      
      
         | 
         | 
        467 | 
        				#else | 
      
      
         | 
         | 
        468 | 
        					lcd_gotoxy(lcd_posx,1); | 
      
      
         | 
         | 
        469 | 
        				#endif | 
      
      
         | 
         | 
        470 | 
        				break; | 
      
      
         | 
         | 
        471 | 
        			} | 
      
      
         | 
         | 
        472 | 
        			if (mode != 2)			// Ordinary Chars | 
      
      
         | 
         | 
        473 | 
        			{ | 
      
      
         | 
         | 
        474 | 
        				if (c<0x20)			// Remap User Defind Char | 
      
      
         | 
         | 
        475 | 
        					c &= 0x07;		// 	from rage 0x10-0x1F to 0x00-0x0f | 
      
      
         | 
         | 
        476 | 
        				lcd_inc_pos();		// Next Position | 
      
      
         | 
         | 
        477 | 
        				} | 
      
      
         | 
         | 
        478 | 
        			lcd_send_data(c);		// Send Byte to LCD | 
      
      
         | 
         | 
        479 | 
        			break; | 
      
      
         | 
         | 
        480 | 
        	} | 
      
      
         | 
         | 
        481 | 
          | 
      
      
         | 
         | 
        482 | 
        	return 0;	// Success | 
      
      
         | 
         | 
        483 | 
        } | 
      
      
         | 
         | 
        484 | 
          | 
      
      
         | 
         | 
        485 | 
          |