Created
May 4, 2011 07:23
-
-
Save funkfinger/954874 to your computer and use it in GitHub Desktop.
Revisions
-
funkfinger revised this gist
May 4, 2011 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,6 @@ // 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 <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> -
funkfinger created this gist
May 4, 2011 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,132 @@ #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #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<<x) #define clr(x) &=~(1<<x) #define inv(x) ^=(1<<x) #define RED PB0 #define GREEN PB1 #define BLUE PB2 #define LED_PORT PORTB #define LED_DDR DDRB void delay_ms(uint16_t ms); void init(); unsigned char compare[CHMAX]; volatile unsigned char compbuff[CHMAX]; int r_val = 0x00; int g_val = 0x55; int b_val = 0xAA; float dim = 1; int main() { init(); int r_dir = 1; int g_dir = 2; int b_dir = 4; for(;;) { if (r_val > 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<CHMAX ; i++) { compare[i] = pwm; // set default PWM values compbuff[i] = pwm; // set default PWM values } TIFR = (1 << TOV0); // clear interrupt flag TIMSK = (1 << TOIE0); // enable overflow interrupt TCCR0B = (1 << CS00); // start timer, no prescale sei(); } ISR (TIM0_OVF_vect) { static unsigned char pinlevelB=PORTB_MASK; static unsigned char softcount=0xFF; PORTB = pinlevelB; // update outputs if(++softcount == 0){ // increment modulo 256 counter and update // the compare values only when counter = 0. compare[0] = compbuff[0]; // verbose code for speed compare[1] = compbuff[1]; compare[2] = compbuff[2]; pinlevelB = PORTB_MASK; // set all port pins high } // clear port pin on compare match (executed on next interrupt) if(compare[0] == softcount) RED_CLEAR; if(compare[1] == softcount) GREEN_CLEAR; if(compare[2] == softcount) BLUE_CLEAR; }