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 | #include "lcd.h"
|
18 | #include <avr/delay.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 | _delay_ms(50);
|
30 |
|
31 | PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
|
32 | _delay_ms(50);
|
33 | }
|
34 |
|
35 | void Clock (void)
|
36 | {
|
37 | PORT_LCD_CLOCK |= (1<<LCD_CLOCK); //Clock PIN (High)
|
38 | _delay_ms(20);
|
39 |
|
40 | PORT_LCD_CLOCK &= ~(1<<LCD_CLOCK); //Clock PIN (Low)
|
41 | _delay_ms(20);
|
42 | }
|
43 |
|
44 | void lcd_char(char ps, char cd)
|
45 | {
|
46 | switch(ps)
|
47 | {
|
48 | case 'ä' : ps = 0xE1; break;
|
49 | case 'ö' : ps = 0xEF; break;
|
50 | case 'ü' : ps = 0xF5; break;
|
51 | case 'ß' : ps = 0xE2; break;
|
52 | case '°' : ps = 0xDF; break;
|
53 | case 'µ' : ps = 0xE4; break;
|
54 | case 'Ä' : ps = 0x00; break; // Point to CG-RAM
|
55 | case 'Ö' : ps = 0x01; break; // self defined characters
|
56 | case 'Ü' : ps = 0x02; break;
|
57 | }
|
58 | lcd_write(ps,1);
|
59 | }
|
60 |
|
61 | void lcd_init (void)
|
62 | {
|
63 | //Set Port Direction Register
|
64 |
|
65 | DDRB =0xff;
|
66 | DDR_LCD_DATA_ENABLE |= (1<<LCD_DATA_ENABLE);
|
67 | DDR_LCD_CLOCK |= (1<<LCD_CLOCK);
|
68 | DDR_LCD_DATA |= (1<<LCD_DATA);
|
69 | PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
|
70 |
|
71 | shift_data_out(0x02<<3);
|
72 | _delay_us(10);
|
73 | shift_data_out(0x02<<3);
|
74 | _delay_us(10);
|
75 |
|
76 | shift_data_out(0x08<<3);
|
77 | _delay_us(10);
|
78 |
|
79 | shift_data_out(0x00<<3);
|
80 | _delay_us(10);
|
81 |
|
82 |
|
83 | shift_data_out(0x0F<<3);
|
84 | _delay_us(10);
|
85 |
|
86 | shift_data_out(0x00<<3);
|
87 | _delay_us(10);
|
88 |
|
89 | shift_data_out(0x01<<3);
|
90 | _delay_us(10);
|
91 |
|
92 | shift_data_out(0x00<<3);
|
93 | _delay_us(10);
|
94 |
|
95 | shift_data_out(0x0C<<3);
|
96 | _delay_us(10);
|
97 | };
|
98 |
|
99 | //------------------------------------------------------------------------------
|
100 | void lcd_write (char data,char cd)
|
101 |
|
102 | {
|
103 | unsigned char h_nibble = 0;
|
104 | unsigned char l_nibble = 0;
|
105 |
|
106 | _delay_us(10);
|
107 |
|
108 | //Soll ins Steuer oder Datenregister geschrieben werden?
|
109 |
|
110 | if(cd)
|
111 | {
|
112 | h_nibble &=~ (1<<LCD_RS_PIN);
|
113 | }
|
114 | else
|
115 | {
|
116 | l_nibble |= (1<<LCD_RS_PIN);
|
117 | }
|
118 |
|
119 | if(back_light)
|
120 | {
|
121 | h_nibble |= (1<<LCD_LIGHT_PIN);
|
122 | l_nibble |= (1<<LCD_LIGHT_PIN);
|
123 | }
|
124 |
|
125 |
|
126 | h_nibble |= (data&0xF0)>>1; //Write Nibbel MSB
|
127 | _delay_ms(10);
|
128 | l_nibble |= (data&0x0F)<<3; //Write Nibbel LSB
|
129 | _delay_ms(10);
|
130 | //Schreiben der 1. 4Bit an das LCD Display
|
131 | shift_data_out(h_nibble);
|
132 |
|
133 | //Schreiben der 2. 4Bit an das LCD Display
|
134 | shift_data_out(l_nibble);
|
135 | };
|
136 |
|
137 | //------------------------------------------------------------------------------
|
138 | void shift_data_out (char byte)
|
139 | {
|
140 | for (unsigned char a=8; a>0; a--)
|
141 | {
|
142 | if ( (byte & (1<<(a-1))) != 0)
|
143 | {
|
144 | PORT_LCD_DATA |= (1<<LCD_DATA); //Data PIN (High)
|
145 |
|
146 | }
|
147 | else
|
148 | {
|
149 | PORT_LCD_DATA &= ~(1<<LCD_DATA); //Data PIN (LOW)
|
150 |
|
151 | }
|
152 | Clock();
|
153 | }
|
154 |
|
155 | enable();
|
156 | };
|
157 | //------------------------------------------------------------------------------
|
158 | void lcd_print_P (unsigned char zeile,unsigned char spalte,const char *Buffer,...)
|
159 | {
|
160 | va_list ap;
|
161 | va_start (ap, Buffer);
|
162 |
|
163 | int format_flag;
|
164 | char str_buffer[10];
|
165 | char str_null_buffer[10];
|
166 | char move = 0;
|
167 | char Base = 0;
|
168 | int tmp = 0;
|
169 | char by;
|
170 | char *ptr;
|
171 |
|
172 | //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
|
173 | zeile = LINE_ADDRESS[zeile];
|
174 | zeile += spalte;
|
175 | lcd_write(zeile,0);
|
176 |
|
177 | //Ausgabe der Zeichen
|
178 | for(;;)
|
179 | {
|
180 | by = *(Buffer++);
|
181 | if(by==0) break; // end of format string
|
182 |
|
183 | if (by == '%')
|
184 | {
|
185 | by = *(Buffer++);
|
186 | if (isdigit(by)>0)
|
187 | {
|
188 |
|
189 | str_null_buffer[0] = by;
|
190 | str_null_buffer[1] = '\0';
|
191 | move = atoi(str_null_buffer);
|
192 | by = *(Buffer++);
|
193 | }
|
194 |
|
195 | switch (by)
|
196 | {
|
197 | case 's':
|
198 | ptr = va_arg(ap,char *);
|
199 | while(*ptr) {lcd_write(*ptr++,1); }
|
200 | break;
|
201 | case 'b':
|
202 | Base = 2;
|
203 | goto ConversionLoop;
|
204 | case 'c':
|
205 | //Int to char
|
206 | format_flag = va_arg(ap,int);
|
207 | lcd_write (format_flag++,1);
|
208 | break;
|
209 | case 'i':
|
210 | Base = 10;
|
211 | goto ConversionLoop;
|
212 | case 'o':
|
213 | Base = 8;
|
214 | goto ConversionLoop;
|
215 | case 'x':
|
216 | Base = 16;
|
217 | //****************************
|
218 | ConversionLoop:
|
219 | //****************************
|
220 | itoa(va_arg(ap,int),str_buffer,Base);
|
221 | int b=0;
|
222 | while (str_buffer[b++] != 0){};
|
223 | b--;
|
224 | if (b<move)
|
225 | {
|
226 | move -=b;
|
227 | for (tmp = 0;tmp<move;tmp++)
|
228 | {
|
229 | str_null_buffer[tmp] = '0';
|
230 | }
|
231 | //tmp ++;
|
232 | str_null_buffer[tmp] = '\0';
|
233 | strcat(str_null_buffer,str_buffer);
|
234 | strcpy(str_buffer,str_null_buffer);
|
235 | }
|
236 | lcd_char(str_buffer,1);
|
237 | move =0;
|
238 | break;
|
239 | }
|
240 |
|
241 | }
|
242 | else
|
243 | {
|
244 | lcd_write (by,1);
|
245 | }
|
246 | }
|
247 | va_end(ap);
|
248 | };
|
249 |
|
250 | //------------------------------------------------------------------------------
|
251 | void lcd_print_str (char *Buffer)
|
252 | {
|
253 | while (*Buffer != 0)
|
254 | {
|
255 | lcd_char(*Buffer++,1);
|
256 | };
|
257 | };
|
258 |
|
259 | //------------------------------------------------------------------------------
|
260 | void lcd_clear (void)
|
261 | {
|
262 | lcd_write (1,0); //Clear Display
|
263 | lcd_write (0x80,0); //Set DD-Ram Adresse = 0
|
264 | }
|