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