1 | /*------------------------------------------------------------------------------
|
2 | Copyright: Radig Ulrich mailto: mail@ulrichradig.de
|
3 | Author: Radig Ulrich
|
4 | Remarks:
|
5 | known Problems: none
|
6 | Version: 22.11.2007
|
7 | Description: Programm zur Ansteuerung eines Standart LCD
|
8 | (HD44870),(SED1278F) und kompatible
|
9 | ------------------------------------------------------------------------------*/
|
10 |
|
11 | #include <stdlib.h>
|
12 | #include <stdarg.h>
|
13 | #include <ctype.h>
|
14 | #include <string.h>
|
15 | #include <avr/io.h>
|
16 | #include <avr/pgmspace.h>
|
17 |
|
18 | #include "lcd.h"
|
19 |
|
20 | const char LINE_ADDRESS[] ={0x80,0xC0,0x90,0xD0}; //2 x 16;4 x 16 uvm.
|
21 | //const char LINE_ADDRESS[] ={0x80,0xC0,0x94,0xD4}; //4 mal 20
|
22 | volatile unsigned char back_light = 0;
|
23 |
|
24 | //------------------------------------------------------------------------------
|
25 |
|
26 | void enable(void)
|
27 | {
|
28 | PORT_LCD_DATA_ENABLE |= (1<<LCD_DATA_ENABLE);
|
29 | NOP();
|
30 | NOP();
|
31 | PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
|
32 | }
|
33 |
|
34 | void Clock (void)
|
35 | {
|
36 | PORT_LCD_CLOCK |= (1<<LCD_CLOCK); //Clock PIN (High)
|
37 | NOP();
|
38 | NOP();
|
39 | PORT_LCD_CLOCK &= ~(1<<LCD_CLOCK); //Clock PIN (Low)
|
40 | }
|
41 | void shift_out(char data, char cd)
|
42 | {
|
43 | unsigned int h_nibble;
|
44 | unsigned int l_nibble;
|
45 |
|
46 | h_nibble |= (data & 0xF0)>>1;
|
47 | Clock();
|
48 | shift_data_out(h_nibble);
|
49 | enable();
|
50 |
|
51 | l_nibble|= (data&0x0F)<<3;
|
52 | Clock();
|
53 | shift_data_out(l_nibble);
|
54 | enable();
|
55 | }
|
56 |
|
57 | void lcd_init (void)
|
58 | {
|
59 | //Set Port Direction Register
|
60 |
|
61 | DDR_LCD_DATA_ENABLE |= (1<<LCD_DATA_ENABLE);
|
62 | DDR_LCD_CLOCK |= (1<<LCD_CLOCK);
|
63 | DDR_LCD_DATA |= (1<<LCD_DATA);
|
64 | PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
|
65 |
|
66 | //Wait a short Time afer Power on
|
67 | WAIT(20);
|
68 | lcd_clear();
|
69 | enable();
|
70 | for (unsigned char a=0;a<3;a++)
|
71 | {
|
72 | shift_out() (0x22,0); //Init in 4 Bit Mode
|
73 | WAIT(5);
|
74 | enable();
|
75 | }
|
76 | WAIT(10);
|
77 | lcd_write(0x80,0);
|
78 | Clock();
|
79 | enable();
|
80 | WAIT(10);
|
81 | lcd_write(0x80,0);
|
82 | Clock();
|
83 | enable();
|
84 | WAIT(10);
|
85 |
|
86 | #ifdef ONE_LINES
|
87 | lcd_write (0x22,0); //1 Zeilen
|
88 | enable();
|
89 | #else
|
90 | lcd_write (0x28,0); //mehrere Zeilen
|
91 | enable();
|
92 | #endif
|
93 | lcd_write (0xD0,0); //Display On
|
94 | enable();
|
95 | }
|
96 |
|
97 | //------------------------------------------------------------------------------
|
98 | void lcd_write (char data,char cd)
|
99 | {
|
100 | WAIT(BUSY_WAIT_US);
|
101 |
|
102 | unsigned char h_byte = 0;
|
103 | unsigned char l_byte = 0;
|
104 |
|
105 | //Soll ins Seuer oder Datenregister geschrieben werden?
|
106 | if(cd)
|
107 | {
|
108 | h_byte |= (1<<LCD_RS_PIN);
|
109 | l_byte |= (1<<LCD_RS_PIN);
|
110 | }
|
111 |
|
112 | if(back_light)
|
113 | {
|
114 | h_byte |= (1<<LCD_LIGHT_PIN);
|
115 | l_byte |= (1<<LCD_LIGHT_PIN);
|
116 | }
|
117 |
|
118 | h_byte |= (data&0xF0)>>1; //Write Nibbel MSB
|
119 | l_byte |= (data&0x0F)<<3; //Write Nibbel LSB
|
120 |
|
121 | //Schreiben der 1. 4Bit an das LCD Display
|
122 | shift_data_out(h_byte);
|
123 |
|
124 | //Schreiben der 2. 4Bit an das LCD Display
|
125 | shift_data_out(l_byte);
|
126 | }
|
127 |
|
128 | //------------------------------------------------------------------------------
|
129 | void shift_data_out (char byte)
|
130 | {
|
131 | for (unsigned char a=8; a>0; a--)
|
132 | {
|
133 | if ( (byte & (1<<(a-1))) != 0)
|
134 | {
|
135 | PORT_LCD_DATA |= (1<<LCD_DATA); //Data PIN (High)
|
136 | }
|
137 | else
|
138 | {
|
139 | PORT_LCD_DATA &= ~(1<<LCD_DATA); //Data PIN (LOW)
|
140 | }
|
141 | Clock();
|
142 | }
|
143 |
|
144 | enable();
|
145 | }
|
146 |
|
147 | //------------------------------------------------------------------------------
|
148 | void lcd_print_P (unsigned char zeile,unsigned char spalte,const char *Buffer,...)
|
149 | {
|
150 | va_list ap;
|
151 | va_start (ap, Buffer);
|
152 |
|
153 | int format_flag;
|
154 | char str_buffer[10];
|
155 | char str_null_buffer[10];
|
156 | char move = 0;
|
157 | char Base = 0;
|
158 | int tmp = 0;
|
159 | char by;
|
160 | char *ptr;
|
161 |
|
162 | //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
|
163 | zeile = LINE_ADDRESS[zeile];
|
164 | zeile += spalte;
|
165 | lcd_write(zeile,0);
|
166 |
|
167 | //Ausgabe der Zeichen
|
168 | for(;;)
|
169 | {
|
170 | by = pgm_read_byte(Buffer++);
|
171 | if(by==0) break; // end of format string
|
172 |
|
173 | if (by == '%')
|
174 | {
|
175 | by = pgm_read_byte(Buffer++);
|
176 | if (isdigit(by)>0)
|
177 | {
|
178 |
|
179 | str_null_buffer[0] = by;
|
180 | str_null_buffer[1] = '\0';
|
181 | move = atoi(str_null_buffer);
|
182 | by = pgm_read_byte(Buffer++);
|
183 | }
|
184 |
|
185 | switch (by)
|
186 | {
|
187 | case 's':
|
188 | ptr = va_arg(ap,char *);
|
189 | while(*ptr) {lcd_write(*ptr++,1); }
|
190 | break;
|
191 | case 'b':
|
192 | Base = 2;
|
193 | goto ConversionLoop;
|
194 | case 'c':
|
195 | //Int to char
|
196 | format_flag = va_arg(ap,int);
|
197 | lcd_write (format_flag++,1);
|
198 | break;
|
199 | case 'i':
|
200 | Base = 10;
|
201 | goto ConversionLoop;
|
202 | case 'o':
|
203 | Base = 8;
|
204 | goto ConversionLoop;
|
205 | case 'x':
|
206 | Base = 16;
|
207 | //****************************
|
208 | ConversionLoop:
|
209 | //****************************
|
210 | itoa(va_arg(ap,int),str_buffer,Base);
|
211 | int b=0;
|
212 | while (str_buffer[b++] != 0){};
|
213 | b--;
|
214 | if (b<move)
|
215 | {
|
216 | move -=b;
|
217 | for (tmp = 0;tmp<move;tmp++)
|
218 | {
|
219 | str_null_buffer[tmp] = '0';
|
220 | }
|
221 | //tmp ++;
|
222 | str_null_buffer[tmp] = '\0';
|
223 | strcat(str_null_buffer,str_buffer);
|
224 | strcpy(str_buffer,str_null_buffer);
|
225 | }
|
226 | lcd_print_str (str_buffer);
|
227 | move =0;
|
228 | break;
|
229 | }
|
230 |
|
231 | }
|
232 | else
|
233 | {
|
234 | lcd_write (by,1);
|
235 | }
|
236 | }
|
237 | va_end(ap);
|
238 | }
|
239 |
|
240 | //------------------------------------------------------------------------------
|
241 | void lcd_print_str (char *Buffer)
|
242 | {
|
243 | while (*Buffer != 0)
|
244 | {
|
245 | lcd_write (*Buffer++,1);
|
246 | };
|
247 | }
|
248 |
|
249 | //------------------------------------------------------------------------------
|
250 | void lcd_clear (void)
|
251 | {
|
252 | lcd_write (1,0); //Clear Display
|
253 | lcd_write (0x80,0); //Set DD-Ram Adresse = 0
|
254 |
|
255 | }
|