Subversion Repositories svnkaklik

Rev

Go to most recent revision | Details | Last modification | View Log

Rev Author Line No. Line
507 kaklik 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
 
14
// What should be set and done before here
15
// ---------------------------------------
16
//
17
// #include <stdio.h>					// If you want to use printf, ...
18
//
19
// #define LCD_DATA				B		// 4 or 8 bits field (lsb bit of the port)
20
// #define LCD_DATA_BIT			4
21
// 
22
// #define LCD_RS				D		// Register Select (port and bit)
23
// #define LCD_RS_BIT			4		
24
//
25
// #define LCD_E				D		// Enable (port and bit)
26
// #define LCD_E_BIT			3
27
//
28
//
29
// // LCD Display Parameters
30
// #define LCD_INTERFACE_BITS	4		// 4 or 8 bit interface
31
// #define LCD_LINES			1		// 1 or 2 or 4 lines
32
// #define LCD_CHARS			20		// usualy 16 or 20, important for 4 line display only
33
//
34
// #include "lcd_hd44780.h"				// Use LCD Library
35
//
36
//
37
// How to use the library 
38
// ----------------------
39
//
40
// void lcd_init(void)		// Init LCD Display
41
//
42
// void lcd_home()			// Goto Home
43
//
44
// void lcd_clear()		// Clear Display
45
//
46
// void lcd_clear_home()	// Clear Display and Goto Home with no Cursor
47
//
48
// void lcd_cursor_on()	// Switch Cursor On
49
//
50
// void lcd_cursor_off()	// Switch Cursor Off
51
//
52
// void lcd_cursor_left()	// Move Cursor Left
53
//
54
// void lcd_cursor_right()	// Move Cursor Right
55
//
56
// void lcd_gotoxy(uint8_t x, uint8_t y)		// Move to Position (1,1 is the first position)
57
//
58
// int lcd_putc(char c)	// LCD Char Output
59
//
60
// int lcd_putc_stream(char c, FILE *unused)	// LCD Char Output (for Stream Library)
61
//
62
//
63
// How to use printf
64
// -----------------
65
//
66
// 1) Define FILE structure
67
//
68
// static FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putc_stream, NULL, _FDEV_SETUP_WRITE);
69
//
70
// 2) Connect it with standard output
71
//
72
// stdout = &lcd_stream;		// Connect stdout to LCD Stream
73
//
74
// 3) Use printf
75
//
76
// printf("\fHello World!\n------------");
77
//
78
// 4) Use special chars
79
//
80
//		\f	- clear display and goto home
81
//		\n	- goto the beginning of the next line
82
//		\r	- goto to the beginning of curent line
83
//		\b	- backspace
84
//		\v	- start and end definition of user defined char
85
//
86
//
87
// How to use User Defined symbols
88
// -------------------------------
89
//
90
// That is easy. Just print the definition to lcd. Look at the example
91
//
92
// printf("\v" "\x10" LCD_CHAR_BAT50 "\v");		// definition (redefines CGRAM content of the LCD)
93
// printf("Battery Status \x10");				// usage
94
//
95
//	\v				starts the definition
96
//	\x10			first (of eight) user defined char
97
//	LCD_CHAR_BAT50	half battery symbol, you can define more symbols here (up to 8)
98
//	\v				end of definition
99
//
100
 
101
 
102
// Check Defined Values and use Default Values if possible
103
// -------------------------------------------------------
104
 
105
// 1 / 2 / 4 Line
106
#ifndef LCD_CHARS
107
	#if LCD_LINES > 2
108
		#error "LCD: Undefined LCD_CHARS"
109
	#else
110
		// Dafault Value
111
		#define LCD_CHARS 20
112
	#endif
113
#endif
114
 
115
#ifndef LCD_LINE_1
116
	// Address of the 1st char on the 1st line
117
	#define LCD_LINE_1	0
118
#endif
119
 
120
#ifndef LCD_LINE_2
121
	// Address of the 1st char on the 2nd line
122
	#define LCD_LINE_2	64			
123
#endif
124
 
125
#ifndef LCD_LINE_3
126
	// Address of the 1st char on the 3rd line
127
	#define LCD_LINE_3	LCD_CHARS	
128
#endif
129
 
130
#ifndef LCD_LINE_4
131
	// Address of the 1st char on the 4th line
132
	#define LCD_LINE_4	(LCD_LINE_2 + LCD_CHARS)
133
#endif
134
 
135
// Data Interface
136
#if LCD_INTERFACE_BITS == 4
137
	#define LCD_DATA_MASK	(0x0F << LCD_DATA_BIT)
138
#elif LCD_INTERFACE_BITS==8
139
	#define LCD_DATA_MASK	(0xFF << LCD_DATA_BIT)
140
#else
141
	#error "LCD: Wrong Value: LCD_INTERFACE_BITS"
142
#endif
143
 
144
#if LCD_DATA_MASK > 0xFF
145
	#error "LCD: Value too Big: LCD_DATA_BIT"
146
#endif
147
 
148
 
149
// Need Delay Library
150
// ------------------
151
 
152
#ifndef F_CPU
153
	#error "LCD: Undefined F_CPU"
154
#endif
155
#include <util/delay.h>				// Delay Routines
156
 
157
 
158
// Need IO Pins
159
// ------------
160
 
161
#include <avr/io.h>					// Device Specific Defines
162
 
163
#define GLUE(a,b)			a##b
164
#define PORT(a)			    GLUE(PORT,a)
165
#define PIN(a)				GLUE(PIN,a)
166
#define DDR(a)				GLUE(DDR,a)
167
 
168
 
169
#define LCD_E_PORT			PORT(LCD_E)
170
#define LCD_E_DDR			DDR(LCD_E)
171
 
172
#define LCD_RS_PORT			PORT(LCD_RS)
173
#define LCD_RS_DDR			DDR(LCD_RS)
174
 
175
#define LCD_DATA_PORT		PORT(LCD_DATA)
176
#define LCD_DATA_DDR		DDR(LCD_DATA)
177
 
178
#ifdef LCD_RW
179
#define LCD_RW_PORT			PORT(LCD_RW)
180
#define LCD_RW_DDR			DDR(LCD_RW)
181
#endif
182
 
183
 
184
// LCD Chip Commands
185
// -----------------
186
 
187
// Comand Clear LCD Display
188
#define LCD_HD44780_CLR 		0x01
189
 
190
// Command Home Cursor
191
#define LCD_HD44780_HOME		0x02
192
 
193
// Command Entry Mode (increment/decrement, shift/no shift)
194
#define LCD_HD44780_ENTMODE(inc, shift) \
195
	(0x04 | ((inc)? 0x02: 0) | ((shift)? 1: 0))
196
 
197
#define LCD_HD44780_ENTMODE_DEF		LCD_HD44780_ENTMODE(1,0)	// Increment Position, No Shift
198
 
199
// Command Display Controll (display on/off, cursor on/off, cursor blinking on/off)
200
#define LCD_HD44780_DISPCTL(disp, cursor, blink) \
201
	(0x08 | ((disp)? 0x04: 0) | ((cursor)? 0x02: 0) | ((blink)? 1: 0))
202
 
203
#define LCD_HD44780_CURSORON		LCD_HD44780_DISPCTL(1,1,0)	// on, cursor on, 
204
#define LCD_HD44780_CURSOROFF		LCD_HD44780_DISPCTL(1,0,0)	// on, cursor off
205
 
206
// Command Cursor or Display Shift (shift display/cursor, left/right)
207
#define LCD_HD44780_SHIFT(shift, right) \
208
	(0x10 | ((shift)? 0x08: 0) | ((right)? 0x04: 0))
209
 
210
#define LCD_HD44780_CURSORLEFT		LCD_HD44780_SHIFT(0,0)
211
#define LCD_HD44780_CURSORRIGHT		LCD_HD44780_SHIFT(0,1)
212
 
213
// Command Function Set ( 4/8-bit interface / 1 or 2 lines )
214
#define LCD_HD44780_4BIT1LINE	0x20	// 4-bit 1-line  font 5x7
215
#define LCD_HD44780_4BIT2LINES	0x28	// 4-bit 2-lines font 5x7
216
#define LCD_HD44780_8BIT1LINE	0x30	// 8-bit 1-line  font 5x7
217
#define LCD_HD44780_8BIT2LINES	0x38	// 8-bit 2-lines font 5x7
218
 
219
// Select Apropriate Mode
220
#if LCD_INTERFACE_BITS==4
221
	#if LCD_LINES == 1
222
		#define LCD_HD44780_FNSET	LCD_HD44780_4BIT1LINE	// 4-bit 1-line
223
	#else
224
		#define LCD_HD44780_FNSET	LCD_HD44780_4BIT2LINES	// 4-bit 2-lines
225
	#endif
226
#elif LCD_INTERFACE_BITS==8
227
	#if LCD_LINES == 1 
228
		#define LCD_HD44780_FNSET	LCD_HD44780_8BIT1LINE	// 8-bit 1-line
229
	#else
230
		#define LCD_HD44780_FNSET	LCD_HD44780_8BIT2LINES	// 8-bit 2-lines
231
	#endif
232
#endif
233
 
234
 
235
// User Defined Chars
236
// ------------------
237
 
238
// Definitions only. 
239
// Because these definitions may be sent to lcd via printf, 
240
// it is impossible to contain 0 bytes (end of string in C) 
241
// so we ored 0x80 to each byte
242
 
243
#define LCD_CHAR_SPACE  "\x80\x80\x80\x80\x80\x80\x80\x80"      /* space (blank char)        */
244
#define LCD_CHAR_BAT100 "\x8E\x9F\x9F\x9F\x9F\x9F\x9F\x1F"      /* symbol battery full       */
245
#define LCD_CHAR_BAT50  "\x8E\x9F\x91\x91\x93\x97\x9F\x1F"      /* symbol baterry half       */
246
#define LCD_CHAR_BAT0   "\x8E\x9F\x91\x91\x91\x91\x91\x1F"      /* symbol baterry empty      */
247
#define LCD_CHAR_UP     "\x80\x84\x8E\x95\x84\x84\x84\x80"      /* symbol arrow up           */
248
#define LCD_CHAR_DOWN   "\x80\x84\x84\x84\x95\x8E\x84\x80"      /* symbol arrow down         */
249
#define LCD_CHAR_LUA    "\x84\x8E\x91\x91\x9F\x91\x91\x80"      /* A s carkou                */
250
#define LCD_CHAR_LLA    "\x81\x82\x8E\x81\x9F\x91\x8F\x80"      /* a s carkou                */
251
#define LCD_CHAR_HUC    "\x8A\x8E\x91\x90\x90\x91\x8E\x80"      /* C s hackem                */
252
#define LCD_CHAR_HLC    "\x8A\x84\x8E\x90\x90\x91\x8E\x80"      /* c s hackem                */
253
#define LCD_CHAR_HUD    "\x8A\x9C\x92\x91\x91\x92\x9C\x80"      /* D s hackem                */
254
#define LCD_CHAR_HLD    "\x85\x83\x8D\x93\x91\x91\x8F\x80"      /* d s hackem                */
255
#define LCD_CHAR_LUE    "\x84\x9F\x90\x90\x9E\x90\x9F\x80"      /* E s carkou                */
256
#define LCD_CHAR_LLE    "\x81\x82\x8E\x91\x9F\x90\x8E\x80"      /* e s carkou                */
257
#define LCD_CHAR_HUE    "\x8A\x9F\x90\x9E\x90\x90\x9F\x80"      /* E s hackem                */
258
#define LCD_CHAR_HLE    "\x8A\x84\x8E\x91\x9F\x90\x8E\x80"      /* e s hackem                */
259
#define LCD_CHAR_LUI    "\x84\x8E\x84\x84\x84\x84\x8E\x80"      /* I s carkou                */
260
#define LCD_CHAR_LLI    "\x82\x84\x80\x8C\x84\x84\x8E\x80"      /* i s carkou                */
261
#define LCD_CHAR_HUN    "\x8A\x95\x91\x99\x95\x93\x91\x80"      /* N s hackem                */
262
#define LCD_CHAR_HLN    "\x8A\x84\x96\x99\x91\x91\x91\x80"      /* n s hackem                */
263
#define LCD_CHAR_LUO    "\x84\x8E\x91\x91\x91\x91\x8E\x80"      /* O s carkou                */
264
#define LCD_CHAR_LLO    "\x82\x84\x8E\x91\x91\x91\x8E\x80"      /* o s carkou                */
265
#define LCD_CHAR_HUR    "\x8A\x9E\x91\x9E\x94\x92\x91\x80"      /* R s hackem                */
266
#define LCD_CHAR_HLR    "\x8A\x84\x96\x99\x90\x90\x90\x80"      /* r s hackem                */
267
#define LCD_CHAR_HUS    "\x8A\x8F\x90\x8E\x81\x81\x9E\x80"      /* S s hackem                */
268
#define LCD_CHAR_HLS    "\x8A\x84\x8E\x90\x8E\x81\x9E\x80"      /* s s hackem                */
269
#define LCD_CHAR_HUT    "\x8A\x9F\x84\x84\x84\x84\x84\x80"      /* T s hackem                */
270
#define LCD_CHAR_HLT    "\x8A\x8C\x9C\x88\x88\x89\x86\x80"      /* t s hackem                */
271
#define LCD_CHAR_LUU    "\x82\x95\x91\x91\x91\x91\x8E\x80"      /* U s carkou                */
272
#define LCD_CHAR_LLU    "\x82\x84\x91\x91\x91\x93\x8D\x80"      /* u s carkou                */
273
#define LCD_CHAR_CUU    "\x86\x97\x91\x91\x91\x91\x8E\x80"      /* U s krouzkem              */
274
#define LCD_CHAR_CLU    "\x86\x86\x91\x91\x91\x91\x8E\x80"      /* u s krouzkem              */
275
#define LCD_CHAR_LUY    "\x82\x95\x91\x8A\x84\x84\x84\x80"      /* Y s carkou                */
276
#define LCD_CHAR_LLY    "\x82\x84\x91\x91\x8F\x81\x8E\x80"      /* y s carkou                */
277
#define LCD_CHAR_HUZ    "\x8A\x9F\x81\x82\x84\x88\x9F\x80"      /* Z s hackem                */
278
#define LCD_CHAR_HLZ    "\x8A\x84\x9F\x82\x84\x88\x9F\x80"      /* z s hackem                */
279
 
280
 
281
// Program
282
// -------
283
 
284
 
285
static int8_t lcd_posx;		// Mirror Register with Position X (1..LCD_CHARS)
286
#if LCD_LINES > 1
287
static int8_t lcd_posy;		// Mirror Register with Position Y (1..LCD_LINES)
288
#endif
289
 
290
 
291
// Send a Nibble or Byte to the LCD COntroller
292
static void
293
lcd_send_nibble(uint8_t rs, uint8_t data)
294
{
295
	// Select Register or Data
296
	if (rs)
297
		LCD_RS_PORT |= (1<<LCD_RS_BIT);
298
 	else
299
		LCD_RS_PORT &= ~(1<<LCD_RS_BIT);
300
 
301
	// Put 4bit/8bit data
302
  	LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_DATA_MASK) | ((data<<LCD_DATA_BIT)&LCD_DATA_MASK);
303
 	_delay_us(1);	// Data Setup Time
304
 
305
	// Click Enable on and off
306
	LCD_E_PORT |= 1<<LCD_E_BIT;
307
 	_delay_us(1);
308
	LCD_E_PORT &= ~(1<<LCD_E_BIT);
309
	_delay_us(40);
310
}
311
 
312
 
313
// Send a Byte to the LCD Controller
314
#if LCD_INTERFACE_BITS == 4
315
static void
316
lcd_send_byte(uint8_t rs, uint8_t data)
317
{
318
 	lcd_send_nibble(rs, data >> 4);		// High Order Data
319
 	lcd_send_nibble(rs, data);			// Low Order Data
320
}
321
#else
322
	#define lcd_send_byte lcd_send_nibble
323
#endif
324
 
325
 
326
// Send a Command to the LCD Controller (RS=0)
327
#define lcd_send_cmd(n)		lcd_send_byte(0, (n))
328
 
329
 
330
// Send a Data Byte to the LCD Controller (RS=1)
331
#define lcd_send_data(n)	lcd_send_byte(1, (n))
332
 
333
 
334
// Goto Home
335
void 
336
lcd_home()
337
{
338
	lcd_send_cmd(LCD_HD44780_HOME);		// Zero Cursor Position and Offset
339
	#if LCD_LINES > 1
340
		lcd_posx=lcd_posy=1;
341
	#else
342
		lcd_posx=1;
343
	#endif
344
  	_delay_ms(2);
345
}
346
 
347
 
348
// Clear Display
349
void 
350
lcd_clear()
351
{
352
	lcd_send_cmd(LCD_HD44780_CLR);		// Clear Memory
353
  	_delay_ms(2);
354
}
355
 
356
 
357
// Switch Cursor On
358
void
359
lcd_cursor_on()
360
{
361
	lcd_send_cmd(LCD_HD44780_CURSORON);
362
}
363
 
364
 
365
// Switch Cursor Off
366
void
367
lcd_cursor_off()
368
{
369
	lcd_send_cmd(LCD_HD44780_CURSOROFF);
370
}
371
 
372
 
373
// Clear Display and Goto Home with no Cursor
374
void
375
lcd_clear_home()
376
{
377
	lcd_clear();		// Clear Memory
378
	lcd_home();			// Zero Cursor Position and Offset
379
	lcd_cursor_off();	// No Cursor
380
}
381
 
382
 
383
// Move to Position (1,1 is the first position)
384
void lcd_gotoxy(uint8_t x, uint8_t y)
385
{
386
	uint8_t Adr;
387
 
388
	Adr=x-1;
389
	#if LCD_LINES > 1
390
	switch (y)
391
	{
392
		case 2:
393
			Adr+=LCD_LINE_2;
394
			break;
395
		#if LCD_LINES > 2
396
		case 3:
397
			Adr+=LCD_LINE_3;
398
			break;
399
		case 4:
400
			Adr+=LCD_LINE_4;
401
			break;
402
		#endif
403
	}
404
	#endif
405
 
406
	lcd_send_cmd(0x80 | (Adr & 0x7F) );
407
	lcd_posx=x;
408
	#if LCD_LINES > 1
409
	lcd_posy=y;
410
	#endif
411
}
412
 
413
 
414
// Increment Position
415
void 
416
lcd_inc_pos()
417
{
418
	// Next Position
419
	lcd_posx++;
420
 
421
	// Correct End of Line
422
	#if LCD_LINES == 1
423
		if (lcd_posx > 40)
424
			lcd_posx = 1;
425
	#elif LCD_LINES == 2
426
		if (lcd_posx > 40)
427
		{
428
			lcd_posx = 1;
429
			lcd_posy++;		// on the Next Line
430
		}
431
	#elif LCD_LINES > 2
432
		if ( ((lcd_posy & 1) && (lcd_posx > LCD_CHARS))	// Odd Lines are Short
433
			|| (lcd_posx > 40-LCD_CHARS) )				// Memory is up to 40 Bytes
434
		{
435
			lcd_posx = 1;	// Position 1
436
			lcd_posy++;		// on the Next Line
437
		}
438
	#endif
439
 
440
	// Correct End of Last Line
441
	#if LCD_LINES > 1
442
	if (lcd_posy > LCD_LINES)
443
	{
444
		lcd_posy = 1;
445
	}
446
	#endif
447
}
448
 
449
// Decrement Position
450
void
451
lcd_dec_pos()
452
{
453
	// Correct Beginning of Line
454
	if (--lcd_posx==0)						// Step Left
455
	{										// If Beginning of the Line
456
		#if LCD_LINES > 1
457
			if(--lcd_posy==0);				// Step Up
458
				lcd_posy = LCD_LINES;		// If we are on Top Go to the Bottom
459
		#endif
460
		#if LCD_LINES <= 2
461
			lcd_posx = 40;				
462
		#else
463
			if(lcd_posy & 1)				// If Odd Line (the Short One)
464
				lcd_posx = LCD_CHARS;		// Set End of the Short Line
465
			else							// Else
466
				lcd_posx = 40-LCD_CHARS;	// Set End of Long Line
467
		#endif
468
	}
469
}
470
 
471
// Move Cursor Left
472
void
473
lcd_cursor_left()
474
{
475
	lcd_send_cmd(LCD_HD44780_CURSORLEFT);
476
	lcd_dec_pos();
477
}
478
 
479
 
480
// Move Cursor Right
481
void
482
lcd_cursor_right()
483
{
484
	lcd_send_cmd(LCD_HD44780_CURSORRIGHT);
485
	lcd_inc_pos();
486
}
487
 
488
 
489
// Init LCD Display
490
void
491
lcd_init(void)
492
{
493
	// Port Init Direction
494
	LCD_E_PORT  &= ~_BV(LCD_E_BIT);			// Enable off
495
	LCD_E_DDR  |= _BV(LCD_E_BIT);			// Enable as Output
496
  	LCD_RS_DDR |= _BV(LCD_RS_BIT);			// Register Select as Output
497
	#ifdef LCD_RW
498
		LCD_RW_DDR |= _BV(LCD_RW_BIT);		// Read Write as Output
499
	#endif
500
    LCD_DATA_DDR |= LCD_DATA_MASK;			// Data as Output
501
 
502
	// Initial Delay
503
  	_delay_ms(40);		// Delay for Vcc
504
 
505
	// Sync 8/4 bit Interface
506
	#if LCD_INTERFACE_BITS == 4
507
	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4);	// 8 bit mode - sync nibble/byte
508
  		_delay_ms(4.1);
509
	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4);
510
  		_delay_us(100);
511
	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE >> 4);
512
		// Set 4 bit mode
513
  		lcd_send_nibble(0, LCD_HD44780_FNSET >> 4);
514
	#elif  LCD_INTERFACE_BITS == 8
515
	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE);		// 8 bit mode - sync nibble/byte
516
  		_delay_ms(4.1);
517
		lcd_send_nibble(0, LCD_HD44780_8BIT1LINE);
518
  		_delay_us(100);
519
	  	lcd_send_nibble(0, LCD_HD44780_8BIT1LINE);
520
	#endif
521
 
522
	// Set and Init
523
	lcd_send_cmd(LCD_HD44780_FNSET);  		// 4/8 bits 1/2 lines	
524
	lcd_send_cmd(LCD_HD44780_ENTMODE_DEF);	// increment/decrement, shift/no shift
525
	lcd_clear_home();						// display on, no cursor, clear and home
526
}
527
 
528
 
529
// LCD Char Output
530
int
531
lcd_putc(char c)
532
{
533
	static uint8_t mode=0;
534
 
535
	switch (c)
536
	{
537
		case '\f':	
538
			lcd_clear_home();       // Clear Display
539
			break;
540
 
541
		case '\n':	
542
			#if LCD_LINES > 1
543
				if (lcd_posy <= LCD_LINES)	// Go to the Next Line
544
					lcd_posy++;
545
			#endif
546
 
547
 		case '\r':	
548
			#if LCD_LINES > 1
549
				lcd_gotoxy(1,lcd_posy);		// Go to the Beginning of the Line
550
			#else
551
				lcd_home();
552
			#endif
553
			break;
554
 
555
		case '\b':
556
			lcd_cursor_left();		// Cursor (Position) Move Back
557
			break;
558
 
559
		default:
560
			if (mode==0 && c=='\v')	// Startr of Definition String
561
			{
562
				mode=1;				// Mode Next Char will be Defined Char 
563
				break;
564
			}
565
			if (mode==1)			// First Char is Position Number
566
			{
567
				lcd_send_cmd(0x40 | ((c & 0x07)<<3) );	// Set CGRAM Address
568
				mode++;				// Mode Define Char Patern
569
				break;
570
			}
571
			if (mode==2 && c=='\v')	// End of Definition String
572
			{
573
				mode=0;
574
				#if LCD_LINES > 1
575
					lcd_gotoxy(lcd_posx,lcd_posy);
576
				#else
577
					lcd_gotoxy(lcd_posx,1);
578
				#endif
579
				break;
580
			}
581
			if (mode != 2)			// Ordinary Chars
582
			{
583
				if (c<0x20)			// Remap User Defind Char
584
					c &= 0x07;		// 	from rage 0x10-0x1F to 0x00-0x0f
585
				lcd_inc_pos();		// Next Position
586
				}
587
			lcd_send_data(c);		// Send Byte to LCD
588
			break;
589
	}
590
 
591
	return 0;	// Success
592
}
593
 
594
 
595
// LCD Char Output (for Stream Library)
596
#ifdef _STDIO_H_
597
static int
598
lcd_putc_stream(char c, FILE *unused)
599
{
600
	return lcd_putc(c);
601
}
602
#endif