#define F_CPU 1000000L #include <inttypes.h> #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> // global variables const uint16_t pwmtable_8D[32] PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255}; int16_t tmp = 0; int16_t step_time=100; // delay in millisecond for one fading step uint16_t result = 0; // Analog Input Value // long delays void my_delay(uint16_t milliseconds) { for(; milliseconds>0; milliseconds--) _delay_ms(1); } // 8-Bit PWM with 32 different settings void pwm_8_32_up(uint16_t delay){ if (tmp<=0) { for(tmp=0; tmp<=31; tmp++){ OCR0B = pgm_read_word(pwmtable_8D+tmp); my_delay(delay); } } } void pwm_8_32_down(uint16_t delay){ if (tmp>=31) { for(tmp=31; tmp>=0; tmp--){ OCR0B = pgm_read_word(pwmtable_8D+tmp); my_delay(delay); } } } uint16_t readADC(uint8_t channel) { uint8_t i; uint16_t result = 0; // Den ADC aktivieren und Teilungsfaktor auf 64 stellen ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // Kanal des Multiplexers waehlen // Interne Referenzspannung verwenden (also 2,56 V) ADMUX = channel | (1<<REFS0); // Den ADC initialisieren und einen sog. Dummyreadout machen ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); // Jetzt 3x die analoge Spannung and Kanal channel auslesen // und dann Durchschnittswert ausrechnen. for(i=0; i<3; i++) { // Eine Wandlung ADCSRA |= (1<<ADSC); // Auf Ergebnis warten... while(ADCSRA & (1<<ADSC)); result += ADCW; } // ADC wieder deaktivieren ADCSRA &= ~(1<<ADEN); result /= 3; return result; } int main(void) { DDRB |= (1<<PB1); // LED uses OC0B DDRB |= (1<<PB2); // IR LED uses PB2 PORTB = (1<<PB2); // IR LED on // PWM Init TCCR0A=0xA3; TCCR0B=0x02; while(1) { result = readADC(3); //Auslesen der analogen Spannungen an Pin 3 if (result > 240) { pwm_8_32_up(step_time/8); } else { pwm_8_32_down(step_time/8); } }; return 0; }