#include #include #include #define LED_ON(COL) PORTB &= ~_BV(COL) #define LED_OFF(COL) PORTB |= _BV(COL) #define RED 2 #define GREEN 1 #define BLUE 0 #define COL_NUM 11 const char RGB[] = { 0, 0, 0, // OFF 64, 0, 0, // 春香 0, 0, 64, // 千早 64, 64, 60, // 雪歩 60, 10, 0, // やよい 0, 64, 0, // 律子 64, 0, 23, // あずささん 64, 24, 24, // 伊織 64, 64, 0, // 亜美・真美 15, 64, 3, // 美希 0, 64, 32, // 響 64, 5, 3, // 貴音 }; volatile char mode = 0; volatile char color = 1; volatile int count = 0; volatile char time = 64; volatile char R = 64; // 初期カラーは春香さん volatile char G = 0; volatile char B = 0; // ボタン割り込み ISR(PCINT0_vect) { _delay_us(100); // チャタリング対策 if(!(PINB & 0b00010000) && !(PINB & 0b0001000)) // ボタン両押し { mode++; if(mode > 4) { TCCR0B = 0b00000000; // Timer off mode = 0; } unsigned char i; for(i = 0; i<2; i++) { LED_OFF(RED); LED_OFF(GREEN); LED_OFF(BLUE); _delay_ms(10); _delay_ms(10); LED_ON(RED); LED_ON(GREEN); LED_ON(BLUE); _delay_ms(10); _delay_ms(10); } return; } // モード0:プリセット if(mode == 0) { if(!(PINB & 0b00010000)) color++; // ボタン上 else if(!(PINB & 0b00001000)) color--; // ボタン下 if(color >= 12) color = 1; if(color <= 0) color = 11; R = RGB[3*color]; G = RGB[3*color + 1]; B = RGB[3*color + 2]; } // モード1:オートローテーション else if(mode == 1) { TCCR0B = 0b00000100; // Timer clk/256 } // モード2:なめらか調光 else if(mode == 2) { if(!(PINB & 0b00010000) || !(PINB & 0b0001000)) TCCR0B = 0b00000011; // Timer clk/64 else TCCR0B = 0b00000000; // Timer stop } else if(mode >= 3) { if(!(PINB & 0b00010000)) time+=32; // ボタン上 else if(!(PINB & 0b00001000)) color++; // ボタン下 if(color > COL_NUM) color = 1; R = RGB[3*color]; G = RGB[3*color + 1]; B = RGB[3*color + 2]; TCCR0B = 0b00000010; // Timer clk/64 } } // タイマー ISR(TIM0_OVF_vect) { if(mode > 2) { count++; if(count == time) { R = 0; G = 0; B = 0; } if(count >= 2 * time) { // モード2:ローテーションモード if(mode == 4) { color++; if(color > COL_NUM) color = 1; } R = RGB[3*color]; G = RGB[3*color + 1]; B = RGB[3*color + 2]; count = 0; } } else { if(mode == 2) { if(!(PINB & 0b00010000)) count++; // ボタン上 else if(!(PINB & 0b00001000)) count--; // ボタン下 } else count++; if(count > 384) count = 0; else if(count < 0) count = 384; if(0 <= count && count < 64) { R = 64; G = count; B = 0; } else if(64 <= count && count < 128) { R = 128 - count; G = 64; B = 0; } else if(128 <= count && count < 192) { R = 0; G = 64; B = count - 128; } else if(192 <= count && count < 256) { R = 0; G = 256 - count; B = 64; } else if(256 <= count && count < 320) { R = count -256; G = 0; B = 64; } else if(320 <= count && count < 384) { R = 64; G = 0; B = 384 - count; } } } // メイン int main() { // PORT初期設定 DDRB = 0b00000111; // 0,1,2:LED 3,4:ボタン PORTB = 0b00011111; // 0,1,2:初期High 3,4 内部プルアップ GIMSK = 0b00100000; // ピン変化割り込み許可 PCMSK = 0b00011000; // PORT3,4許可 TIMSK = 0b00000010; // Timer0オーバーフロー割り込み許可 sei(); // 割り込み許可 unsigned char cnt = 0; unsigned char PWM_R = 0; unsigned char PWM_G = 0; unsigned char PWM_B = 0; for(;;) { cnt = 64; PWM_R = R; PWM_G = G; PWM_B = B; if(PWM_R) LED_ON(RED); if(PWM_G) LED_ON(GREEN); if(PWM_B) LED_ON(BLUE); while(cnt--) { if(!(PWM_R--)) LED_OFF(RED); if(!(PWM_G--)) LED_OFF(GREEN); if(!(PWM_B--)) LED_OFF(BLUE); } } }