// based largely on Atmel's AVR136: Low-Jitter Multi-Channel Software PWM Application Note: // http://www.atmel.com/dyn/resources/prod_documents/doc8020.pdf #include #include #include #define CHMAX 3 // maximum number of PWM channels #define PWMDEFAULT 0x00 // default PWM value at start up for all channels #define RED_CLEAR (pinlevelB &= ~(1 << RED)) // map RED to PB0 #define GREEN_CLEAR (pinlevelB &= ~(1 << GREEN)) // map GREEN to PB1 #define BLUE_CLEAR (pinlevelB &= ~(1 << BLUE)) // map BLUE to PB2 //! Set bits corresponding to pin usage above #define PORTB_MASK (1 << PB0)|(1 << PB1)|(1 << PB2) #define set(x) |= (1< 254 - 1) { r_dir = -1; } if (r_val < 1 + 1) { r_dir = 1; } if (g_val > 254 - 3) { g_dir = -2; } if (g_val < 1 + 3) { g_dir = 2; } if (b_val > 254 - 4) { b_dir = -4; } if (b_val < 1 + 4) { b_dir = 4; } r_val += r_dir; g_val += g_dir; b_val += b_dir; compbuff[0] = r_val; compbuff[1] = g_val; compbuff[2] = b_val; delay_ms(50); } } void delay_ms(uint16_t ms) { while (ms) { _delay_ms(1); ms--; } } void init(void) { // set the direction of the ports LED_DDR set(RED); LED_DDR set(GREEN); LED_DDR set(BLUE); unsigned char i, pwm; CLKPR = (1 << CLKPCE); // enable clock prescaler update CLKPR = 0; // set clock to maximum (= crystal) pwm = PWMDEFAULT; // initialise all channels for(i=0 ; i