Subversion Repositories svnkaklik

Rev

Rev 359 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
359 kaklik 1
/*******************************************************************************************************
2
 Title  :   C include file for the HD44780U LCD library (lcd_io.c)
3
 Author:    Chris efstathiou hendrix@otenet.gr
4
 Date:      1/Jul/2002
5
 Software:  AVR-GCC with AVR-AS
6
 Target:    any AVR device
7
 Comments:  This software is FREE.
8
 
9
 DESCRIPTION
10
       Basic routines for interfacing a HD44780U-based text lcd display
11
       Based on Volker Oth's lcd library (http://members.xoom.com/volkeroth),
12
       Peter Fleury's work <pfleury@gmx.ch>  http://jump.to/fleury .
13
       and the very good lcd page at www.myke.com
14
 
15
       With this driver you can select from 2 different I/O modes.
16
       1) MODE 6 - 6 or 7  pin I/O mode
17
       2) MODE 2 - 2 pin I/O mode with an additional 74LS174
18
       3) MODE 7 - multiple lcd unit mode 
19
 
20
MODE 6 INFORMATION
21
       mode 6 now needs only 6 pins as long the pins can function as output
22
       freeing two bits to be used as general i/o.
23
       R/W pin on the lcd must be connected to ground.
24
       Also the pins can be scattered all over the place (any pin in any port).
25
       ( the other pins of the port(s) are not affected )
26
       Be carefull not to change the status of the E lcd pin by using the outp()
27
       command (both in PORT(X) and DDR(X) ) elsewhere in your  program  otherwise
28
       your program will crash and you will have a lot of fun for the whole family.
29
       Use sbi() and cbi() commands instead.
30
 
31
MODE 7 INFORMATION
32
       mode 7 supports up to 3 lcd units and all the characteristics of mode 6
33
       except that lcd reading is not possible.
34
       The lcd diplays can be of different type.
35
 
36
 
37
MODE 2 INFORMATION
38
       mode 2 uses only 2 pins in any combination you want as long the pin
39
       can function as output.
40
       You also need to make a very simple cirquit (really silly) with 74LS174.
41
       See the included JPG photo for the schematic.
42
       Also the pins can be scattered all over the place (any pin in any port).
43
       ( the other pins of the port(s) are not affected )
44
       YOU MAY NOT! MULTIPLEX THE DATA AND CLOCK PINS WITH OTHER DEVICES 
45
       The pins are automatically set as outputs when you call an lcd function
46
       Be carefull not to change the status of the CLOCK and DATA pins by using the outp()
47
       command (both in PORT(X) and DDR(X) ) elsewhere in your  program  otherwise
48
       your program will crash and you will have a lot of fun for the whole family (again!).
49
       Use sbi() and cbi() commands instead.     
50
 
51
       MEMORY MAPPED MODE IS NOT SUPPORTED BY THIS DRIVER !!!
52
 
53
CAUTION!!!  FOR SLOW LCD UNITS INCREASE THE "LCD_DELAY_TIME"  VALUE!!!  
54
            The driver does not read anything back from the lcd because that way i only need 6
55
            I/O lines and furthermore i can use the output only port found in MEGA103.
56
            Since i dont read anything back, i just wait for commands to be executed
57
            so below i define the time to wait for the two categories of commands of HD44780 .    
58
            The two CATEGORIES are:
59
            1) 2ms for clear screen and return home commands (nominal value=1,52 ms)
60
               and it is derived from "LCD_DELAY_TIME" .  
61
            2) 50us for all other commands (nominal value=37 us) 
62
 
63
            Even the slowest units will work reliably with LCD_DELAY_TIME=160. 
64
            The Longer delay needed for CATEGORY 1 is calculated from the "LCD_DELAY_TIME" value.
65
            The specifications for HD44780 @ 270KHZ are 37 us for CATEGORY 2 and 1,52 ms for CATEGORY 1 
66
 
67
LCD MODULE INFORMATION!
68
       The maximum time required by each instruction for the slowest lcd units is
69
       4.1 msecs for clearing the display or moving the cursor/display to the "home position",
70
       160 usecs for all other commands. (i use 50 because i use good units)  
71
 
72
       Usual HD44780 Pins connections 
73
       1 = Ground 
74
       2 = Vcc 
75
       3 = Contrast Voltage 
76
       4 = "R/S" _Instruction/Register Select 
77
       5 = "R/W" _Read/Write LCD Registers (Connected to GND for this driver to work!) 
78
       6 = "E" Clock 
79
       7 - 14 = Data I/O Pins 0 to 7 (0=7, 1=8,... 7=14 )
80
       15 - GND for the BACKLIGHTING (Check to be sure because some units have it for VCC)
81
       16 - VCC for the BACKLIGHTING (Check to be sure because some units have it for GND)
82
 
83
CONNECTION TABLE AS USED IN THIS lcd_io.h FILE       
84
      |^^^^^^^^^^^^^^^^^^^^^^^^^^|  
85
      |  port_pin0->lcd_D4_pin11 |
86
      |  port_pin1->lcd_D5_pin12 |
87
      |  port_pin2->lcd_D6_pin13 |
88
      |  port_pin3->lcd_D7_pin14 |
89
      |  port_pin4->lcd_RS_pin4  |
90
      |  port_pin5->lcd_E_pin6   |
91
      |  lcd_E_pin5->GND         |
92
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
93
 
94
*******************************************************************************************************/
95
#ifndef LCD_IO_H
96
#define LCD_IO_H
97
 
98
/*############################################################################################*/
99
/* CONFIGURATION BLOCK STARTS HERE. Change these definitions to adapt setting */
100
/*############################################################################################*/
101
/* GLOBAL SETTINGS (settings described here are aplyied everywhere) */
102
 
103
#ifndef F_CPU
104
#define F_CPU                     3686400L  /* CPU CLOCK FREQUENCY         */
105
#endif
106
 
107
#define LCD_IO_MODE               6         /* 6 = 6 PIN I/O, 2 = 2 PIN I/O, 7 = multi lcd mode */
108
 
109
#define LCD_AUTO_LINE_FEED        0         /* 1 = Auto line feed, 0 = no Auto line feed */
110
 
111
#define LCD_DELAY_TIME            100       /* Read the INTRO about this  */ 
112
 
113
/***********************************************************************************************/
114
#if LCD_IO_MODE == 2     
115
/* 
116
   CONFIGURATION OF BELOW LINES ONLY NECESSARY IN 2 PIN MODE  
117
   If you plan to use just one port for all pins then just edit "LCD_PORT" 
118
   otherwise you must specify the port of each lcd signal. the port(s) must be able
119
   to function as output.  It can be any combination!
120
   USE CAPITAL LETTER FOR PORT DESIGNATION! (A,B,C,D...etc.)
121
*/                             
122
#define LCD_CHARS_PER_LINE       20        /* visible chars per lcd line */
123
#define LCD_LINES                4         /* visible lines */
124
 
125
#define LCD_PORT                 B  
126
 
127
#define LCD_CLOCK_SIGNAL_PORT    LCD_PORT      /* Put your lcd clock port here (A,B,C...etc.)  */
128
#define LCD_CLOCK_PIN            0             /* Put your lcd clock pin here */
129
 
130
#define LCD_DATA_SIGNAL_PORT     LCD_PORT      /* Put your lcd data port here (A,B,C...etc.)    */
131
#define LCD_DATA_PIN             1             /* Put your lcd data pin here */
132
 
133
#endif
134
/***********************************************************************************************/
135
/* END OF 2 PIN CONFIGURATION BLOCK  */
136
/***********************************************************************************************/
137
#if LCD_IO_MODE == 6 
138
/* 
139
    CONFIGURATION OF BELOW LINES ONLY NECESSARY IN MODE 6 
140
    If you plan to use just one port for all pins then just edit "LCD_PORT" 
141
    otherwise you must specify the port of each lcd signal. the port(s) must be able
142
    to function as output.   It can be any combination!  
143
    PUT YOUR LCD PORT LETTER HERE USING CAPITAL LETTER (A,B,C,D...etc)
144
*/
145
#define LCD_CHARS_PER_LINE       20        /* visible chars per lcd line */
146
#define LCD_LINES                4         /* visible lines */
147
 
148
#define LCD_MULTIPLEX_ENABLE     0                /* 1= the DDR's used are saved and restored */
149
#define LCD_READ_REQUIRED        0                /* 0=use delay, 1=read busy flag (7 pins needed) */
150
 
151
 
152
 
153
#define LCD_PORT                 B   
154
 
155
#define LCD_DATA4_PORT           LCD_PORT         /* port for data 0 pin  */
156
#define LCD_D4_PIN               0                /* AVR port pin number */
157
 
158
#define LCD_DATA5_PORT           LCD_PORT         /* port for data 1 pin  */ 
159
#define LCD_D5_PIN               1                /* AVR port pin number */
160
 
161
#define LCD_DATA6_PORT           LCD_PORT         /* port for data 2 pin  */
162
#define LCD_D6_PIN               2                /* AVR port pin number */       
163
 
164
#define LCD_DATA7_PORT           LCD_PORT         /* port for data 3 pin  */
165
#define LCD_D7_PIN               3                /* AVR port pin number */
166
 
167
#define LCD_RS_SIGNAL_PORT       LCD_PORT         /* port for RS line */
168
#define LCD_RS_PIN               4                /* AVR port pin number */
169
 
170
#define LCD_E_SIGNAL_PORT        LCD_PORT         /* port for Enable line */
171
#define LCD_E_PIN                5                /* AVR port pin number */
172
 
173
 
174
 
175
/* YOU NEED TO EDIT  "LCD_RW_SIGNAL_PORT" AND "LCD_RW_PIN" ONLY IF "LCD_READ_REQUIRED == 1" */
176
#if LCD_READ_REQUIRED == 1
177
#define LCD_RW_SIGNAL_PORT       LCD_PORT         /* port for R/W line */
178
#define LCD_RW_PIN               6                /* AVR port pin number */
179
#endif
180
 
181
#endif
182
/***********************************************************************************************/
183
/* END OF 6 PIN CONFIGURATION BLOCK  */
184
/***********************************************************************************************/
185
#if LCD_IO_MODE == 7
186
/* 
187
    CONFIGURATION OF BELOW LINES ONLY NECESSARY IN MODE 7
188
    If you plan to use just one port for all pins then just edit "LCD_PORT" 
189
    otherwise you must specify the port of each lcd signal. the port(s) must be able
190
    to function as output.   It can be any combination!  
191
    PUT YOUR LCD PORT LETTER HERE USING CAPITAL LETTER (A,B,C,D...etc)
192
*/
193
#define NUMBER_OF_LCD_UNITS      2         /* 2 or 3. if you set it to 1, mode 6 will be selected */
194
 
195
#define LCD_0_CHARS_PER_LINE     20        /* visible chars per lcd line */
196
#define LCD_0_LINES              4         /* visible lines */
197
 
198
#define LCD_1_CHARS_PER_LINE     20        /* visible chars per lcd line */
199
#define LCD_1_LINES              4         /* visible lines */
200
 
201
#if NUMBER_OF_LCD_UNITS >=3
202
#define LCD_2_CHARS_PER_LINE     20        /* visible chars per lcd line */
203
#define LCD_2_LINES              4         /* visible lines */
204
#endif
205
 
206
 
207
 
208
#define LCD_PORT                 B   
209
 
210
#define LCD_DATA4_PORT           LCD_PORT         /* port for data 0 pin  */
211
#define LCD_D4_PIN               0                /* AVR port pin number */
212
 
213
#define LCD_DATA5_PORT           LCD_PORT         /* port for data 1 pin  */ 
214
#define LCD_D5_PIN               1                /* AVR port pin number */
215
 
216
#define LCD_DATA6_PORT           LCD_PORT         /* port for data 2 pin  */
217
#define LCD_D6_PIN               2                /* AVR port pin number */       
218
 
219
#define LCD_DATA7_PORT           LCD_PORT         /* port for data 3 pin  */
220
#define LCD_D7_PIN               3                /* AVR port pin number */
221
 
222
#define LCD_RS_SIGNAL_PORT       LCD_PORT         /* port for RS line */
223
#define LCD_RS_PIN               4                /* AVR port pin number */
224
 
225
#define LCD_0_E_SIGNAL_PORT      LCD_PORT         /* port for Enable line */
226
#define LCD_0_E_PIN              5                /* AVR port pin number */
227
 
228
#define LCD_1_E_SIGNAL_PORT      LCD_PORT         /* port for Enable line */
229
#define LCD_1_E_PIN              6                /* AVR port pin number */
230
 
231
/* EDIT THE BELOW LINES IF YOU USE 3 LCD UNITS */
232
#if NUMBER_OF_LCD_UNITS >=3
233
#define LCD_2_E_SIGNAL_PORT      LCD_PORT         /* port for Enable line */
234
#define LCD_2_E_PIN              7                /* AVR port pin number */
235
#endif
236
 
237
#endif  /* LCD_IO_MODE == 7 */
238
 
239
/*############################################################################################*/
240
/*                            CONFIGURATION BLOCK ENDS HERE.                                  */
241
/*############################################################################################*/
242
 
243
/* you shouldn't need to change anything below this line */
244
 
245
/* Some clever thinking triks */
246
#if LCD_IO_MODE == 7 && NUMBER_OF_LCD_UNITS == 1
247
 
248
#undef  LCD_IO_MODE
249
#define LCD_IO_MODE          6
250
#define LCD_READ_REQUIRED    0
251
#define LCD_E_SIGNAL_PORT    LCD_0_E_SIGNAL_PORT
252
#define LCD_E_PIN            LCD_0_E_PIN 
253
#define LCD_CHARS_PER_LINE   LCD_0_CHARS_PER_LINE
254
#define LCD_LINES            LCD_0_LINES 
255
#undef  LCD_MULTIPLEX_ENABLE
256
#define LCD_MULTIPLEX_ENABLE 0
257
#undef  LCD_READ_REQUIRED
258
#define LCD_READ_REQUIRED    0
259
#undef  LCD_1_CHARS_PER_LINE     
260
#undef  LCD_1_LINES              
261
#undef  LCD_1_E_SIGNAL_PORT      
262
#undef  LCD_1_E_PIN              
263
 
264
 
265
#elif   LCD_IO_MODE == 7 && NUMBER_OF_LCD_UNITS > 1
266
 
267
#define LCD_0                0 
268
#define LCD_1                1
269
#define LCD_2                2
270
 
271
#endif /* #if LCD_IO_MODE == 7 && NUMBER_OF_LCD_UNITS == 1 */
272
 
273
/*-----------------------------------------------------------------------------------*/
274
/*  HD44780 PARAMETERS */
275
/*-----------------------------------------------------------------------------------*/
276
 
277
#define LCD_LINE_LENGTH          0x40     /* internal line length */
278
#define LCD_START_LINE1          0x00     /* DDRAM address of first char of line 1 */
279
#define LCD_START_LINE2          0x40     /* DDRAM address of first char of line 2 */
280
#define LCD_START_LINE3          0x14     /* DDRAM address of first char of line 3 */
281
#define LCD_START_LINE4          0x54     /* DDRAM address of first char of line 4 */
282
 
283
/* instruction register bit positions */
284
#define LCD_CLR                  0      /* DB0: clear display */
285
#define LCD_HOME                 1      /* DB1: return to home position */
286
#define LCD_ENTRY_MODE           2      /* DB2: set entry mode */
287
#define LCD_ENTRY_INC            1      /*   DB1: 1=increment, 0=decrement  */
288
#define LCD_ENTRY_SHIFT          0      /*   DB2: 1=display shift on        */
289
#define LCD_ON                   3      /* DB3: turn lcd/cursor on */
290
#define LCD_ON_DISPLAY           2      /*   DB2: turn display on */
291
#define LCD_ON_CURSOR            1      /*   DB1: turn cursor on */
292
#define LCD_ON_BLINK             0      /*     DB0: blinking cursor ? */
293
#define LCD_MOVE                 4      /* DB4: move cursor/display */
294
#define LCD_MOVE_DISP            3      /*   DB3: move display (0-> cursor) ? */
295
#define LCD_MOVE_RIGHT           2      /*   DB2: move right (0-> left) ? */
296
#define LCD_FUNCTION             5      /* DB5: function set */
297
#define LCD_FUNCTION_8BIT        4      /*   DB4: set 8BIT mode (0->4BIT mode) */
298
#define LCD_FUNCTION_2LINES      3      /*   DB3: two lines (0->one line) */
299
#define LCD_FUNCTION_10DOTS      2      /*   DB2: 5x10 font (0->5x7 font) */
300
#define LCD_CGRAM                6      /* DB6: set CG RAM address */
301
#define LCD_DDRAM                7      /* DB7: set DD RAM address */
302
#define LCD_BUSY                 7      /* DB7: LCD is busy */
303
 
304
/* set entry mode: display shift on/off, dec/inc cursor move direction */
305
#define LCD_ENTRY_DEC            0x04   /* display shift off, dec cursor move dir */
306
#define LCD_ENTRY_DEC_SHIFT      0x05   /* display shift on,  dec cursor move dir */
307
#define LCD_ENTRY_INC_           0x06   /* display shift off, inc cursor move dir */
308
#define LCD_ENTRY_INC_SHIFT      0x07   /* display shift on,  inc cursor move dir */
309
 
310
/* display on/off, cursor on/off, blinking char at cursor position */
311
#define LCD_DISP_OFF             0x08   /* display off                            */
312
#define LCD_DISP_ON              0x0C   /* display on, cursor off                 */
313
#define LCD_DISP_ON_BLINK        0x0D   /* display on, cursor off, blink char     */
314
#define LCD_DISP_ON_CURSOR       0x0E   /* display on, cursor on                  */
315
#define LCD_DISP_ON_CURSOR_BLINK 0x0F   /* display on, cursor on, blink char      */
316
 
317
/* move cursor/shift display */
318
#define LCD_MOVE_CURSOR_LEFT     0x10   /* move cursor left  (decrement)          */
319
#define LCD_MOVE_CURSOR_RIGHT    0x14   /* move cursor right (increment)          */
320
#define LCD_MOVE_DISP_LEFT       0x18   /* shift display left                     */
321
#define LCD_MOVE_DISP_RIGHT      0x1C   /* shift display right                    */
322
 
323
/* function set: set interface data length and number of display lines */
324
#define LCD_FUNCTION_4BIT_1LINE  0x20   /* 4-bit interface, single line, 5x7 dots */
325
#define LCD_FUNCTION_4BIT_2LINES 0x28   /* 4-bit interface, dual line,   5x7 dots */
326
#define LCD_FUNCTION_8BIT_1LINE  0x30   /* 8-bit interface, single line, 5x7 dots */
327
#define LCD_FUNCTION_8BIT_2LINES 0x38   /* 8-bit interface, dual line,   5x7 dots */
328
 
329
 
330
#define LCD_MODE_DEFAULT         ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )
331
 
332
 
333
 
334
/*-----------------------------------------------------------------------------------*/
335
/*  function prototypes */
336
/*-----------------------------------------------------------------------------------*/
337
 
338
extern void         lcd_init(void);
339
extern void         lcd_command(unsigned char cmd);
340
extern void         lcd_gotoxy(unsigned char lcd_x, unsigned char lcd_y);
341
extern void         lcd_clrscr(void);
342
extern void         lcd_clrline(unsigned char line);
343
extern void         lcd_home(void);
344
extern void         lcd_putc(unsigned char c);
345
extern void         lcd_puts(const unsigned char *s);
346
extern void         lcd_puts_p(const unsigned char *progmem_s);
347
extern void         lcd_puts_e(unsigned char *eeprom_s); 
348
extern void         lcd_puti(int value, unsigned char dot_position);
349
extern unsigned int lcd_getxy(void);
350
 
351
 
352
/*
353
1) Suppose we want to display a 16 bit var with a rvalue 0f 325
354
2) We give the command lcd_puti(var_name, 0); were var=325
355
   The display will show 325 
356
3) alternatives:
357
   a) We give the command lcd_puti(var_name,1);
358
      The display will show 32,5 
359
   b) We give the command lcd_puti(var_name,2);
360
      The display will show 3,25 
361
   c) We give the command lcd_puti(var_name,3);
362
      The display will show 0,325 
363
   d) We give the command lcd_puti(var_name,4);
364
      The display will show 0,0325 
365
   e) We give the command lcd_puti(var_name,1); var=-325
366
      The display will show -32,5
367
   f) We give the command lcd_puti(var_name,3); var=-325
368
      The display will show  -0,325
369
 
370
 */
371
/*
372
** macros for automatically storing string constant in program memory
373
*/
374
#ifndef P
375
#define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;})
376
#endif
377
#define lcd_puts_P(__s)         lcd_puts_p(P(__s))
378
 
379
#endif //LCD_IO_H
380
/*######################################################################################################*/
381
/*                                         T H E   E N D                                                */
382
/*######################################################################################################*/
383
 
384