1 | Software: Entwicklungsumgebung: AVR Studio 4.14 build 589
|
2 | C-Compiler:WinAVR-20080610
|
3 |
|
4 | Tastenfunktion: Taster 1 : Reset des Sensormoduls
|
5 |
|
6 | Jumperstellung: keine Auswirkung
|
7 |
|
8 | Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts)
|
9 |
|
10 |
|
11 | =============================================================================*/
|
12 |
|
13 |
|
14 | // Deklarationen ==============================================================
|
15 |
|
16 | // Festlegung der Quarzfrequenz
|
17 |
|
18 | #ifndef F_CPU // optional definieren
|
19 | #define F_CPU 18432000UL // 18,432 MHz Quarz
|
20 | #endif
|
21 |
|
22 |
|
23 | // Include von Header-Dateien
|
24 |
|
25 | #include <avr/io.h> // I/O-Konfiguration (intern weitere Dateien)
|
26 | #include <stdbool.h> // Bibliothek fuer Bit-Variable
|
27 | #include <avr/interrupt.h> // Definition von Interrupts
|
28 | #include <util/delay.h> // Definition von Delays (Wartezeiten)
|
29 | #include <avr/sleep.h>
|
30 |
|
31 | #define SET_BIT(PORT, BIT) ((PORT) |= (1 << (BIT))) // Port-Bit Setzen
|
32 | #define CLR_BIT(PORT, BIT) ((PORT) &= ~(1 << (BIT))) // Port-Bit Loeschen
|
33 | #define TGL_BIT(PORT, BIT) ((PORT) ^= (1 << (BIT))) // Port-Bit Toggeln
|
34 |
|
35 | int i;
|
36 | int x;
|
37 |
|
38 | void initLDR0(void);
|
39 | void initLDR1(void);
|
40 | void initLDR2(void);
|
41 | void initLDR3(void);
|
42 | void init_Timer2(void);
|
43 | void Schlafmodus(void);
|
44 | void Leuchtstaerke(void);
|
45 | void Auswertung(void);
|
46 | void Motorsteuerung(void);
|
47 |
|
48 | int lux0;
|
49 | int lux1;
|
50 | int lux2;
|
51 | int lux3;
|
52 |
|
53 | unsigned char modus = 0;
|
54 |
|
55 | /*volatile int LDR0;
|
56 | volatile int LDR1;
|
57 | volatile int LDR2;
|
58 | volatile int LDR3;
|
59 |
|
60 | volatile int LDR02;
|
61 | volatile int LDR20;
|
62 | volatile int LDR13;
|
63 | volatile int LDR31;*/
|
64 |
|
65 | int LDR0;
|
66 | int LDR1;
|
67 | int LDR2;
|
68 | int LDR3;
|
69 |
|
70 | int LDR02;
|
71 | int LDR20;
|
72 | int LDR13;
|
73 | int LDR31;
|
74 |
|
75 | bool Motor_oben = 0;
|
76 | bool Motor_unten = 0;
|
77 | bool Motor_rechts = 0;
|
78 | bool Motor_links = 0;
|
79 |
|
80 |
|
81 | //========================================================================
|
82 |
|
83 | // Hauptprogramm==========================================================
|
84 |
|
85 |
|
86 | int main(void)
|
87 |
|
88 | {
|
89 | init_Timer2();
|
90 |
|
91 | while(1)
|
92 | {
|
93 | Schlafmodus();
|
94 |
|
95 | switch(modus)
|
96 | {
|
97 | case 0:
|
98 | Schlafmodus();
|
99 | break;
|
100 |
|
101 | case 1:
|
102 | cli();
|
103 | Leuchtstaerke();
|
104 | Auswertung();
|
105 | break;
|
106 |
|
107 | case 2:
|
108 | Motorsteuerung();
|
109 | break;
|
110 |
|
111 | }
|
112 |
|
113 | }
|
114 | }
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | //========================================================================
|
121 | //============================ Interrupt Routine==========================
|
122 |
|
123 | // Interrupt Timer 2 (8bit)
|
124 | //18432000/256/1024=0,0124s
|
125 |
|
126 | ISR (TIMER2_OVF_vect) // Interrupt Service Rountine Timer Overflow 2
|
127 |
|
128 | {
|
129 | i++;
|
130 |
|
131 | if(i==166)
|
132 | {
|
133 | i=0;
|
134 | modus=1;
|
135 | }
|
136 | }
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | //=========================================================================
|
142 | //============================== Initialisierung Timer2====================
|
143 |
|
144 | void init_Timer2() // Timer 2 initaliseren
|
145 | {
|
146 | ASSR |= (1<< AS2); // Timer2 asynchron takten
|
147 | // _delay_ms(100); // Einschwingzeit des 32kHz Quarzes
|
148 | TCCR2A = 0; // Timer 2 auf "Normal Mode" schalten
|
149 | TCCR2B |= 0x7 ; // mit Prescaler /1024 betreiben -> OVF 8s XXXXXXXXXXXX 0x7
|
150 |
|
151 | while((ASSR & (1<< TCR2AUB))&&(ASSR & (1<< TCR2BUB))); // Warte auf das Ende des Zugriffs
|
152 |
|
153 | TIFR2 |= (1<<TOV2); // Interrupts löschen (*)
|
154 | TIMSK2 |= (1<<TOIE2); // Timer overflow Interrupt freischalten
|
155 | }
|
156 |
|
157 |
|
158 |
|
159 | //=========================================================================
|
160 | //=================Unterprogramm für Schlafmodus===========================
|
161 |
|
162 | void Schlafmodus()
|
163 |
|
164 | {
|
165 | sei();
|
166 |
|
167 | ACSR |= (1<<ACD); // A/D deaktivieren
|
168 | ADCSRA &= ~(1<<ADEN); // A/D ausschalten
|
169 | PRR |= (1<<PRADC); // A/D shutdown
|
170 |
|
171 | OCR2A |= 0x0; // Dummyzugriff
|
172 | while((ASSR & (1<< TCR2AUB))&&(ASSR & (1<< TCR2BUB))); // Warte auf das Ende des Zugriffs
|
173 |
|
174 | set_sleep_mode(SLEEP_MODE_PWR_SAVE);
|
175 | sleep_mode(); // in den Schlafmodus wechseln
|
176 | }
|
177 |
|
178 |
|
179 |
|
180 | //=========================================================================
|
181 | //=================Unterprogramm für Leuchstaerkenbestimmung===============
|
182 |
|
183 |
|
184 | void Leuchtstaerke()
|
185 |
|
186 | //======================== 1. WANDLUNG ====================================
|
187 |
|
188 | {
|
189 | initLDR0();
|
190 |
|
191 | PRR &= ~(1<<PRADC); // A/D boot
|
192 | ACSR &= ~(1<<ACD); // A/D aktivieren
|
193 | ADCSRA |= (1<<ADEN); // AD aktivieren
|
194 | ADCSRA |= (1<<ADSC); // Konvertierung starten
|
195 |
|
196 | while (ADCSRA & (1<<ADSC)) // Wenn Konvertierung gestartet ist
|
197 | {
|
198 | ;
|
199 | }
|
200 |
|
201 | lux0 = ADCL;
|
202 | lux0 += (ADCH<<8);
|
203 |
|
204 | lux0=0;
|
205 |
|
206 | for (i=0; i<4; i++)
|
207 | {
|
208 | ADCSRA |= (1<<ADSC);
|
209 |
|
210 | while (ADCSRA & (1<<ADSC)) // Wenn Conversion gestartet ist
|
211 | {
|
212 | ;
|
213 | }
|
214 |
|
215 | lux0 = ADCL;
|
216 | lux0 += (ADCH<<8);
|
217 | }
|
218 |
|
219 | ADCSRA &= ~(1<<ADEN);
|
220 |
|
221 | lux0 /=4; // durch 4 teilen
|
222 | LDR0 = lux0;
|
223 |
|
224 | i=0;
|
225 |
|
226 | _delay_us(50);
|
227 |
|
228 |
|
229 | //======================== 2. WANDLUNG ====================================
|
230 |
|
231 | initLDR1();
|
232 |
|
233 | ADCSRA |= (1<<ADEN); // AD aktivieren
|
234 | ADCSRA |= (1<<ADSC); // Konvertierung starten
|
235 |
|
236 | while (ADCSRA & (1<<ADSC)) // Wenn Konvertierung gestartet ist
|
237 | {
|
238 | ;
|
239 | }
|
240 |
|
241 | lux1 = ADCL;
|
242 | lux1 += (ADCH<<8);
|
243 |
|
244 | lux1=0;
|
245 |
|
246 | for (i=0; i<4; i++)
|
247 | {
|
248 | ADCSRA |= (1<<ADSC);
|
249 |
|
250 | while (ADCSRA & (1<<ADSC)) // Wenn Conversion gestartet ist
|
251 | {
|
252 | ;
|
253 | }
|
254 |
|
255 | lux1 = ADCL;
|
256 | lux1 += (ADCH<<8);
|
257 | }
|
258 |
|
259 | ADCSRA &= ~(1<<ADEN);
|
260 |
|
261 | lux1 /=4; // durch 4 teilen
|
262 | LDR1 = lux1;
|
263 |
|
264 | i=0;
|
265 |
|
266 | _delay_us(50);
|
267 |
|
268 |
|
269 | //======================== 3. WANDLUNG ====================================
|
270 |
|
271 | initLDR2();
|
272 |
|
273 | ADCSRA |= (1<<ADEN); // AD aktivieren
|
274 | ADCSRA |= (1<<ADSC); // Konvertierung starten
|
275 |
|
276 | while (ADCSRA & (1<<ADSC)) // Wenn Konvertierung gestartet ist
|
277 | {
|
278 | ;
|
279 | }
|
280 |
|
281 | lux2 = ADCL;
|
282 | lux2 += (ADCH<<8);
|
283 |
|
284 | lux2=0;
|
285 |
|
286 | for (i=0; i<4; i++)
|
287 | {
|
288 | ADCSRA |= (1<<ADSC);
|
289 |
|
290 | while (ADCSRA & (1<<ADSC)) // Wenn Conversion gestartet ist
|
291 | {
|
292 | ;
|
293 | }
|
294 |
|
295 | lux2 = ADCL;
|
296 | lux2 += (ADCH<<8);
|
297 | }
|
298 |
|
299 | ADCSRA &= ~(1<<ADEN);
|
300 |
|
301 | lux2 /=4; // durch 4 teilen
|
302 | LDR2 = lux2;
|
303 |
|
304 | i=0;
|
305 |
|
306 | _delay_us(50);
|
307 |
|
308 | //======================== 4. WANDLUNG ====================================
|
309 |
|
310 | initLDR3();
|
311 |
|
312 | ADCSRA |= (1<<ADEN); // AD aktivieren
|
313 | ADCSRA |= (1<<ADSC); // Konvertierung starten
|
314 |
|
315 | while (ADCSRA & (1<<ADSC)) // Wenn Konvertierung gestartet ist
|
316 | {
|
317 | ;
|
318 | }
|
319 |
|
320 | lux3 = ADCL;
|
321 | lux3 += (ADCH<<8);
|
322 |
|
323 | lux3=0;
|
324 |
|
325 | for (i=0; i<4; i++)
|
326 | {
|
327 | ADCSRA |= (1<<ADSC);
|
328 |
|
329 | while (ADCSRA & (1<<ADSC)) // Wenn Conversion gestartet ist
|
330 | {
|
331 | ;
|
332 | }
|
333 |
|
334 | lux3 = ADCL;
|
335 | lux3 += (ADCH<<8);
|
336 | }
|
337 |
|
338 | ADCSRA &= ~(1<<ADEN);
|
339 |
|
340 | lux3 /=4; // durch 4 teilen
|
341 | LDR3 = lux3;
|
342 |
|
343 | i=0;
|
344 |
|
345 | _delay_us(50);
|
346 | }
|
347 |
|
348 |
|
349 |
|
350 |
|
351 | //=========================================================================
|
352 | //=================Unterprogramm zur LDR-Initialisierung===================
|
353 |
|
354 | void initLDR0()
|
355 |
|
356 | {
|
357 | ADMUX |= 0xC0; // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (0<<MUX0) | (0<<MUX1)
|
358 |
|
359 | // 1.1V mit Externen Kondensator (REFS) + ADC0 Eingang LDR (MUX)
|
360 |
|
361 | ADCSRA |= 0x87; // (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
|
362 |
|
363 | // ADC aktivieren + Vorteiler 128 (Prescaler Selection Bits)
|
364 | }
|
365 |
|
366 | void initLDR1()
|
367 |
|
368 | {
|
369 | ADMUX |= 0xC1; // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (0<<MUX0) | (1<<MUX1)
|
370 |
|
371 | // 1.1V mit Externen Kondensator (REFS) + ADC1 Eingang LDR (MUX)
|
372 |
|
373 | ADCSRA |= 0x87;
|
374 | }
|
375 |
|
376 | void initLDR2()
|
377 |
|
378 | {
|
379 | ADMUX |= 0xC2; // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (1<<MUX0) | (0<<MUX1)
|
380 |
|
381 | // 1.1V mit Externen Kondensator (REFS) + ADC2 Eingang LDR (MUX)
|
382 |
|
383 | ADCSRA |= 0x87;
|
384 | }
|
385 |
|
386 | void initLDR3()
|
387 |
|
388 | {
|
389 | ADMUX |= 0xC3; // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (1<<MUX0) | (1<<MUX1)
|
390 |
|
391 | // 1.1V mit Externen Kondensator (REFS) + ADC3 Eingang LDR (MUX)
|
392 |
|
393 | ADCSRA |= 0x87;
|
394 | }
|
395 |
|
396 |
|
397 |
|
398 | //=========================================================================
|
399 | //=================Unterprogramm zur LDR-Auswertung========================
|
400 |
|
401 | void Auswertung()
|
402 |
|
403 | {
|
404 | if(LDR0>LDR2)
|
405 | {
|
406 | LDR02 = LDR0-LDR2;
|
407 |
|
408 | if(LDR02>100)
|
409 | {
|
410 | Motor_links=1;
|
411 | LDR02=0;
|
412 | modus=2;
|
413 | }
|
414 |
|
415 | else
|
416 | {
|
417 | LDR02=0;
|
418 | modus=0;
|
419 | }
|
420 | }
|
421 |
|
422 | else
|
423 | {
|
424 | LDR20 = LDR2-LDR0;
|
425 |
|
426 | if(LDR20>100)
|
427 | {
|
428 | Motor_rechts=1;
|
429 | LDR20=0;
|
430 | modus=2;
|
431 | }
|
432 |
|
433 | else
|
434 | {
|
435 | LDR20=0;
|
436 | modus=0;
|
437 | }
|
438 | }
|
439 |
|
440 | if(LDR1>LDR3)
|
441 | {
|
442 | LDR13 = LDR1-LDR3;
|
443 |
|
444 | if(LDR13>100)
|
445 | {
|
446 | Motor_oben=1;
|
447 | LDR13=0;
|
448 | modus=2;
|
449 | }
|
450 |
|
451 | else
|
452 | {
|
453 | LDR13=0;
|
454 | modus=0;
|
455 | }
|
456 | }
|
457 |
|
458 | else
|
459 | {
|
460 | LDR31 = LDR3-LDR1;
|
461 |
|
462 | if(LDR31>100)
|
463 | {
|
464 | Motor_unten=1;
|
465 | LDR31=0;
|
466 | modus=2;
|
467 | }
|
468 |
|
469 | else
|
470 | {
|
471 | LDR31=0;
|
472 | modus=0;
|
473 | }
|
474 | }
|
475 | }
|
476 |
|
477 |
|
478 |
|
479 | //=========================================================================
|
480 | //=================Unterprogramm zur Motorsteuerung========================
|
481 |
|
482 | void Motorsteuerung()
|
483 |
|
484 | {
|
485 | if(Motor_links==1) //LDR0>LDR2
|
486 | {
|
487 | SET_BIT(DDRB, DDB0);
|
488 | CLR_BIT(PORTB, PB0); // LED einschalten;
|
489 | Motor_links=0;
|
490 | modus=1;
|
491 | }
|
492 |
|
493 | else
|
494 | {
|
495 | SET_BIT(DDRB, DDB0);
|
496 | SET_BIT(PORTB, PB0); // LED ausschalten, falls an
|
497 | modus=1;
|
498 | }
|
499 |
|
500 | if(Motor_rechts==1) //LDR0<LDR2
|
501 | {
|
502 | SET_BIT(DDRB, DDB2);
|
503 | CLR_BIT(PORTB, PB2); // LED einschalten;
|
504 | Motor_rechts=0;
|
505 | modus=1;
|
506 | }
|
507 |
|
508 | else
|
509 | {
|
510 | SET_BIT(DDRB, DDB2);
|
511 | SET_BIT(PORTB, PB2); // LED ausschalten, falls an
|
512 | modus=1;
|
513 | }
|
514 |
|
515 | if(Motor_oben==1) //LDR1>LDR3
|
516 | {
|
517 | SET_BIT(DDRB, DDB1);
|
518 | CLR_BIT(PORTB, PB1); // LED einschalten;
|
519 | Motor_oben=0;
|
520 | modus=1;
|
521 | }
|
522 |
|
523 | else
|
524 | {
|
525 | SET_BIT(DDRB, DDB1);
|
526 | SET_BIT(PORTB, PB1); // LED ausschalten, falls an
|
527 | modus=1;
|
528 | }
|
529 |
|
530 | if(Motor_unten==1) //LDR1<LDR3
|
531 | {
|
532 | SET_BIT(DDRB, DDB3);
|
533 | CLR_BIT(PORTB, PB3); // LED einschalten;
|
534 | Motor_unten=0;
|
535 | modus=1;
|
536 | }
|
537 |
|
538 | else
|
539 | {
|
540 | SET_BIT(DDRB, DDB3);
|
541 | SET_BIT(PORTB, PB3); // LED ausschalten, falls anmodus=1;
|
542 | modus=1;
|
543 | }
|
544 | }
|