/* Written 2007 by Matthias Bolte and Aiko Christ*/ #include #include #include #include #define DDB0 0 #define DDB1 1 #define DDB2 2 #define PB0 0 #define PB1 1 #define PB2 2 typedef struct pwm_global_s { uint8_t cycles; } pwm_global_t; typedef struct pwm_led_s { uint8_t offcycles; uint8_t port; } pwm_led_t; typedef struct fade_s { uint8_t cur; uint8_t dir[3]; uint8_t speed[3]; } fade_t; // define and init struct pwm_global_t pwm_global = {0}; pwm_led_t pwm_led[3] = {{255,PB0},{96,PB1},{128,PB2}}; fade_t fade = {0,{0,0,0},{2,1,2}}; void pwm_handler() { pwm_led_t* led; uint8_t i; for (i=0;i<3;++i) { led = &pwm_led[i]; if (!pwm_global.cycles && led->offcycles != 0) { PORTB &= ~(1 << led->port); } else if (pwm_global.cycles == led->offcycles && led->offcycles < 255){ PORTB |= (1 << led->port); } } } void fade_handler() { pwm_led_t* led_p; fade_t* fade_p; uint8_t speed; uint8_t i; for (i=0;i<3;++i) { led_p = &pwm_led[i]; fade_p = &fade; speed = fade_p->speed[i]; if (fade_p->dir[i] == 1) { if (led_p->offcycles > speed - 1) led_p->offcycles -= speed; else { led_p->offcycles += speed; fade_p->dir[i] = 0; } } else { if (led_p->offcycles < 256 - speed) led_p->offcycles += speed; else { led_p->offcycles -= speed; fade_p->dir[i] = 1; fade_p->cur = (fade_p->cur + 1) % 3; } } } } ISR(TIMER1_COMPA_vect) { ++pwm_global.cycles; if (!pwm_global.cycles) fade_handler(); pwm_handler(); } int main(void) { DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2); TCCR1A = 0; TCCR1B = (1 << WGM12) | (1 << CS10); OCR1A = (unsigned short) ((unsigned long) 1024 + 256); TIMSK |= (1 << OCIE1A); sei(); while(1) { } return 0; }