#include #include #include #include /* * Overview: * three LEDs: * PB1/OC1A yellow * PB2 yellow * PB4/OC1B red */ static void init() { DDRB |= _BV(PB1) | _BV(PB2) | _BV(PB4); // PWM setup, use T/C 1 TCCR1 = _BV(CS10) // clock at CLK/1 | _BV(PWM1A) // OCR1A in PWM mode | _BV(COM1A1); // clear on compare match GTCCR = _BV(PWM1B) // OCR1B in PWM mode | _BV(COM1B1); // clear on compare match) OCR1C = 255; OCR1A = 0; OCR1B = 0; } static unsigned char levels[] = { 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 255 }; #define N_LEVELS (sizeof(levels)/sizeof(levels[0])) static void led_set(unsigned char led, unsigned char val) { switch (led) { case 0: OCR1A = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; break; case 1: if (val) { PORTB |= _BV(PB2); } else { PORTB &= ~_BV(PB2); } break; case 2: OCR1B = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; break; } } static unsigned char rand[] = { 193, 33, 133, 97, 139, 225, 40, 105, 110, 238, 57, 250, 26, 221, 166, 247, 138, 23, 107, 122, 154, 33, 201, 66, 154, 78, 137, 198, 86, 232, 38, 182, 16, 198, 73, 231, 58, 114, 58, 105, }; #define N_RAND (sizeof(rand)/sizeof(rand[0])) static void led0() { static unsigned char r, l, exp; again: if (l == exp) { r++; if (r > N_RAND-7) r = 0; exp = rand[r] >> 4; if (exp >= N_LEVELS-4) goto again; } if (l < exp) { l++; } else if (l > exp) { l--; } led_set(0, l); } static void led1() { static unsigned char r; unsigned char exp; led_set(1, 1); #if 0 again: r++; if (r > N_RAND) r = 0; exp = rand[r]; led_set(1, ((exp >> 3) & 1) ^ ((exp >> 5) & 1)); #endif } static void led2() { static unsigned char r, l, exp; again: if (l == exp) { r++; if (r > N_RAND) r = 0; exp = rand[r] & 0xF; if (exp >= N_LEVELS) goto again; } if (l < exp) { l++; } else if (l > exp) { l--; } led_set(2, l); } int main(void) { init(); while (1) { led0(); led1(); led2(); _delay_ms(40); } }