Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
359 kaklik 1
 
2
/****************************************************************************
3
 Title  :   C  file for the HD44780U LCD library (lcd_io.c)
4
 Author:    Chris efstathiou hendrix@otenet.gr
5
 Date:      1/Jul/2002
6
 Software:  AVR-GCC with AVR-AS
7
 Target:    any AVR device
8
 Comments:  This software is FREE.
9
 
10
*****************************************************************************/
11
#ifndef _IO_REG_MACRO_MODE_
12
#define _IO_REG_MACRO_MODE_  1     /* In case you have the new assignment mode io headers */
13
#endif
14
 
15
#ifndef  _SFR_ASM_COMPAT
16
#define  _SFR_ASM_COMPAT     1     /* This is for GCC 3.2 */
17
#endif
18
 
19
#include <io.h>
20
#include <progmem.h>
21
#include <eeprom.h>
22
#include "lcd_io.h"
23
 
24
/* constants/macros */
25
#ifndef CONCAT1
26
#define CONCAT1(a, b) CONCAT2(a, b)
27
#endif
28
 
29
#ifndef CONCAT2
30
#define CONCAT2(a, b) a ## b
31
#endif
32
 
33
#define LCD_POWER_ON_DELAY ( (20000*(F_CPU/60000))/100 )    /* 20 milliseconds */
34
#define LCD_INIT_DELAY     ( (5000*(F_CPU/60000))/100 )     /* 5 milliseconds */
35
 
36
#define INIT_MODE   2
37
#define DATA_MODE   1
38
#define CMD_MODE    0
39
 
40
 
41
/* CONVERSION OF LCD_DELAY_TIME TO TRUE MICROSECONDS */
42
#if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
43
#define LCD_DELAY_SHORT ( (LCD_DELAY_TIME*(F_CPU/60000))/100 )
44
#define LCD_DELAY_LONG  ( LCD_DELAY_SHORT*40 )
45
#endif
46
 
47
 
48
 
49
/*######################################################################################################*/
50
#if LCD_IO_MODE == 2
51
/*######################################################################################################*/
52
 
53
#define LCD_DATA_PORT_IS_IO   1
54
#define LCD_CLOCK_PORT_IS_IO  1
55
 
56
#define LCD_DATA_PORT         CONCAT1(PORT,LCD_DATA_SIGNAL_PORT)
57
#define LCD_DATA_DDR_REG      CONCAT1(DDR,LCD_DATA_SIGNAL_PORT)
58
 
59
#define LCD_CLOCK_PORT        CONCAT1(PORT,LCD_CLOCK_SIGNAL_PORT) 
60
#define LCD_CLOCK_DDR_REG     CONCAT1(DDR,LCD_CLOCK_SIGNAL_PORT) 
61
 
62
#define LCD_READ_REQUIRED 0
63
 
64
 
65
 
66
#if defined(__AVR_ATmega103__)
67
 
68
#if LCD_DATA_PORT == PORTC 
69
#undef  LCD_DATA_PORT_IS_IO
70
#undef  LCD_DATA_DDR_REG
71
#define LCD_DATA_PORT_IS_IO   0
72
#endif
73
 
74
#if LCD_CLOCK_PORT == PORTC 
75
#undef  LCD_CLOCK_PORT_IS_IO
76
#undef  LCD_CLOCK_DDR_REG
77
#define LCD_CLOCK_PORT_IS_IO  0
78
#endif
79
#endif /* #if defined(__AVR_ATmega103__) */
80
 
81
/*######################################################################################################*/
82
#elif LCD_IO_MODE == 6
83
/*######################################################################################################*/
84
#define lcd_toggle_e()   ({ cbi(LCD_E_PORT, LCD_E_PIN); delay(F_CPU/6000000); \
85
                            sbi(LCD_E_PORT, LCD_E_PIN);  })
86
 
87
#if LCD_READ_REQUIRED == 1  
88
#undef  LCD_MULTIPLEX_REQUIRED
89
#define LCD_MULTIPLEX_REQUIRED   0
90
#define BUSY_FLAG   0
91
#define DATA        1
92
#endif
93
 
94
#if LCD_LINES == 1 || LCD_LINES == 2 || LCD_LINES == 4
95
#else
96
#error THE LCD LINES MUST BE 1 OR 2 OR 4 !
97
#endif
98
 
99
#define LCD_D4_PORT_IS_IO     1   
100
#define LCD_D5_PORT_IS_IO     1   
101
#define LCD_D6_PORT_IS_IO     1 
102
#define LCD_D7_PORT_IS_IO     1
103
#define LCD_RS_PORT_IS_IO     1
104
#define LCD_RW_PORT_IS_IO     1
105
#define LCD_E_PORT_IS_IO      1
106
 
107
#define LCD_D4_PORT           CONCAT1(PORT, LCD_DATA4_PORT)
108
#define LCD_D5_PORT           CONCAT1(PORT, LCD_DATA5_PORT)
109
#define LCD_D6_PORT           CONCAT1(PORT, LCD_DATA6_PORT)
110
#define LCD_D7_PORT           CONCAT1(PORT, LCD_DATA7_PORT)
111
#define LCD_RS_PORT           CONCAT1(PORT, LCD_RS_SIGNAL_PORT)
112
#define LCD_RW_PORT           CONCAT1(PORT, LCD_RW_SIGNAL_PORT)
113
#define LCD_E_PORT            CONCAT1(PORT, LCD_E_SIGNAL_PORT)
114
 
115
#define LCD_D4_DDR_REG        CONCAT1(DDR, LCD_DATA4_PORT)
116
#define LCD_D5_DDR_REG        CONCAT1(DDR, LCD_DATA5_PORT)
117
#define LCD_D6_DDR_REG        CONCAT1(DDR, LCD_DATA6_PORT)
118
#define LCD_D7_DDR_REG        CONCAT1(DDR, LCD_DATA7_PORT)
119
#define LCD_RS_DDR_REG        CONCAT1(DDR, LCD_RS_SIGNAL_PORT)
120
#define LCD_RW_DDR_REG        CONCAT1(DDR, LCD_RW_SIGNAL_PORT)
121
#define LCD_E_DDR_REG         CONCAT1(DDR, LCD_E_SIGNAL_PORT)
122
 
123
 
124
 
125
#if   LCD_READ_REQUIRED == 1
126
 
127
#define LCD_D4_PIN_REG        CONCAT1(PIN, LCD_DATA4_PORT)
128
#define LCD_D5_PIN_REG        CONCAT1(PIN, LCD_DATA5_PORT)
129
#define LCD_D6_PIN_REG        CONCAT1(PIN, LCD_DATA6_PORT)
130
#define LCD_D7_PIN_REG        CONCAT1(PIN, LCD_DATA7_PORT)
131
 
132
#elif LCD_READ_REQUIRED == 0
133
 
134
#undef LCD_RW_PORT
135
#undef LCD_RW_DDR_REG
136
#undef LCD_RW_PORT_IS_IO
137
 
138
#endif
139
 
140
 
141
 
142
#if defined(__AVR_ATmega103__)
143
 
144
#if LCD_D4_PORT == PORTC 
145
#if LCD_READ_REQUIRED == 1
146
#error THE PORT FOR LCD_D4 IS OUTPUT ONLY!
147
#endif
148
#undef  LCD_D4_PORT_IS_IO
149
#undef  LCD_D4_DDR_REG 
150
#define LCD_D4_PORT_IS_IO   0
151
#endif
152
 
153
#if LCD_D5_PORT == PORTC 
154
#if LCD_READ_REQUIRED == 1
155
#error THE PORT FOR LCD_D5 IS OUTPUT ONLY!
156
#endif
157
#undef  LCD_D5_PORT_IS_IO
158
#undef  LCD_D5_DDR_REG 
159
#define LCD_D5_PORT_IS_IO   0
160
#endif
161
 
162
#if LCD_D6_PORT == PORTC 
163
#if LCD_READ_REQUIRED == 1
164
#error THE PORT FOR LCD_D6 IS OUTPUT ONLY!
165
#endif
166
#undef  LCD_D6_PORT_IS_IO
167
#undef  LCD_D6_DDR_REG 
168
#define LCD_D6_PORT_IS_IO   0
169
#endif
170
 
171
#if LCD_D7_PORT == PORTC 
172
#if LCD_READ_REQUIRED == 1
173
#error THE PORT FOR LCD_D7 IS OUTPUT ONLY!
174
#endif
175
#undef  LCD_D7_PORT_IS_IO
176
#undef  LCD_D7_DDR_REG 
177
#define LCD_D7_PORT_IS_IO   0
178
#endif
179
 
180
#if LCD_RS_PORT == PORTC 
181
#undef  LCD_RS_PORT_IS_IO
182
#undef  LCD_RS_DDR_REG 
183
#define LCD_RS_PORT_IS_IO   0
184
#endif
185
 
186
#if LCD_READ_REQUIRED == 1 
187
#if LCD_RW_PORT == PORTC 
188
#undef  LCD_RW_PORT_IS_IO
189
#undef  LCD_RW_DDR_REG 
190
#define LCD_RW_PORT_IS_IO   0
191
#endif 
192
#endif
193
 
194
#if LCD_E_PORT == PORTC 
195
#undef  LCD_E_PORT_IS_IO
196
#undef  LCD_E_DDR_REG 
197
#define LCD_E_PORT_IS_IO    0
198
#endif
199
 
200
#endif /* #if defined(__AVR_ATmega103__) */
201
 
202
/*######################################################################################################*/
203
#elif LCD_IO_MODE == 7
204
/*######################################################################################################*/
205
 
206
#define lcd_toggle_e()   ({ cbivar(lcd_E_port, lcd_E_pin); delay(F_CPU/6000000); \
207
                            sbivar(lcd_E_port, lcd_E_pin);  })
208
#if SREG > 0X3F
209
#define IO_TO_MEM_OFFSET  0
210
#else
211
#define IO_TO_MEM_OFFSET  0X20
212
#endif
213
 
214
#define LCD_READ_REQUIRED 0  
215
 
216
#if LCD_0_LINES == 1 || LCD_0_LINES == 2 || LCD_0_LINES == 4
217
#else
218
#error THE LCD LINES MUST BE 1 OR 2 OR 4 !
219
#endif
220
 
221
#if LCD_1_LINES == 1 || LCD_1_LINES == 2 || LCD_1_LINES == 4
222
#else
223
#error THE LCD LINES MUST BE 1 OR 2 OR 4 !
224
#endif
225
 
226
#if NUMBER_OF_LCD_UNITS >= 3
227
#if LCD_2_LINES == 1 || LCD_2_LINES == 2 || LCD_2_LINES == 4
228
#else
229
#error THE LCD LINES MUST BE 1 OR 2 OR 4 !
230
#endif
231
#endif
232
 
233
#define LCD_D4_PORT_IS_IO     1   
234
#define LCD_D5_PORT_IS_IO     1   
235
#define LCD_D6_PORT_IS_IO     1 
236
#define LCD_D7_PORT_IS_IO     1
237
#define LCD_RS_PORT_IS_IO     1
238
#define LCD_0_E_PORT_IS_IO    1
239
#define LCD_1_E_PORT_IS_IO    1
240
 
241
#if NUMBER_OF_LCD_UNITS >=3
242
#define LCD_2_E_PORT_IS_IO    1
243
#endif
244
 
245
#define LCD_D4_PORT           CONCAT1(PORT, LCD_DATA4_PORT)
246
#define LCD_D5_PORT           CONCAT1(PORT, LCD_DATA5_PORT)
247
#define LCD_D6_PORT           CONCAT1(PORT, LCD_DATA6_PORT)
248
#define LCD_D7_PORT           CONCAT1(PORT, LCD_DATA7_PORT)
249
#define LCD_RS_PORT           CONCAT1(PORT, LCD_RS_SIGNAL_PORT)
250
#define LCD_0_E_PORT          CONCAT1(PORT, LCD_0_E_SIGNAL_PORT)
251
#define LCD_1_E_PORT          CONCAT1(PORT, LCD_1_E_SIGNAL_PORT)
252
 
253
#if NUMBER_OF_LCD_UNITS >=3
254
#define LCD_2_E_PORT          CONCAT1(PORT, LCD_2_E_SIGNAL_PORT)
255
#endif
256
 
257
#define LCD_D4_DDR_REG        CONCAT1(DDR, LCD_DATA4_PORT)
258
#define LCD_D5_DDR_REG        CONCAT1(DDR, LCD_DATA5_PORT)
259
#define LCD_D6_DDR_REG        CONCAT1(DDR, LCD_DATA6_PORT)
260
#define LCD_D7_DDR_REG        CONCAT1(DDR, LCD_DATA7_PORT)
261
#define LCD_RS_DDR_REG        CONCAT1(DDR, LCD_RS_SIGNAL_PORT)
262
#define LCD_0_E_DDR_REG       CONCAT1(DDR, LCD_0_E_SIGNAL_PORT)
263
#define LCD_1_E_DDR_REG       CONCAT1(DDR, LCD_1_E_SIGNAL_PORT)
264
 
265
#if NUMBER_OF_LCD_UNITS >=3
266
#define LCD_2_E_DDR_REG       CONCAT1(DDR, LCD_2_E_SIGNAL_PORT)
267
#endif
268
 
269
 
270
#if defined(__AVR_ATmega103__)
271
 
272
#if LCD_D4_PORT == PORTC 
273
#undef  LCD_D4_PORT_IS_IO
274
#undef  LCD_D4_DDR_REG 
275
#define LCD_D4_PORT_IS_IO   0
276
#endif
277
 
278
#if LCD_D5_PORT == PORTC 
279
#undef  LCD_D5_PORT_IS_IO
280
#undef  LCD_D5_DDR_REG 
281
#define LCD_D5_PORT_IS_IO   0
282
#endif
283
 
284
#if LCD_D6_PORT == PORTC 
285
#undef  LCD_D6_PORT_IS_IO
286
#undef  LCD_D6_DDR_REG 
287
#define LCD_D6_PORT_IS_IO   0
288
#endif
289
 
290
#if LCD_D7_PORT == PORTC 
291
#undef  LCD_D7_PORT_IS_IO
292
#undef  LCD_D7_DDR_REG 
293
#define LCD_D7_PORT_IS_IO   0
294
#endif
295
 
296
#if LCD_RS_PORT == PORTC 
297
#undef  LCD_RS_PORT_IS_IO
298
#undef  LCD_RS_DDR_REG 
299
#define LCD_RS_PORT_IS_IO   0
300
#endif
301
 
302
#if LCD_0_E_PORT == PORTC 
303
#undef  LCD_0_E_PORT_IS_IO
304
#undef  LCD_0_E_DDR_REG 
305
#define LCD_0_E_PORT_IS_IO  0
306
#endif
307
 
308
#if LCD_1_E_PORT == PORTC 
309
#undef  LCD_1_E_PORT_IS_IO
310
#undef  LCD_1_E_DDR_REG 
311
#define LCD_1_E_PORT_IS_IO  0
312
#endif
313
 
314
#if NUMBER_OF_LCD_UNITS >=3
315
#if LCD_2_E_PORT == PORTC 
316
#undef  LCD_2_E_PORT_IS_IO
317
#undef  LCD_2_E_DDR_REG 
318
#define LCD_2_E_PORT_IS_IO  0
319
#endif
320
#endif  /*  #if NUMBER_OF_LCD_UNITS >=3  */
321
 
322
#endif  /*  #if defined(__AVR_ATmega103__)  */
323
 
324
#endif  /*  #elif LCD_IO_MODE == 7 */   
325
/*######################################################################################################*/
326
 
327
/* type definitions */
328
 
329
typedef unsigned char  u08;
330
typedef unsigned short u16;
331
 
332
/*######################################################################################################*/
333
/* FUNCTION PROTOTYPES                                                                                  */
334
/*######################################################################################################*/
335
 
336
#if LCD_IO_MODE == 7
337
static void sbivar(unsigned char port, unsigned char bit);
338
static void cbivar(unsigned char port, unsigned char bit);
339
#endif
340
 
341
#if  LCD_READ_REQUIRED == 1
342
static unsigned char lcd_read(unsigned char rs);
343
static inline unsigned char lcd_waitbusy(void);
344
#endif
345
 
346
static void delay(unsigned long int us);
347
 
348
/*######################################################################################################*/
349
/* GLOBAL variables                                                                                     */
350
/*######################################################################################################*/
351
 
352
static unsigned char x,y, putc_lock=0;
353
#if LCD_IO_MODE == 7
354
static unsigned char lcd_E_port=0, lcd_E_pin=0, lcd_chars_per_line=0, lcd_lines=0, current_lcd_unit=0;
355
static struct xy {
356
                   unsigned char x;
357
                   unsigned char y;
358
                 } xy_coordinates[NUMBER_OF_LCD_UNITS];
359
 
360
#endif
361
 
362
/*######################################################################################################*/
363
/* local functions */
364
/*######################################################################################################*/
365
 
366
static void delay(unsigned long int us)
367
/* delay for a minimum of <us> microseconds (with a 6 Mhz crystal, the resolution is 1 us) */
368
{
369
   while ( us ) { us--; }  /* 6 cpu cycles per loop */
370
} 
371
 
372
/*######################################################################################################*/
373
#if LCD_IO_MODE == 7   /* lcd_write() function for 6 bit i/o one lcd unit */
374
/*######################################################################################################*/
375
 
376
 
377
static void sbivar(unsigned char port, unsigned char bit)
378
{
379
register unsigned char temp=0;
380
 
381
    temp=*((unsigned char*)(port+IO_TO_MEM_OFFSET));
382
    temp|= (1<<bit);
383
    *((unsigned char*)(port+IO_TO_MEM_OFFSET))=temp;
384
 
385
return;
386
}
387
/*######################################################################################################*/
388
 
389
static void cbivar(unsigned char port, unsigned char bit)
390
{
391
register unsigned char temp=0;
392
 
393
    temp=*((unsigned char*)(port+IO_TO_MEM_OFFSET));
394
    temp &= ~(1<<bit);
395
    *((unsigned char*)(port+IO_TO_MEM_OFFSET))=temp;
396
 
397
return;
398
}
399
/*######################################################################################################*/
400
 
401
static void lcd_write(unsigned char data, unsigned char mode) 
402
{
403
register unsigned char rs=0; 
404
 
405
 
406
       if(mode==DATA_MODE) rs=1; else rs=0;          /* set the rs value */
407
       /* output high nibble first */ 
408
       if(data&0x10) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
409
       if(data&0x20) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
410
       if(data&0x40) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
411
       if(data&0x80) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
412
       if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
413
       lcd_toggle_e();
414
       /* output low nibble */
415
       /* if INIT_MODE skip this section else execute it */
416
       if(mode!=INIT_MODE)
417
        {
418
          if(data&0x01) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
419
          if(data&0x02) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
420
          if(data&0x04) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
421
          if(data&0x08) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
422
          if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
423
          lcd_toggle_e();
424
        }
425
 
426
 delay(LCD_DELAY_SHORT);
427
 
428
}
429
/*------------------------------------------------------------------------------------------------------*/
430
void  select_lcd(unsigned char lcd_unit)
431
{
432
/* Save the current lcd unit x,y coordinates */
433
   xy_coordinates[current_lcd_unit].x=x;
434
   xy_coordinates[current_lcd_unit].y=y;
435
 
436
   if(lcd_unit==0)
437
    {
438
       lcd_E_port= LCD_0_E_PORT;
439
       lcd_E_pin = LCD_0_E_PIN;
440
       lcd_chars_per_line = LCD_0_CHARS_PER_LINE;
441
       lcd_lines = LCD_0_LINES;
442
       current_lcd_unit=lcd_unit;     /* Make the requested lcd unit current (active) */
443
       x=xy_coordinates[lcd_unit].x;  /* Load the saved x,y coordinates of the specified lcd unit */
444
       y=xy_coordinates[lcd_unit].y;
445
    }
446
   else if(lcd_unit==1)
447
         {
448
            lcd_E_port= LCD_1_E_PORT;
449
            lcd_E_pin = LCD_1_E_PIN;
450
            lcd_chars_per_line = LCD_1_CHARS_PER_LINE;
451
            lcd_lines = LCD_1_LINES;
452
            current_lcd_unit=lcd_unit;
453
            x=xy_coordinates[lcd_unit].x;
454
            y=xy_coordinates[lcd_unit].y;
455
         }
456
#if NUMBER_OF_LCD_UNITS >=3
457
   else if(lcd_unit==2)
458
         {
459
            lcd_E_port= LCD_2_E_PORT;
460
            lcd_E_pin = LCD_2_E_PIN;
461
            lcd_chars_per_line = LCD_2_CHARS_PER_LINE;
462
            lcd_lines = LCD_2_LINES;
463
            current_lcd_unit=lcd_unit;
464
            x=xy_coordinates[lcd_unit].x;
465
            y=xy_coordinates[lcd_unit].y;
466
         }
467
#endif
468
return;
469
}
470
/*######################################################################################################*/
471
#elif LCD_IO_MODE == 6   /* lcd_write() function for 6 bit i/o  with multi lcd units */
472
/*######################################################################################################*/
473
 
474
#if LCD_READ_REQUIRED == 1 
475
 
476
#define LCD_READ_DELAY  ( (10*(F_CPU/60000))/100 )
477
 
478
static unsigned char lcd_read(unsigned char rs) 
479
{
480
register unsigned char data=0;
481
/* RS=1: read data, RS=0: read busy flag, RW=1  read mode */  
482
    if (rs) sbi(LCD_RS_PORT, LCD_RS_PIN); else cbi(LCD_RS_PORT, LCD_RS_PIN);    
483
 
484
    /* configure data pins as input */
485
    cbi(LCD_D4_DDR_REG, LCD_D4_PIN );
486
    cbi(LCD_D5_DDR_REG, LCD_D5_PIN );
487
    cbi(LCD_D6_DDR_REG, LCD_D6_PIN );
488
    cbi(LCD_D7_DDR_REG, LCD_D7_PIN );
489
 
490
    /* set R/W pin for reading from LCD */
491
    sbi(LCD_RW_PORT, LCD_RW_PIN); 
492
    delay(LCD_READ_DELAY);
493
 
494
    if(bit_is_set(LCD_D7_PIN_REG, LCD_D7_PIN)) { data+=1; }
495
    data=(data<<1);
496
    if(bit_is_set(LCD_D6_PIN_REG, LCD_D6_PIN)) { data+=1; }
497
    data=(data<<1);
498
    if(bit_is_set(LCD_D5_PIN_REG, LCD_D5_PIN)) { data+=1; }
499
    data=(data<<1);
500
    if(bit_is_set(LCD_D4_PIN_REG, LCD_D4_PIN)) { data+=1; }
501
    data=(data<<1);
502
 
503
    lcd_toggle_e();
504
    delay(LCD_READ_DELAY);
505
 
506
    if(bit_is_set(LCD_D7_PIN_REG, LCD_D7_PIN)) { data+=1; }
507
    data=(data<<1);
508
    if(bit_is_set(LCD_D6_PIN_REG, LCD_D6_PIN)) { data+=1; }
509
    data=(data<<1);
510
    if(bit_is_set(LCD_D5_PIN_REG, LCD_D5_PIN)) { data+=1; }
511
    data=(data<<1);
512
    if(bit_is_set(LCD_D4_PIN_REG, LCD_D4_PIN)) { data+=1; }
513
 
514
    lcd_toggle_e();
515
 
516
    /* clear R/W pin for writting to LCD */
517
    cbi(LCD_RW_PORT, LCD_RW_PIN);      
518
 
519
    /* configure data pins as outputs */
520
    sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
521
    sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
522
    sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
523
    sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
524
 
525
 
526
return (data);
527
}
528
/*######################################################################################################*/
529
static inline unsigned char lcd_waitbusy(void)
530
/* loops while lcd is busy, reads address counter */
531
{
532
register unsigned char c;
533
 
534
    while ( (c=lcd_read(BUSY_FLAG) & (1<<LCD_BUSY)) ); 
535
 
536
    return (c);  // return address counter
537
}
538
 
539
#endif  /* #if LCD_READ_REQUIRED == 1  */
540
/*######################################################################################################*/
541
 
542
static void lcd_write(unsigned char data, unsigned char mode) 
543
{
544
register unsigned char rs=0; 
545
 
546
 /* save and set DDR(X) register(s) in case another program altered those values */
547
#if LCD_MULTIPLEX_ENABLE == 1
548
 
549
#if LCD_D4_PORT_IS_IO==1
550
unsigned char d4_is_output=0;
551
if(inp(LCD_D4_DDR_REG)&(1<<LCD_D4_PIN)) { d4_is_output=1; }
552
sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
553
#endif
554
#if LCD_D5_PORT_IS_IO==1
555
unsigned char d5_is_output=0;
556
if(inp(LCD_D5_DDR_REG)&(1<<LCD_D5_PIN)) { d5_is_output=1; }
557
sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
558
#endif
559
#if LCD_D6_PORT_IS_IO==1
560
unsigned char d6_is_output=0;
561
if(inp(LCD_D6_DDR_REG)&(1<<LCD_D6_PIN)) { d6_is_output=1; }
562
sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
563
#endif
564
#if LCD_D7_PORT_IS_IO==1
565
unsigned char d7_is_output=0;
566
if(inp(LCD_D7_DDR_REG)&(1<<LCD_D7_PIN)) { d7_is_output=1; }
567
sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
568
#endif
569
#if LCD_RS_PORT_IS_IO==1
570
unsigned char rs_is_output=0;
571
if(inp(LCD_RS_DDR_REG)&(1<<LCD_RS_PIN)) { rs_is_output=1; }
572
sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
573
#endif
574
 
575
#endif  /* LCD_MULTIPLEX_ENABLE == 1 */
576
 
577
       if(mode==DATA_MODE) rs=1; else rs=0;          /* set the rs value */
578
       /* output high nibble first */ 
579
       if(data&0x10) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
580
       if(data&0x20) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
581
       if(data&0x40) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
582
       if(data&0x80) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
583
       if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
584
       lcd_toggle_e();
585
       /* output low nibble */
586
       /* if INIT_MODE skip this section else execute it */
587
       if(mode!=INIT_MODE)
588
        {
589
          if(data&0x01) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
590
          if(data&0x02) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
591
          if(data&0x04) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
592
          if(data&0x08) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
593
          if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
594
          lcd_toggle_e();
595
        }
596
#if   LCD_READ_REQUIRED == 0
597
 delay(LCD_DELAY_SHORT);
598
#elif LCD_READ_REQUIRED == 1
599
 lcd_waitbusy();
600
#endif
601
 
602
/* Restore the DDR registers, if multiplexing wanted */     
603
#if LCD_MULTIPLEX_ENABLE == 1 
604
 
605
#if LCD_D4_PORT_IS_IO==1
606
if(!d4_is_output) { cbi(LCD_D4_DDR_REG, LCD_D4_PIN ); } 
607
#endif
608
#if LCD_D5_PORT_IS_IO==1
609
if(!d5_is_output) { cbi(LCD_D5_DDR_REG, LCD_D5_PIN ); }
610
#endif
611
#if LCD_D6_PORT_IS_IO==1
612
if(!d6_is_output) { cbi(LCD_D6_DDR_REG, LCD_D6_PIN ); }
613
#endif
614
#if LCD_D7_PORT_IS_IO==1
615
if(!d7_is_output) { cbi(LCD_D7_DDR_REG, LCD_D7_PIN ); }
616
#endif
617
#if LCD_RS_PORT_IS_IO==1
618
if(!rs_is_output) { cbi(LCD_RS_DDR_REG, LCD_RS_PIN ); }
619
#endif
620
 
621
#endif  /* LCD_MULTIPLEX_ENABLE == 1 */
622
}
623
/*######################################################################################################*/
624
#elif LCD_IO_MODE == 2  /* lcd_write() function for 2 bit i/o */
625
/*######################################################################################################*/
626
 
627
static void lcd_write(unsigned char lcd_data,unsigned char mode) 
628
{
629
#define toggle_clock() ({ sbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); cbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); }) 
630
#define data(x) ({ if(x) sbi(LCD_DATA_PORT, LCD_DATA_PIN); else cbi(LCD_DATA_PORT, LCD_DATA_PIN); })        
631
#define toggle_data()       ({ data(1); delay(F_CPU/6000000); data(0); })
632
 
633
register unsigned char x=0, rs=0;
634
 
635
       /* INITIALIZATION */
636
       /* Set clock and data pins as outputs, at low state and set rs value */ 
637
#if LCD_CLOCK_PORT_IS_IO
638
  sbi(LCD_CLOCK_DDR_REG, LCD_CLOCK_PIN); 
639
#endif
640
#if LCD_DATA_PORT_IS_IO
641
  sbi(LCD_DATA_DDR_REG, LCD_DATA_PIN);
642
#endif
643
       cbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); cbi(LCD_DATA_PORT, LCD_DATA_PIN); 
644
       if(mode==DATA_MODE) rs=1; else rs=0;
645
 
646
       /* send high nibble first */
647
       x=6; while(x--)   {  toggle_clock();  }           /* clear shift register */           
648
       data(1);             toggle_clock();              /* send E "AND" signal */
649
       data(rs);            toggle_clock();              /* send RS signal */
650
       x=0x80; while(x>=0x10) { data(lcd_data&x); toggle_clock(); x=(x>>1); }
651
       /* Strobe E pin making sure that the pulse is 450 ns min */
652
       toggle_data();   
653
 
654
       /* send low nibble  Clock and Data are already low */
655
       x=6; while(x--)   {  toggle_clock();  }           /* clear shift register */       
656
       data(1);             toggle_clock();              /* send E "AND" signal */
657
       data(rs);            toggle_clock();              /* send RS signal */
658
       x=0x08; while(x>=0x01) { data(lcd_data&x); toggle_clock(); x=(x>>1); }
659
       /* if INIT_MODE do NOT strobe the E pin else strobe it */
660
       if(mode!=INIT_MODE) { toggle_data(); }       
661
 
662
       delay(LCD_DELAY_SHORT);     /* wait for command to execute  */     
663
 
664
}
665
/*######################################################################################################*/
666
#endif /* #elif LCD_IO_MODE == 2 */
667
/*######################################################################################################*/
668
 
669
/*######################################################################################################*/
670
/* PUBLIC FUNCTIONS */
671
/*######################################################################################################*/
672
void lcd_command(unsigned char cmd)
673
/* send command <cmd> to LCD */
674
{
675
    lcd_write(cmd,CMD_MODE);
676
 
677
}
678
/*######################################################################################################*/
679
 
680
void lcd_gotoxy(unsigned char lcd_x, unsigned char lcd_y)
681
/* goto position (x,y) */
682
{
683
#if LCD_IO_MODE == 7 
684
 
685
if(lcd_x >= lcd_chars_per_line || lcd_y >= lcd_lines) { putc_lock=1; return; }
686
else putc_lock=0;
687
 
688
    if (lcd_y==0 )    { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
689
    else if(lcd_y==1) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x); }
690
    else if(lcd_y==2) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+lcd_x); }
691
    else              { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+lcd_x); }
692
/*------------------------------------------------------------------------------------------------------*/
693
#elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
694
/*------------------------------------------------------------------------------------------------------*/
695
 
696
if(lcd_x >= LCD_CHARS_PER_LINE || lcd_y >= LCD_LINES) { putc_lock=1; return; }
697
else putc_lock=0;
698
 
699
#if LCD_LINES==1
700
    if (lcd_y==0 ) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
701
#endif
702
#if LCD_LINES==2
703
    if (lcd_y==0 ) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x);  }
704
    else           { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x);  }
705
#endif
706
 
707
#if LCD_LINES==4
708
    if (lcd_y==0 )    { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
709
    else if(lcd_y==1) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x); }
710
    else if(lcd_y==2) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+lcd_x); }
711
    else              { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+lcd_x); }
712
#endif
713
#endif
714
    x=lcd_x;
715
    y=lcd_y;
716
 
717
}/* lcd_gotoxy */
718
/*######################################################################################################*/
719
 
720
unsigned int lcd_getxy(void)
721
{
722
  return((y*100)+x); 
723
}
724
/*######################################################################################################*/
725
 
726
void lcd_clrscr(void)
727
/* clear lcd and set cursor to home position */
728
{
729
   lcd_command(1<<LCD_CLR);
730
#if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
731
   delay(LCD_DELAY_LONG);       /* this command needs more waiting time to execute */
732
#elif LCD_READ_REQUIRED == 1 && LCD_IO_MODE == 6  
733
   lcd_waitbusy();
734
#endif
735
 
736
   x=0; y=0;
737
}
738
/*######################################################################################################*/
739
 
740
void lcd_clrline(unsigned char line)
741
/* clear a specific lcd line and set cursor at the start of the line */
742
{
743
#if LCD_IO_MODE == 7
744
   if(lcd_lines==1)
745
    {
746
       lcd_gotoxy(0, 0);
747
       while(x<lcd_chars_per_line) { lcd_putc(' '); }
748
       lcd_gotoxy(0, 0);
749
    }    
750
 
751
   if(line<lcd_lines)
752
    {
753
       lcd_gotoxy(0, line);
754
       while(x<lcd_chars_per_line) { lcd_putc(' '); }
755
       lcd_gotoxy(0, line);
756
    }   
757
 
758
#elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
759
 
760
#if LCD_LINES == 1
761
  lcd_gotoxy(0, 0);
762
  while(x<LCD_CHARS_PER_LINE) { lcd_putc(' '); }
763
  lcd_gotoxy(0, 0);
764
#else  /* #if LCD_LINES == 1 */
765
  if(line<LCD_LINES)
766
   {
767
      lcd_gotoxy(0, line);
768
      while(x<LCD_CHARS_PER_LINE) { lcd_putc(' '); }
769
      lcd_gotoxy(0, line);
770
   }   
771
#endif  /*  #if LCD_LINES == 1  */
772
#endif  /*  #if LCD_IO_MODE == 7 */
773
}
774
/*######################################################################################################*/
775
 
776
void lcd_home(void)
777
/* set cursor to home position */
778
{
779
    lcd_command(1<<LCD_HOME);
780
#if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
781
    delay(LCD_DELAY_LONG);       /* this command needs more waiting time to execute */
782
#elif LCD_READ_REQUIRED == 1 && LCD_IO_MODE == 6 
783
    lcd_waitbusy();
784
#endif    
785
    x=0; y=0;
786
}
787
/*######################################################################################################*/
788
 
789
void lcd_putc(unsigned char c)
790
/* print character at current cursor position */
791
{
792
 if(!putc_lock)
793
  {
794
#if LCD_IO_MODE == 7
795
   if(lcd_lines !=1)
796
    {  if(c=='\n') { if(y<lcd_lines-1) lcd_gotoxy(0,(y+1)); }
797
       else if(x<lcd_chars_per_line) { lcd_write(c, DATA_MODE); x++; }
798
#if LCD_AUTO_LINE_FEED == 1
799
       else if(y<lcd_lines-1) { lcd_gotoxy(0,(y+1)); lcd_write(c, DATA_MODE); x++; }
800
       else { lcd_gotoxy(0,0); lcd_write(c, DATA_MODE); x++; }
801
#endif
802
    }
803
   else{
804
         if(c=='\n') { return; }
805
         if(x<lcd_chars_per_line) { lcd_write(c, DATA_MODE); x++; }
806
       }
807
#elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
808
 
809
#if LCD_LINES!=1
810
       if(c=='\n') { if(y<LCD_LINES-1) lcd_gotoxy(0,(y+1)); }
811
       else if(x<LCD_CHARS_PER_LINE) { lcd_write(c, DATA_MODE); x++; }
812
#if LCD_AUTO_LINE_FEED == 1
813
       else if(y<LCD_LINES-1) { lcd_gotoxy(0,(y+1)); lcd_write(c, DATA_MODE); x++; }
814
       else { lcd_gotoxy(0,0); lcd_write(c, DATA_MODE); x++; }
815
#endif
816
 
817
#else
818
       if(c=='\n') { return; }
819
       if(x<LCD_CHARS_PER_LINE) { lcd_write(c, DATA_MODE); x++; }
820
#endif
821
 
822
#endif  /*   #if LCD_IO_MODE == 7  */       
823
  }  
824
}
825
/*######################################################################################################*/
826
 
827
void lcd_puts(const unsigned char *s)
828
/* print string on lcd (no auto linefeed) */
829
{
830
    register unsigned char c;
831
 
832
    while ( (c = *s++) ) { lcd_putc(c);  }
833
 
834
}
835
/*######################################################################################################*/
836
 
837
void lcd_puts_p(const unsigned char *progmem_s)
838
/* print string from program memory on lcd (no auto linefeed) */
839
{
840
    register unsigned char c;
841
 
842
    while ( (c = PRG_RDB(progmem_s++)) ) { lcd_putc(c);  }
843
 
844
}
845
/*######################################################################################################*/
846
 
847
void lcd_puts_e(unsigned char *eeprom_s)
848
/* print string from eeprom on lcd (no auto linefeed) */
849
{
850
 register unsigned char c;
851
 
852
    while( (c=eeprom_rb((unsigned int)eeprom_s++))&& c!=0xFF ) { lcd_putc(c);  }
853
    /*{ if(c==0xFF) break; lcd_putc(c);  }*/               
854
}
855
/*######################################################################################################*/
856
 
857
void lcd_puti(int value, unsigned char dot_position)
858
/* print signed integer on lcd with or without comma (no auto linefeed) */
859
{
860
unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
861
 
862
        /* convert int to ascii  */ 
863
        if(value<0) { lcd_putc('-'); value=-value; }    
864
        do { position--; *(lcd_data+position)=(value%radix)+'0'; value/=radix;  } while(value); 
865
 
866
        /* some fractional digit corrections  */
867
        if( dot_position>=sizeof(lcd_data) ) return;
868
        while( (sizeof(lcd_data)-dot_position)<=position )  position--; 
869
 
870
        /* start displaying the number */
871
        for(;position<=(sizeof(lcd_data)-1);position++)
872
          {
873
            if( position==sizeof(lcd_data)-dot_position ) lcd_putc(',');  
874
            lcd_putc(lcd_data[position]);
875
          }
876
 
877
return;
878
}
879
/*######################################################################################################*/
880
#if LCD_IO_MODE == 6 || LCD_IO_MODE == 2
881
/*######################################################################################################*/
882
 
883
void lcd_init(void)
884
{
885
/* initialize display and select type of cursor */
886
/* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */
887
 
888
#if LCD_LINES==1
889
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_1LINE 
890
#else
891
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_2LINES 
892
#endif 
893
 
894
#if LCD_IO_MODE == 6  
895
 
896
#if LCD_E_PORT_IS_IO==1
897
sbi(LCD_E_DDR_REG, LCD_E_PIN  );
898
#endif        
899
sbi(LCD_E_PORT, LCD_E_PIN  ); 
900
 
901
#if LCD_MULTIPLEX_ENABLE == 0 
902
 
903
#if LCD_D4_PORT_IS_IO==1
904
sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
905
#endif
906
#if LCD_D5_PORT_IS_IO==1
907
sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
908
#endif
909
#if LCD_D6_PORT_IS_IO==1
910
sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
911
#endif
912
#if LCD_D7_PORT_IS_IO==1
913
sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
914
#endif
915
#if LCD_RS_PORT_IS_IO==1
916
sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
917
#endif
918
 
919
#if LCD_READ_REQUIRED == 1 
920
#if  LCD_RW_PORT_IS_IO == 1
921
sbi(LCD_RW_DDR_REG, LCD_RW_PIN  );
922
#endif
923
cbi(LCD_RW_PORT, LCD_RW_PIN  ); 
924
#endif
925
 
926
#endif  /* #if LCD_MULTIPLEX_ENABLE == 0 */
927
 
928
#endif  /* #if LCD_IO_MODE == 6 */
929
 
930
/*------ Initialize lcd to 4 bit i/o mode -------*/
931
/* initial write to lcd is 8bit using delay since busy flag can't be checked here anyway */
932
 
933
    delay(LCD_POWER_ON_DELAY);                          /* Wait 20 milliseconds  */
934
 
935
    lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
936
    delay(LCD_INIT_DELAY);                              /* Wait 5 milliseconds */
937
 
938
    lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
939
 
940
    lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
941
 
942
    lcd_write(LCD_FUNCTION_4BIT_1LINE, INIT_MODE);      /* set IO mode to 4bit */
943
 
944
 
945
    /* from now on the lcd accepts only 4 bit I/O, so we can use lcd_command() */    
946
 
947
    lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines  */
948
    lcd_command(LCD_DISP_OFF);              /* display off                  */
949
    lcd_clrscr();                           /* display clear                */ 
950
    lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
951
    lcd_command(LCD_DISP_ON);               /* LCD DISPLAY ON (DEFAULT)     */
952
 
953
}/* lcd_init */
954
/*######################################################################################################*/
955
#elif LCD_IO_MODE == 7 
956
/*######################################################################################################*/
957
 
958
void lcd_init(void)
959
{
960
unsigned char lcd_unit=0;
961
/* initialize display and select type of cursor */
962
/* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */
963
 
964
#if LCD_D4_PORT_IS_IO == 1
965
sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
966
#endif
967
#if LCD_D5_PORT_IS_IO == 1
968
sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
969
#endif
970
#if LCD_D6_PORT_IS_IO == 1
971
sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
972
#endif
973
#if LCD_D7_PORT_IS_IO == 1
974
sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
975
#endif
976
#if LCD_RS_PORT_IS_IO == 1
977
sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
978
#endif
979
 
980
#if LCD_0_E_PORT_IS_IO == 1
981
sbi(LCD_0_E_DDR_REG, LCD_0_E_PIN  );                 
982
#endif        
983
sbi(LCD_0_E_PORT, LCD_0_E_PIN  ); 
984
 
985
#if LCD_1_E_PORT_IS_IO == 1
986
sbi(LCD_1_E_DDR_REG, LCD_1_E_PIN  );                 
987
#endif        
988
sbi(LCD_1_E_PORT, LCD_1_E_PIN  ); 
989
 
990
#if NUMBER_OF_LCD_UNITS >= 3
991
#if LCD_2_E_PORT_IS_IO == 1
992
sbi(LCD_2_E_DDR_REG, LCD_2_E_PIN  );                 
993
#endif        
994
sbi(LCD_2_E_PORT, LCD_2_E_PIN  );
995
#endif 
996
 
997
/*------ Initialize lcd to 4 bit i/o mode -------*/
998
/* initial write to lcd is 8bit using delay since busy flag can't be checked here anyway */
999
    xy_coordinates[LCD_0].x=0;
1000
    xy_coordinates[LCD_0].y=0;
1001
    xy_coordinates[LCD_1].x=0;
1002
    xy_coordinates[LCD_1].y=0;
1003
#if NUMBER_OF_LCD_UNITS >=3
1004
    xy_coordinates[LCD_2].x=0;
1005
    xy_coordinates[LCD_2].y=0;
1006
#endif
1007
 
1008
 
1009
for(lcd_unit=0; lcd_unit<NUMBER_OF_LCD_UNITS; lcd_unit++)
1010
  {
1011
      select_lcd(lcd_unit);
1012
 
1013
      delay(LCD_POWER_ON_DELAY);                          /* Wait 20 milliseconds  */
1014
      lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
1015
      delay(LCD_INIT_DELAY);                              /* Wait 5 milliseconds */
1016
      lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
1017
      lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
1018
      lcd_write(LCD_FUNCTION_4BIT_1LINE, INIT_MODE);      /* set IO mode to 4bit */
1019
 
1020
      /* from now on the lcd accepts only 4 bit I/O, so we can use lcd_command() */    
1021
      /* function set: set how many lines the lcd unit has.  */
1022
      if(lcd_lines==1) { lcd_command(LCD_FUNCTION_4BIT_1LINE);  }  
1023
      else { lcd_command(LCD_FUNCTION_4BIT_2LINES); }
1024
 
1025
      lcd_command(LCD_DISP_OFF);                               /* display off                  */
1026
      lcd_clrscr();                                            /* display clear                */ 
1027
      lcd_command(LCD_MODE_DEFAULT);                           /* set entry mode               */
1028
      lcd_command(LCD_DISP_ON);                                /* Display on                   */
1029
 
1030
  } 
1031
select_lcd(0);
1032
 
1033
return;  
1034
}/* lcd_init */
1035
 
1036
#endif
1037
/*######################################################################################################*/
1038
/*                                         T H E   E N D                                                */
1039
/*######################################################################################################*/
1040