1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <util/delay.h>
|
4 | #include <stdio.h>
|
5 | #include <stdint.h>
|
6 |
|
7 | #define LICHTLIMIT 500
|
8 |
|
9 | // ADC
|
10 | /* ADC initialisieren */
|
11 | void ADC_Init(void) {
|
12 |
|
13 | // die Versorgungsspannung AVcc als Refernz wählen:
|
14 | ADMUX = (1<<REFS0);
|
15 | // oder interne Referenzspannung als Referenz für den ADC wählen:
|
16 | // ADMUX = (1<<REFS1) | (1<<REFS0);
|
17 |
|
18 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
|
19 | // schon auf 0, also single conversion
|
20 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
|
21 | ADCSRA |= (1<<ADEN); // ADC aktivieren
|
22 |
|
23 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
24 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
25 |
|
26 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
27 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
28 | }
|
29 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
30 | Wandlung nicht übernommen. */
|
31 | (void) ADCW;
|
32 | }
|
33 |
|
34 | /* ADC Einzelmessung */
|
35 | uint16_t ADC_Read( uint8_t channel )
|
36 | {
|
37 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
38 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
39 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
40 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
41 | }
|
42 | return ADCW; // ADC auslesen und zurückgeben
|
43 | }
|
44 |
|
45 | // ADC Ende
|
46 |
|
47 | // Taster entprellen
|
48 |
|
49 | inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
|
50 | {
|
51 | if ( !(*port & (1 << pin)) )
|
52 | {
|
53 | /* Pin wurde auf Masse gezogen, 100ms warten */
|
54 | _delay_ms(10); // Maximalwert des Parameters an _delay_ms
|
55 | _delay_ms(10); // beachten, vgl. Dokumentation der avr-libc
|
56 | if ( *port & (1 << pin) )
|
57 | {
|
58 | /* Anwender Zeit zum Loslassen des Tasters geben */
|
59 | _delay_ms(10);
|
60 | _delay_ms(10);
|
61 | return 1;
|
62 | }
|
63 | }
|
64 | return 0;
|
65 | }
|
66 |
|
67 | // Taster entprellen ende
|
68 |
|
69 | int MODUS = 1; // 1 = PWM, 2 = Fotowiderstand, 3 = Licht
|
70 | int STATUSLED = 0; // 0 = Aus, 1 = wechsel, 2 = alle
|
71 | int PWMSTATUS = 1; // 1 = wechsel, 2 = alle gleichzeitig
|
72 |
|
73 | //PWM
|
74 | int pwmalle;
|
75 | int pwmseiten;
|
76 | int pwmobenunten;
|
77 | int PWMTIME = 20;
|
78 |
|
79 | int pwmrun = 1;
|
80 |
|
81 | //Licht Start Helligkeit
|
82 | int brightness = 0;
|
83 |
|
84 | int main(void)
|
85 | {
|
86 |
|
87 | // PWM
|
88 |
|
89 | DDRB |= (1<<PB1); // Port OC1A mit angeschlossener LED als Ausgang
|
90 | DDRB |= (1<<PB2);
|
91 | TCCR1A = (1<<WGM11) |(1<<WGM10) | (1<<COM1A1) | (1 << COM1B1); // PWM, phase correct, 8 bit.
|
92 | TCCR1B = (1<<CS10); // Prescaler 64 = Enable counter
|
93 |
|
94 |
|
95 | // PWM Ende
|
96 |
|
97 | // Taster
|
98 | DDRD &= ~ (1<<PD0); // Settings Taster
|
99 | DDRD &= ~ (1<<PD1); // Modus Taster
|
100 |
|
101 | // Fotowiderstand
|
102 | DDRC &= ~ (1<<PC5);
|
103 |
|
104 | // LEDs
|
105 | DDRB |= (1<<PB0); // ModusLED Fotowiderstand
|
106 |
|
107 | DDRD |= (1<<PD2); // StatusLED PWM alle
|
108 | DDRD |= (1<<PD3); // StatusLED PWM wechsel
|
109 | DDRD |= (1<<PD6); // ModusLED Licht
|
110 | DDRD |= (1<<PD7); // ModusLED PWM
|
111 |
|
112 | PORTB |= (1<<PB0); // ModusLED Fotowiderstand
|
113 |
|
114 | PORTD |= (1<<PD2); // StatusLED PWM alle
|
115 | PORTD |= (1<<PD3); // StatusLED PWM wechsel
|
116 | PORTD |= (1<<PD6); // ModusLED Licht
|
117 | PORTD |= (1<<PD7); // ModusLED PWM
|
118 |
|
119 | // ADC
|
120 | uint16_t adcval;
|
121 | ADC_Init();
|
122 |
|
123 | while(1)
|
124 | {
|
125 |
|
126 | if (debounce(&PIND, PD1))
|
127 | {
|
128 | if (MODUS == 3)
|
129 | {
|
130 | MODUS = 1;
|
131 | OCR1A = 0;
|
132 | OCR1B = 0;
|
133 | }
|
134 | else
|
135 | {
|
136 | MODUS++;
|
137 | OCR1A = 0;
|
138 | OCR1B = 0;
|
139 | }
|
140 | }
|
141 |
|
142 | // LED status
|
143 | if (MODUS == 1)
|
144 | {
|
145 | PORTB |= (1<<PB0);
|
146 | PORTD |= (1<<PD6);
|
147 | PORTD &= ~ (1<<PD7);
|
148 | }
|
149 |
|
150 | if (MODUS == 2)
|
151 | {
|
152 | PORTB &= ~(1<<PB0);
|
153 | PORTD |= (1<<PD6);
|
154 | PORTD |= (1<<PD7);
|
155 | STATUSLED = 0;
|
156 | }
|
157 |
|
158 | if (MODUS == 3)
|
159 | {
|
160 | PORTB |= (1<<PB0);
|
161 | PORTD &= ~(1<<PD6);
|
162 | PORTD |= (1<<PD7);
|
163 | STATUSLED = 0;
|
164 | }
|
165 |
|
166 | if (STATUSLED == 0)
|
167 | {
|
168 | PORTD |= (1<<PD2);
|
169 | PORTD |= (1<<PD3);
|
170 | }
|
171 |
|
172 | if (STATUSLED == 1)
|
173 | {
|
174 | PORTD |= (1<<PD2);
|
175 | PORTD &= ~ (1<<PD3);
|
176 | }
|
177 |
|
178 | if (STATUSLED == 2)
|
179 | {
|
180 | PORTD &= ~ (1<<PD2);
|
181 | PORTD |= (1<<PD3);
|
182 | }
|
183 |
|
184 | // Programme
|
185 |
|
186 | if (MODUS == 1)
|
187 | {
|
188 | if (debounce(&PIND, PD0))
|
189 | {
|
190 | if (PWMSTATUS == 2) { PWMSTATUS = 1; STATUSLED = 1; pwmrun = 1; pwmalle = 0;}
|
191 | else { PWMSTATUS = 2; STATUSLED = 2; pwmrun = 1; pwmseiten = 0; pwmobenunten = 1023;}
|
192 | }
|
193 |
|
194 | if (PWMSTATUS == 1)
|
195 | {
|
196 | if (pwmrun == 1)
|
197 | {
|
198 | OCR1A = pwmseiten;
|
199 | OCR1B = pwmobenunten;
|
200 | pwmseiten++;
|
201 | pwmobenunten--;
|
202 | _delay_ms(20);
|
203 | if (pwmseiten == LICHTLIMIT) { pwmrun = 2; }
|
204 | }
|
205 |
|
206 | if (pwmrun == 2)
|
207 | {
|
208 | OCR1A = pwmseiten;
|
209 | OCR1B = pwmobenunten;
|
210 | pwmseiten--;
|
211 | pwmobenunten++;
|
212 | _delay_ms(20);
|
213 | if (pwmseiten == 0) { pwmrun = 1; }
|
214 | }
|
215 | }
|
216 |
|
217 | if (PWMSTATUS == 2)
|
218 | {
|
219 | if (pwmrun == 1)
|
220 | {
|
221 | OCR1A = pwmalle;
|
222 | OCR1B = pwmalle;
|
223 | pwmalle++;
|
224 | _delay_ms(20);
|
225 | if (pwmalle == LICHTLIMIT) { pwmrun = 2; }
|
226 | }
|
227 |
|
228 | if (pwmrun == 2)
|
229 | {
|
230 | OCR1A = pwmalle;
|
231 | OCR1B = pwmalle;
|
232 | pwmalle--;
|
233 | pwmobenunten++;
|
234 | _delay_ms(20);
|
235 | if (pwmalle == 0) { pwmrun = 1; }
|
236 | }
|
237 | }
|
238 | }
|
239 |
|
240 | if (MODUS == 2)
|
241 | {
|
242 | adcval = ADC_Read(5);
|
243 | OCR1A = adcval;
|
244 | OCR1B = adcval;
|
245 | }
|
246 |
|
247 | if (MODUS == 3)
|
248 | {
|
249 | if (debounce(&PIND, PD0))
|
250 | {
|
251 | if (brightness == LICHTLIMIT)
|
252 | {
|
253 | brightness = 10;
|
254 | }
|
255 | else
|
256 | {
|
257 | brightness = brightness + 10;
|
258 | }
|
259 | }
|
260 | OCR1A = brightness;
|
261 | OCR1B = brightness;
|
262 | }
|
263 |
|
264 | //while(a>1){
|
265 | //OCR1A = a;
|
266 | //_delay_ms(15);
|
267 | //a--;
|
268 | //}
|
269 |
|
270 | //while(a<500){
|
271 | //OCR1A = a;
|
272 | //_delay_ms(15);
|
273 | //a++;
|
274 | //}
|
275 |
|
276 | }
|
277 | return 0;
|
278 | }
|