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 | int pwm_counter=0;
|
10 | int poti_counter=0;
|
11 |
|
12 | // Helligkeit von 1 bis 50
|
13 | int pb1_soll = 1; //zw. 1 und 50: BLAU
|
14 | int pb2_soll = 1; //zw. 1 und 50: GRÜN
|
15 | int pb3_soll = 1; //zw. 1 und 50: ROT
|
16 |
|
17 | int main(void) {
|
18 |
|
19 | // Für ADC Werter
|
20 | uint16_t result;
|
21 |
|
22 | // Ausgänge setzen
|
23 | DDRB|=(1<<PB1);
|
24 | DDRB|=(1<<PB2);
|
25 | DDRB|=(1<<PB3);
|
26 |
|
27 | //ADC zum Poti auslesen
|
28 | ADMUX = (0<<REFS1) | (1<<REFS0); // ADC Ref auf Avcc, PC0 gewählt, normale Formatierung
|
29 | ADCSRA= (1<<ADEN) | (1<<ADSC) | (0<<ADFR) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
|
30 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
31 | result = ADCW; //Dummy auslesen
|
32 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen, wird später für erstes Poti verwendet
|
33 |
|
34 | // Timer 0 konfigurieren
|
35 | TCCR0 = (1<<CS00); // Prescaler 0!!!
|
36 |
|
37 | // Overflow Interrupt erlauben
|
38 | TIMSK |= (1<<TOIE0);
|
39 |
|
40 | // Global Interrupts aktivieren
|
41 | sei();
|
42 |
|
43 | while (1) {
|
44 | //folgende Zeilen sind nur zum Debuggen. LED wird nicht heller!
|
45 | int pb1_soll=pb1_soll+1;
|
46 | int pb2_soll=pb2_soll+1;
|
47 | int pb3_soll=pb3_soll+1;
|
48 |
|
49 | //Poti an PC0 ->steuert-> PB1
|
50 | if (poti_counter==0) {
|
51 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
52 | result = ADCW; //PC0 auslesen
|
53 | pb1_soll=result/20;
|
54 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0); // ADC Ref auf Avcc, PC1 gewählt, normale Formatierung
|
55 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
56 | poti_counter++;
|
57 | }
|
58 | if (poti_counter==1) {
|
59 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
60 | result = ADCW; //PC1 auslesen
|
61 | pb2_soll=result/20;
|
62 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (1<<MUX1) | (0<<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==2) {
|
67 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
68 | result = ADCW; //PC2 auslesen
|
69 | pb3_soll=result/20;
|
70 | ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0); // ADC Ref auf Avcc, PC1 gewählt, normale Formatierung
|
71 | ADCSRA|= (1<<ADSC); //Aktuellen tatsächlichen Wert holen
|
72 | poti_counter=0;
|
73 | }
|
74 | }
|
75 | }
|
76 |
|
77 | #ifndef TIMER0_OVF_vect
|
78 | // Für ältere WinAVR Versionen z.B. WinAVR-20071221
|
79 | #define TIMER0_OVF_vect TIMER0_OVF0_vect
|
80 | #endif
|
81 | // Interrupt
|
82 | ISR (TIMER0_OVF_vect) {
|
83 | if (pb1_soll==pwm_counter) {
|
84 | aus(PORTB,PB1);
|
85 | }
|
86 | if (pb2_soll==pwm_counter) {
|
87 | aus(PORTB,PB2);
|
88 | }
|
89 | if (pb3_soll==pwm_counter) {
|
90 | aus(PORTB,PB3);
|
91 | }
|
92 | if (pwm_counter>=50) {
|
93 | pwm_counter=0;
|
94 | if (pb1_soll>0) {
|
95 | an(PORTB,PB1);
|
96 | }
|
97 | if (pb2_soll>0) {
|
98 | an(PORTB,PB2);
|
99 | }
|
100 | if (pb3_soll>0) {
|
101 | an(PORTB,PB3);
|
102 | }
|
103 | }
|
104 | else {
|
105 | pwm_counter++;
|
106 | }
|
107 |
|
108 | }
|