1 | /*
|
2 | * AVR_Dimmer.c
|
3 | *
|
4 | * Created: 30.09.2012 13:26:59
|
5 | * Author:
|
6 | */
|
7 |
|
8 | // interner Oszillator 9,6 Mhz
|
9 | #define F_CPU 9600000UL
|
10 |
|
11 | #include <avr/io.h>
|
12 | #include <avr/interrupt.h>
|
13 |
|
14 | #define PWM_Output_Port PORTB
|
15 | #define PWM_Output_Bit 0
|
16 | #define PWM_Output_DDR DDRB
|
17 |
|
18 | #define POTI_Input_Port PORTB
|
19 | #define POTI_Input_Bit 4
|
20 | #define POTI_Input_DDR DDRB
|
21 |
|
22 | #define set_bit(var, bit) var |= (1 << bit)
|
23 | #define clr_bit(var, bit) var &= ~(1 << bit)
|
24 |
|
25 | void ADC_Init(); // ADC Inititialisierung
|
26 | uint16_t ADC_Read(uint8_t channel); // ADC Einzelmessung
|
27 |
|
28 | uint8_t pwm_counter = 0;
|
29 | uint8_t volatile pwm_value;
|
30 | uint16_t volatile adc_in;
|
31 | uint8_t adc_percent;
|
32 |
|
33 | int main(void)
|
34 | {
|
35 |
|
36 | // Initialisierung
|
37 |
|
38 | // PWM Output definieren
|
39 | set_bit(PWM_Output_DDR, PWM_Output_Bit);
|
40 | // ADC Input definieren
|
41 | set_bit(POTI_Input_DDR, POTI_Input_Bit);
|
42 |
|
43 | // ADC initialisieren
|
44 | ADC_Init();
|
45 |
|
46 | // Timer definieren
|
47 | TIMSK0 = (1 << TOIE0); // Timer0 Overflow Input Enable
|
48 | TCCR0B = (1 << CS01); // Prescaler 8
|
49 | TCNT0 = 0; // Timer Anfangswert 0
|
50 | sei(); // Interrupts aktivieren
|
51 |
|
52 | while(1)
|
53 | {
|
54 | adc_in = ADC_Read(2); // ADC auslesen
|
55 | adc_percent = adc_in / 1024 * 100;
|
56 |
|
57 | pwm_value = adc_percent / 100 * 255;
|
58 | }
|
59 | }
|
60 |
|
61 | // ISR Timer0 Overflow
|
62 | ISR(TIMER0_OVF_vect) {
|
63 |
|
64 | pwm_counter++;
|
65 |
|
66 | if (pwm_value <= pwm_counter) {
|
67 | set_bit(PWM_Output_Port, PWM_Output_Bit);
|
68 | } else {
|
69 | clr_bit(PWM_Output_Port, PWM_Output_Bit);
|
70 | };
|
71 |
|
72 | }
|
73 |
|
74 | // ADC Initialisierung
|
75 | void ADC_Init(void) {
|
76 |
|
77 | uint16_t result;
|
78 |
|
79 | // VCC als Referenz
|
80 | ADMUX = ~(1 << REFS0);
|
81 |
|
82 | // Frequenzvorverteiler 128
|
83 | ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
|
84 |
|
85 | // ADC aktivieren
|
86 | ADCSRA |= (1 << ADEN);
|
87 |
|
88 | // Dummy Readout
|
89 |
|
90 | ADCSRA |= (1 << ADSC); // eine ADC Wandlung
|
91 | while (ADCSRA & (1 << ADSC)) {;}; // auf Abschluss warten
|
92 | result = ADCW; // Ergebnis muss einmal gelesen werden sonst wird die nächste Wandlung nicht übernommen
|
93 |
|
94 | }
|
95 |
|
96 | // ADC Einzelmessung
|
97 | uint16_t ADC_Read(uint8_t channel) {
|
98 |
|
99 | // Kanal wählen
|
100 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
101 | ADCSRA |= (1 << ADSC); // eine Wandlung
|
102 | while (ADCSRA & (1 << ADSC)) {;}; // auf Ergebnis warten
|
103 |
|
104 | return ADCW; // Ergebnis zurückgeben
|
105 |
|
106 | }
|