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