#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;
}