1 | /*
|
2 | Copyright: Radig Ulrich mailto: mail@ulrichradig.de
|
3 | Author: Radig Ulrich
|
4 | Remarks:
|
5 | known Problems: none
|
6 | Version: 28.05.2004
|
7 | Description: Programm zur Ansteuerung eines Standart LCD
|
8 | (HD44870),(SED1278F) und kompatible
|
9 | */
|
10 |
|
11 | #include <lcd.h>
|
12 |
|
13 | //Prototypes
|
14 | void Write_LCD (char,char);
|
15 | char Read_LCD (char);
|
16 | void LCD_Init (void);
|
17 | void LCD_Clear (void);
|
18 | void LCD_Print (char,char,char *Buffer,...);
|
19 |
|
20 | void LCD_Init (void)
|
21 | {
|
22 | char tmp = Init_LCD_Zeilen;
|
23 | //Set Port Direction Register to Output for LCD Databus und LCD
|
24 | Steuerbus
|
25 | LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
|
26 | //Wait a short Time afer Power on
|
27 | for (int a=0;a<3000;a++)
|
28 | {
|
29 |
|
30 | }
|
31 | Write_LCD (0x22,0); //Init in 4 Bit Mode
|
32 | //Wait a short Time afer Power on
|
33 | for (int a=0;a<3000;a++)
|
34 | {
|
35 | for (int b=0;b<100;b++);
|
36 | }
|
37 | Write_LCD (0x22,0); //Init in 4 Bit Mode (Zur Sicherheit nochmal)
|
38 | if (tmp == 1)
|
39 | {
|
40 | Write_LCD (0x20,0); //1 Zeilen
|
41 | }
|
42 | else
|
43 | {
|
44 | Write_LCD (0x28,0); //mehrere Zeilen
|
45 | }
|
46 | Write_LCD (0x0C,0); //Display On
|
47 | Write_LCD (0x80,0); //Set DD-Ram Adresse = 0
|
48 | }
|
49 |
|
50 | void Write_LCD (char Data,char CD)
|
51 | {
|
52 | //Set Port Direction Register to Output for LCD Databus und LCD
|
53 | Steuerbus
|
54 | LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
|
55 | //Soll ins Seuer oder Datenregister geschrieben werden?
|
56 | if (CD == 0)
|
57 | {
|
58 | cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
|
59 | }
|
60 | else
|
61 | {
|
62 | sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
|
63 | }
|
64 | //Schreibsignal setzen
|
65 | cbi(LCD_Port_Write,LCD_RW); //Zum Schreiben RW-Pin = Low
|
66 | //Schreiben der 1. 4Bit an das LCD Display
|
67 | LCD_Port_Write = (LCD_Port_Write&0xF0) + ((Data&0xF0)>>4); //Write
|
68 | Nibbel MSB
|
69 | sbi(LCD_Port_Write,LCD_E);
|
70 | cbi(LCD_Port_Write,LCD_E);
|
71 | //Schreiben der 2. 4Bit an das LCD Display
|
72 | LCD_Port_Write = (LCD_Port_Write&0xF0) + (Data&0x0F); //Write Nibbel
|
73 | LSB
|
74 | sbi(LCD_Port_Write,LCD_E);
|
75 | cbi(LCD_Port_Write,LCD_E);
|
76 |
|
77 |
|
78 | }
|
79 |
|
80 | char Read_LCD (char CD)
|
81 | {
|
82 | char Data;
|
83 | //Set Port Direction Register to Output for LCD Databus und LCD
|
84 | Steuerbus
|
85 | LCD_Port_DDR = LCD_DataInput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
|
86 | //Lesesignal setzen
|
87 | sbi(LCD_Port_Write,LCD_RW); //Zum Lesen RW-Pin = High
|
88 | //Soll ins Seuer oder Datenregister geschrieben werden?
|
89 | if (CD == 0)
|
90 | {
|
91 | cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
|
92 | }
|
93 | else
|
94 | {
|
95 | sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
|
96 | }
|
97 | sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
|
98 | for (int a=0;a<100;a++) //Wartet ein bisschen bis daten anliegen
|
99 | {
|
100 | }
|
101 | Data = (LCD_Port_Read&0x0F)<<4; //Lesen des 1. Nibble (MSB)
|
102 | cbi(LCD_Port_Write,LCD_E);
|
103 |
|
104 | sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
|
105 | for (int a=0;a<100;a++) //Wartet ein bisschen bis daten anliegen
|
106 | {
|
107 | }
|
108 | Data += (LCD_Port_Read&0x0F); //Lesen des 2. Nibble (LSB)
|
109 | cbi(LCD_Port_Write,LCD_E);
|
110 | return(Data);
|
111 | }
|
112 |
|
113 | void LCD_Print (char zeile,char spalte,char *Buffer,...)
|
114 | {
|
115 | // Hilfsvariable zum Zählen der ausgegebenen Zeichen
|
116 | char nFieldWidth = 0;
|
117 |
|
118 | struct {
|
119 | char fLeftJust:1; // Feldausrichtung links oder rechts
|
120 | char fNegative:1; // Auszugebende Zahl ist negativ.
|
121 | } flags;
|
122 |
|
123 | #define SCRATCH 16
|
124 | unsigned char scratch[SCRATCH];
|
125 | unsigned char format_flag;
|
126 | unsigned int u_val=0, base=0;
|
127 | unsigned char *ptr;
|
128 | char hexA = 'a';
|
129 | char *p;
|
130 | int n;
|
131 | int nLen;
|
132 | va_list ap;
|
133 |
|
134 | va_start (ap, Buffer);
|
135 | //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
|
136 | if (zeile >= Init_LCD_Zeilen) //wurden mehr Zeilen angegeben als
|
137 | Initialisiert
|
138 | {
|
139 | zeile = Init_LCD_Zeilen - 1;
|
140 | }
|
141 | zeile = 0x80/Init_LCD_Zeilen*zeile;
|
142 | zeile += spalte;
|
143 | if (zeile >= 0x80) //ist der Wert ausserhalb des DD-Ram Adresse
|
144 | {
|
145 | zeile = 0x7F;
|
146 | }
|
147 | zeile += 0x80;
|
148 | Write_LCD (zeile,0);
|
149 |
|
150 | while (*Buffer != 0)
|
151 | {
|
152 | if (*Buffer == '%')
|
153 | {
|
154 | *Buffer++;
|
155 | switch (format_flag = *Buffer++){
|
156 |
|
157 | case 'c':
|
158 | format_flag = va_arg(ap,int);
|
159 | Write_LCD (format_flag++,1);
|
160 |
|
161 | case 'i':
|
162 | case 'd':
|
163 | case 'u':
|
164 | base = 10;
|
165 | goto CONVERSION_LOOP;
|
166 | case 'o':
|
167 | base = 8;
|
168 | goto CONVERSION_LOOP;
|
169 |
|
170 | case 'X':
|
171 | hexA = 'A';
|
172 | // Weiter wie 'x'
|
173 | case 'x':
|
174 | base = 16;
|
175 | }
|
176 |
|
177 | CONVERSION_LOOP:
|
178 | u_val = va_arg (ap, int);
|
179 | n = u_val;
|
180 | flags.fNegative = 0;
|
181 | if (format_flag == 'd' || format_flag == 'i') {
|
182 | // Negative Werte auswerten
|
183 | if (((int) u_val) < 0) {
|
184 | flags.fNegative = 1;
|
185 | u_val = -u_val;
|
186 | }
|
187 | }
|
188 | // Der Scratchpuffer wird von rechts nach links
|
189 | aufgefüllt
|
190 | // beginnend mit dem niederwertigsten Digit.
|
191 | ptr = scratch + SCRATCH;
|
192 | *--ptr = 0; // Abschliessendes NULL-Byte eintragen
|
193 | do
|
194 | {
|
195 | char ch = u_val % base + '0';
|
196 | if (ch > '9') ch += hexA - '9' - 1;
|
197 | *--ptr = ch;
|
198 | u_val /= base;
|
199 | } while (u_val);
|
200 |
|
201 | if (n < base) *--ptr = '0';
|
202 | if (flags.fNegative) *--ptr = '-';
|
203 | // Länge bestimmen
|
204 | p = ptr;
|
205 | nLen = 0;
|
206 | while (*p++) nLen++;
|
207 | // Feld bei Bedarf links auffüllen
|
208 | if (!flags.fLeftJust) {
|
209 | for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
|
210 | }
|
211 | // Pufferinhalt schreiben
|
212 | for (n=0; n < nLen; n++) Write_LCD (*ptr++,1);
|
213 | // Feld bei Bedarf rechts auffüllen
|
214 | if (flags.fLeftJust) {
|
215 | for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
|
216 | }
|
217 | }
|
218 | Write_LCD (*Buffer++,1);
|
219 | }
|
220 | va_end(ap);
|
221 | }
|
222 |
|
223 | void LCD_Clear (void)
|
224 | {
|
225 | Write_LCD (1,0); //Clear Display
|
226 | Write_LCD (0x80,0); //Set DD-Ram Adresse = 0
|
227 | }
|