1 | /********************************************************************
|
2 | * *
|
3 | * LCD-Text *
|
4 | * *
|
5 | *********************************************************************
|
6 | * *
|
7 | * Funktion: Textausgabe auf myAVR LCD-Display im 4-BitModus *
|
8 | * Schaltung: myAVR-Display am Stecker angesteckt *
|
9 | * PortD Bit 4-7: Daten *
|
10 | * PortD Bit 2: RS, high=Daten, low=Kommando *
|
11 | * PortD Bit 3: E, high-Impuls für gültige Daten *
|
12 | * *
|
13 | *********************************************************************
|
14 | * *
|
15 | * Autor: Prof. Dr.-Ing. U. Kosiedowski *
|
16 | * Version: 1.0 *
|
17 | * Datum: 13.04.2010 *
|
18 | * *
|
19 | ********************************************************************/
|
20 |
|
21 |
|
22 |
|
23 | //==================================================================
|
24 | // Funktion für LCD-Kommandos
|
25 | //==================================================================
|
26 | // Name: lcd_cmd(cmd)
|
27 | // Funktion: sendet ein Kommando an das LCD-Display
|
28 | // Argument: cmd: Kommando, 1 Byte
|
29 | //==================================================================
|
30 |
|
31 | #include <avr/io.h> // Bezeichnungen für Register
|
32 | #define F_CPU 3686400
|
33 | #include <util/delay.h>
|
34 | #include <stdint.h>
|
35 |
|
36 | void lcd_cmd(unsigned char cmd)
|
37 | {
|
38 | unsigned char tmp = cmd; // Kommando in Arbeitsvariable speichern
|
39 | tmp &= 0xF0; // unteres Halbbyte ausblenden, RS=0, E=0
|
40 | PORTD = tmp; // Signalausgabe
|
41 | tmp |= 0x08; // Bit 3 setzen -> E=1
|
42 | PORTD = tmp; // Signalausgabe
|
43 | tmp &= 0xF7; // Bit 3 rücksetzen -> E=0
|
44 | PORTD = tmp; // Signalausgabe
|
45 |
|
46 | tmp = cmd<<4; // Kommando unteres Halbbyte -> Arbeitsvariable
|
47 | PORTD = tmp; // Signalausgabe
|
48 | tmp |= 0x08; // Bit 3 setzen -> E=1
|
49 | PORTD = tmp; // Signalausgabe
|
50 | tmp &= 0xF7; // Bit 3 rücksetzen -> E=0
|
51 | PORTD = tmp; // Signalausgabe
|
52 | _delay_ms(1); // Verzögerung 1ms -> Ausführung
|
53 | }
|
54 |
|
55 | //==================================================================
|
56 | // Funktion zur Anzeige einer Zeichenkette
|
57 | //==================================================================
|
58 | // Name: lcd_text(char* pText)
|
59 | // Funktion: sendet eine Zeichenkette an das LCD-Display
|
60 | // Zeichenkette muss mit 0x00 abgeschlossen sein
|
61 | // Argument: cmd: Zeiger auf Anfang der Zeichenkette, 1 Byte
|
62 | //==================================================================
|
63 | void lcd_text(char* pText)
|
64 | {
|
65 | int j = 0; // Zählvariable für Zeichen
|
66 | while(pText[j]!=0) // Ausgabe bis 0-Zeichen als Ende-Kennung
|
67 | {
|
68 | unsigned char tmp = pText[j]; // Text in Arbeitsvariable speichern
|
69 | tmp &= 0xF0; // unteres Halbbyte ausblenden, RS=1, E=0
|
70 | tmp |= 0x04; // Bit 2 setzen -> RS=1
|
71 | PORTD = tmp; // Signalausgabe
|
72 | tmp |= 0x08; // Bit 3 setzen -> E=1
|
73 | PORTD = tmp; // Signalausgabe
|
74 | tmp &= 0xF7; // Bit 3 rücksetzen -> E=0
|
75 | PORTD = tmp; // Signalausgabe
|
76 |
|
77 | tmp = pText[j]<<4; // Kommando unteres Halbbyte -> Arbeitsvariable
|
78 | tmp |= 0x04; // Bit 2 setzen -> RS=1
|
79 | PORTD = tmp; // Signalausgabe
|
80 | tmp |= 0x08; // Bit 3 setzen -> E=1
|
81 | PORTD = tmp; // Signalausgabe
|
82 | tmp &= 0xF7; // Bit 3 rücksetzen -> E=0
|
83 | PORTD = tmp; // Signalausgabe
|
84 |
|
85 | _delay_ms(1); // Verzögerung 1ms -> Ausführung
|
86 | j++; // Index auf nächstes Zeichen setzen
|
87 | }
|
88 | }
|
89 |
|
90 | //==================================================================
|
91 | // Funktion zur Initialisierung des LCD-Displays
|
92 | //==================================================================
|
93 | // Name: lcd_goto(int row, int col)
|
94 | // Funktion: Positionierung des Cursors
|
95 | // Argumente: row: Zeile 1..2, integer
|
96 | // col: Spalte 1..16, integer
|
97 | //==================================================================
|
98 | void lcd_goto(char row, char col)
|
99 | {
|
100 | row--; // Null-basierend
|
101 | row&=0x01; // sicherheitshalber
|
102 | row*=0x40; // Zeile nach Bit 6 bringen
|
103 | col--; // Null-basierend
|
104 | col&=0x0f; // sicherheitshalber
|
105 | char tmp=row|col;
|
106 | tmp|=0x80; // Cursor setzen
|
107 | lcd_cmd(tmp); // senden
|
108 | }
|
109 |
|
110 | //==================================================================
|
111 | // Funktion zur Initialisierung des LCD-Displays
|
112 | //==================================================================
|
113 | // Name: lcd_init()
|
114 | // Funktion: Initialisierung der Ports
|
115 | // Initialisierung des LCD-Displays
|
116 | // Argument: N/A
|
117 | //==================================================================
|
118 | void lcd_init()
|
119 | {
|
120 | DDRD=0xff; // Port D als Ausgang konfigurieren
|
121 | PORTD=0; // Port D löschen bis LCD gebootet hat
|
122 | _delay_ms(50); // LCD-Bootvorgang -> Verzögerung 50ms
|
123 |
|
124 | // Soft-RESET Kommando 3x senden
|
125 | PORTD = 0x30; // Soft-Reset Kommando, E=0, RS=0
|
126 | PORTD = 0x38; // Soft-Reset Kommando, E=1, RS=0
|
127 | PORTD = 0x30; // Soft-Reset Kommando, E=0, RS=0
|
128 | _delay_ms(5); // Befehlsausführung -> Verzögerung 5ms
|
129 |
|
130 | PORTD = 0x38; // Soft-Reset Kommando, E=1, RS=0
|
131 | PORTD = 0x30;
|
132 | _delay_ms(1); // Befehlsausführung -> Verzögerung 1ms
|
133 |
|
134 | PORTD = 0x38; // Soft-Reset Kommando, E=1, RS=0
|
135 | PORTD = 0x30;
|
136 | _delay_ms(5); // Befehlsausführung -> Verzögerung 5ms
|
137 |
|
138 | // 4-BitModus einschalten
|
139 | PORTD=0x20; // oberes Halbbyte, E=0, RS=0
|
140 | PORTD=0x28; // oberes Halbbyte, E=1, RS=0
|
141 | PORTD=0x20;
|
142 | _delay_ms(1); // Befehlsausführung -> Verzögerung 5ms
|
143 |
|
144 | // ab hier läuft das LCD im 4-Bit-Modus
|
145 | lcd_cmd(0x28); // Funktions-Set: 2 Zeilen, 5x7 Matrix, 4 Bit
|
146 | lcd_cmd(0x06); // Entry Mode
|
147 | lcd_cmd(0x0E); // LCD einschalten
|
148 | lcd_cmd(0x01);
|
149 | _delay_ms(1); // Befehlsausführung -> Verzögerung 2ms
|
150 | }
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | //==================================================================
|
158 | // Funktion zur Umwandlung von Zahlen in Text
|
159 | //==================================================================
|
160 | // Name: lcd_zahl()
|
161 | // Funktion: Zahl in Text
|
162 | // Argument: Zahl, Zahl_T
|
163 | //==================================================================
|
164 | void lcd_zahl(unsigned int zahl,char *Zahl_T)
|
165 |
|
166 | {
|
167 | unsigned char Ziffer100=0;
|
168 | unsigned char Ziffer10=0;
|
169 | unsigned char Ziffer1=0;
|
170 |
|
171 | while(zahl>=100) // Hunderterstelle
|
172 | {
|
173 | Ziffer100++;
|
174 | zahl-=100;
|
175 | }
|
176 |
|
177 | while(zahl>=10) // Zehnerstelle
|
178 | {
|
179 | Ziffer10++;
|
180 | zahl-=10;
|
181 | }
|
182 |
|
183 | while(zahl>=1) // Einserstelle
|
184 | {
|
185 | Ziffer1++;
|
186 | zahl-=1;
|
187 | }
|
188 |
|
189 | Zahl_T[0]=Ziffer100+0x30;
|
190 | Zahl_T[1]=Ziffer10+0x30;
|
191 | Zahl_T[2]=Ziffer1+0x30;
|
192 | }
|
193 |
|
194 |
|
195 | /*======================================================================================
|
196 | HAUPTPROGRAMM
|
197 | ======================================================================================*/
|
198 |
|
199 | int main()
|
200 | {
|
201 | // Konfiguration Timer/Counter 2
|
202 | TCCR2 = 0b01100001; // Timer Control Register
|
203 | DDRB = 0b00111000; // Data Direction Register B: 0=Eingänge; 1=Ausgänge
|
204 |
|
205 |
|
206 | // Konfiguration AD-Wandler
|
207 | ADMUX = 0xE0;
|
208 | ADCSRA = 0xE0;
|
209 |
|
210 | PORTB= 0b00000011; // Pull-up Widerstand: 1=aktiv
|
211 | char Zahl_T[1];
|
212 | char Taster=0b00000001;
|
213 | char z=0;
|
214 | char PEAK=180;
|
215 | char HOLD=20;
|
216 | char OFF=0;
|
217 | unsigned int HOLD_TIME=50000;
|
218 | unsigned int i=0;
|
219 |
|
220 | lcd_init(); // Initialisierung des Displays
|
221 | lcd_goto(1,1); // Positionierung des Cursors
|
222 | lcd_text("AD-Wandler 0-255"); // erste Textzeile
|
223 | lcd_goto(2,1); // Positionierung des Cursors
|
224 | lcd_text("P1:"); // zweite Textzeile
|
225 |
|
226 | while(1)
|
227 | {
|
228 | switch(z)
|
229 | {
|
230 | case 0: OCR2 = OFF;
|
231 | i=0;
|
232 | lcd_zahl(OFF,Zahl_T);
|
233 | lcd_goto(2,5); // Positionierung des Cursors
|
234 | lcd_text(Zahl_T);
|
235 |
|
236 | if(!(PINB & Taster))
|
237 | z=1;
|
238 | else
|
239 | {
|
240 | z=0;
|
241 | }
|
242 | break;
|
243 |
|
244 | case 1: OCR2 = PEAK;
|
245 | i++;
|
246 | lcd_zahl(PEAK,Zahl_T);
|
247 | lcd_goto(2,5); // Positionierung des Cursors
|
248 | lcd_text(Zahl_T);
|
249 |
|
250 | if(PINB&Taster)
|
251 | z=0;
|
252 | else
|
253 | {
|
254 | if(!(PINB & Taster)&&(i<HOLD_TIME))
|
255 | z=1;
|
256 | else
|
257 | {
|
258 | z=2;
|
259 | }
|
260 | }
|
261 | break;
|
262 |
|
263 | case 2: OCR2 = HOLD;
|
264 | lcd_zahl(HOLD,Zahl_T);
|
265 | lcd_goto(2,5); // Positionierung des Cursors
|
266 | lcd_text(Zahl_T);
|
267 |
|
268 | if(!(PINB & Taster)&&(i=HOLD_TIME))
|
269 | z=2;
|
270 | else
|
271 | {
|
272 | z=0;
|
273 | }
|
274 | break;
|
275 | }
|
276 | }
|
277 | }
|