1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | #define F_CPU 16000000L // Systemtakt in Hz
|
5 | #define an(port,b) (port) |= (1<<(b))
|
6 | #define aus(port,b) (port) &= ~(1<<(b))
|
7 |
|
8 | // aktueller Counterstand
|
9 | volatile int pwm_counter=0; // Wird durch den internen Timer hochgezählt
|
10 | volatile int poti_counter=0; // 1...3: Dieses Poti wird ausgelesen
|
11 |
|
12 | // Helligkeit von 1 bis 50
|
13 | volatile int pb1_soll = 0; //zw. 0 und 50: BLAU
|
14 | volatile int pb2_soll = 0; //zw. 0 und 50: GRÜN
|
15 | volatile int pb3_soll = 0; //zw. 0 und 50: ROT
|
16 | volatile int schalter = 1; //zw. 0 und 1: Schalter 0: manuell/1: automatisch
|
17 | volatile int auto_phase = 0; // Phasen für automatischen Betrieb
|
18 | /************************Phasen für automatischen Betrieb**********************
|
19 | *0:Rot an
|
20 | *1:Blau heller
|
21 | *2:Rot dünkler
|
22 | *3:Grün heller
|
23 | *4:Blau dünkler
|
24 | *5:Rot heller
|
25 | *6:Grün dünkler
|
26 | */
|
27 |
|
28 | int main(void) {
|
29 |
|
30 | // Für ADC Werter
|
31 | uint16_t result;
|
32 |
|
33 | // Ausgänge setzen
|
34 | DDRB|=(1<<PB1);
|
35 | DDRB|=(1<<PB2);
|
36 | DDRB|=(1<<PB3);
|
37 |
|
38 | //ADC zum Poti auslesen
|
39 | ADMUX = (0<<REFS1) | (1<<REFS0); // ADC Ref auf Avcc, PC0 gewählt, normale Formatierung
|
40 | ADCSRA= (1<<ADEN) | (1<<ADSC) | (0<<ADFR) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
|
41 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
42 | result = ADCW; //Dummy auslesen
|
43 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen, wird später für erstes Poti verwendet
|
44 |
|
45 | // Timer 0 konfigurieren
|
46 | TCCR0 = (1<<CS00); // Prescaler 0!!!
|
47 |
|
48 | // Overflow Interrupt erlauben
|
49 | TIMSK |= (1<<TOIE0);
|
50 |
|
51 | // Global Interrupts aktivieren
|
52 | sei();
|
53 |
|
54 | while (1) {
|
55 | //Nur wenn Schalter auf manuell steht
|
56 | if (schalter==0) {
|
57 | //Poti an PC0 ->steuert-> PB1
|
58 | if (poti_counter==0) {
|
59 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
60 | result = ADCW; //PC0 auslesen
|
61 | pb1_soll=result/20;
|
62 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0); // ADC Ref auf Avcc, PC1 gewählt, normale Formatierung
|
63 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
64 | poti_counter++;
|
65 | }
|
66 | if (poti_counter==1) {
|
67 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
68 | result = ADCW; //PC1 auslesen
|
69 | pb2_soll=result/20;
|
70 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0); // ADC Ref auf Avcc, PC2 gewählt, normale Formatierung
|
71 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
72 | poti_counter++;
|
73 | }
|
74 | if (poti_counter==2) {
|
75 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
76 | result = ADCW; //PC2 auslesen
|
77 | pb3_soll=result/20;
|
78 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0); // ADC Ref auf Avcc, PC3 gewählt, normale Formatierung
|
79 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
80 | poti_counter++;
|
81 | }
|
82 | } //Ende manuell
|
83 |
|
84 | if ((poti_counter==3) || (schalter==1)) {
|
85 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
86 | result = ADCW; //PC3 auslesen
|
87 | result=result/20;
|
88 | if (result<=25) {
|
89 | //Schalter auf 0
|
90 | schalter=0;
|
91 | TCCR0 = (0<<CS01); // Prescaler 0!!!
|
92 | }
|
93 | else {
|
94 | //Schalter auf 1
|
95 | schalter=1;
|
96 | TCCR0 = (1<<CS01); // Prescaler 64!!!
|
97 | }
|
98 | if (schalter==0) { //Manueller Betrieb
|
99 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0); // ADC Ref auf Avcc, PC0 gewählt, normale Formatierung
|
100 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
101 | poti_counter=0;
|
102 | }
|
103 | else { //Automatischer Betrieb
|
104 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
105 | }
|
106 | }
|
107 | }
|
108 | }
|
109 |
|
110 | #ifndef TIMER0_OVF_vect
|
111 | // Für ältere WinAVR Versionen z.B. WinAVR-20071221
|
112 | #define TIMER0_OVF_vect TIMER0_OVF0_vect
|
113 | #endif
|
114 | // Interrupt
|
115 | ISR (TIMER0_OVF_vect) {
|
116 |
|
117 | if (schalter==1) { //Automatischer Betrieb
|
118 | // Phasen
|
119 | // 0: Rot an; Rest aus
|
120 | if (pwm_counter==0) {
|
121 | pb1_soll=0;
|
122 | pb2_soll=0;
|
123 | pb3_soll=50;
|
124 | }
|
125 | // 1: Blau heller
|
126 | if ((pwm_counter>=1)&(pwm_counter<=43)) {
|
127 | pb1_soll=pwm_counter;
|
128 | }
|
129 | // 2: Rot dünkler
|
130 | if ((pwm_counter>=44)&(pwm_counter<=86)) {
|
131 | //pb3_soll=pb3_soll-(pwm_counter-43);
|
132 | pb3_soll=0;
|
133 | }
|
134 | // 3: Grün heller
|
135 | if ((pwm_counter>=87)&(pwm_counter<=128)) {
|
136 | pb2_soll=pwm_counter-86;
|
137 | }
|
138 | // 4: Blau dünkler
|
139 | if ((pwm_counter>=129)&(pwm_counter<=171)) {
|
140 | //pb1_soll=pb1_soll-(pwm_counter-128);
|
141 | pb1_soll=0;
|
142 | }
|
143 | // 5: Rot heller
|
144 | if ((pwm_counter>=172)&(pwm_counter<=214)) {
|
145 | pb3_soll=pwm_counter-171;
|
146 | }
|
147 | // 6: Grün dünkler
|
148 | if ((pwm_counter>=215)&(pwm_counter<=255)) {
|
149 | //pb2_soll=pb2_soll-(pwm_counter-214);
|
150 | pb2_soll=0;
|
151 | }
|
152 | }
|
153 |
|
154 | if (pb1_soll==pwm_counter) {
|
155 | aus(PORTB,PB1);
|
156 | }
|
157 | if (pb2_soll==pwm_counter) {
|
158 | aus(PORTB,PB2);
|
159 | }
|
160 | if (pb3_soll==pwm_counter) {
|
161 | aus(PORTB,PB3);
|
162 | }
|
163 | if (pwm_counter>=50) {
|
164 | pwm_counter=0;
|
165 | if (pb1_soll>0) {
|
166 | an(PORTB,PB1);
|
167 | }
|
168 | if (pb2_soll>0) {
|
169 | an(PORTB,PB2);
|
170 | }
|
171 | if (pb3_soll>0) {
|
172 | an(PORTB,PB3);
|
173 | }
|
174 | }
|
175 | else {
|
176 | pwm_counter++;
|
177 | }
|
178 |
|
179 |
|
180 | }
|