1 | // MCU: ATTINY841
|
2 |
|
3 | #ifndef F_CPU
|
4 | #define F_CPU 8000000UL
|
5 | #endif
|
6 |
|
7 | #include <avr/io.h>
|
8 |
|
9 | uint16_t read_adc(uint8_t channel);
|
10 |
|
11 | int main(void)
|
12 | {
|
13 | uint16_t helligkeit = 0; // 0 dunkel, 127 = 100%
|
14 | uint16_t farbe = 0; // 0 = warmweiss, 127 = kaltweiss
|
15 | uint16_t dimmlevel_cw = 0; // dimmwert kaltweiss
|
16 | uint16_t dimmlevel_ww = 0; // dimmwert warmweiss
|
17 | float ratio_cw = 0; //
|
18 | float ratio_ww = 0; //
|
19 |
|
20 | // init i/o's
|
21 | DDRA = (1<<PORTA1) | (1<<PORTA2); // set outputs
|
22 | PUEA = (1<<PORTA3); // set inputs
|
23 | DDRB = 0x00; // set outputs
|
24 | PUEB = (1<<PORTB0); // set inputs
|
25 |
|
26 | // init timer prescaler
|
27 | CCP = 0xD8; // enable configuration change to change clock prescaler.
|
28 | CLKPR = 0x00; // set clock prescaler to 1 from 1
|
29 |
|
30 | // init timer 1 fast-pwm 10bit // PIN3 PA2 TOCC1
|
31 | TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
|
32 | TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
|
33 | TCCR1C = (0<<FOC1A) | (0<<FOC1B);
|
34 | TOCPMSA0 |= (0<<TOCC1S1) | (1<<TOCC1S0); // i/o pin assignment
|
35 | TOCPMSA1 |= 0x00; // i/o pin assignment
|
36 | TOCPMCOE |= (1<<TOCC1OE); // enable/disable output pin
|
37 | TIMSK1 = (0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);
|
38 | TCCR1A |= (1<<COM1A1);
|
39 |
|
40 | // init timer 2 fast-pwm 10bit // PIN4 PA1 TOCC0
|
41 | TCCR2A = (1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
|
42 | TCCR2B = (0<<ICNC2) | (0<<ICES2) | (0<<WGM23) | (1<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
|
43 | TCCR2C = (0<<FOC2A) | (0<<FOC2B);
|
44 | TOCPMSA0 |= (1<<TOCC0S1) | (0<<TOCC0S0); // i/o pin assignment
|
45 | TOCPMSA1 |= 0x00; // i/o pin assignment
|
46 | TOCPMCOE |= (1<<TOCC0OE); // enable/disable output pin
|
47 | TIMSK2 = (0<<ICIE2) | (0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);
|
48 | TCCR2A |= (1<<COM2B1);
|
49 |
|
50 | // init adc
|
51 | ADCSRA |= ((1<<ADEN) |(1<<ADPS2) | (1<<ADPS1)); // Enable ADC, set prescaler to 16
|
52 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
53 | while (ADCSRA & (1<<ADSC));
|
54 | (void) ADCW;
|
55 |
|
56 | while (1)
|
57 | {
|
58 | // potis über 10bit adc einlesen
|
59 | farbe = read_adc(3); // PA3 ADC3
|
60 | helligkeit = read_adc(11); // PB0 ADC11
|
61 |
|
62 | // farbeverhältnis berechnen
|
63 | ratio_cw = (float)farbe/511.5;
|
64 | ratio_ww = 2-ratio_cw;
|
65 |
|
66 | // helligkeit berechnen (für 50/50-verhältnis)
|
67 | dimmlevel_cw = helligkeit/2;
|
68 | dimmlevel_ww = helligkeit/2;
|
69 |
|
70 | // helligkeit anhand farbverhälgnis verrechnen
|
71 | dimmlevel_cw = dimmlevel_cw * ratio_cw;
|
72 | dimmlevel_ww = dimmlevel_ww * ratio_ww;
|
73 |
|
74 | // pwm-timer / ausgänge setzen
|
75 | OCR2B = dimmlevel_cw;
|
76 | OCR1A = dimmlevel_ww;
|
77 | }
|
78 | }
|
79 |
|
80 | uint16_t read_adc(uint8_t channel)
|
81 | {
|
82 | #define ADC_AVRG 2 // number of ad-conversions
|
83 | #define ADC_OFFSET 0 // adc offset-value (empiric)
|
84 |
|
85 | uint32_t ADValue = 0; // saves sum of ad-conversions
|
86 |
|
87 | ADMUXA = (ADMUXA & ~(0x1F)) | (channel & 0x1F); // select adc channel
|
88 |
|
89 | for(uint8_t i = 0; i < ADC_AVRG; i++) // read adc values
|
90 | { ADCSRA |= (1<<ADSC); // start the first conversion
|
91 | while(ADCSRA &(1<<ADSC)); // wait until conversion is finished
|
92 | ADValue += ADCW; // write adc value in variable
|
93 | }
|
94 |
|
95 | return (uint16_t) ((ADValue / ADC_AVRG) + ADC_OFFSET);
|
96 | }
|