/****************************************************************************
Title: final shower time machine code
Author: Rob Duarte <rahji@rahji.com>
Date: 04/24/2007
Software: AVR-GCC 4.1.2
Hardware: ATTiny13 using onboard clock
N.O. momentary switch on INT0 pin
LEDs no PB2-4
Description: led strobe light with a button to control the off-time
on-time is hard-coded
*****************************************************************************/
// attiny with CKSEL=11 (128KHz clock)
// pb2-4
// with 128KHz clock and /256 timer prescale, each clock cycle is 2 ms
// LEDs are hardcoded to be ON for 2 cycles
// maximum OFF-cycles (can't be higher than 255 - LED_ON_CYCLES)
// minimum OFF-cycles
// LEDs are OFF for 20 cycles by default
// increment for changing delay on button press
volatile uint8_t off_until = DELAY_DEFAULT;
// catch a button press interrupt
ISR
{
// if the button is pressed, increase the delay or start at 0 again if we're near max
if ((off_until+DELAY_JUMP)>DELAY_MAX) off_until=DELAY_MIN;
else off_until += DELAY_JUMP;
// adjust timer compare values using the new off_until
OCR0B = off_until;
OCR0A = OCR0B + LED_ON_CYCLES;
}
// when we reach the first compare match (compare reg B)
// turn the LEDs on
ISR { PORTB |= LEDS; }
// when we reach the second compare match (compare reg A) turn the LEDs off
// timer is reset after the match with compare register A
ISR { PORTB &= ~LEDS; }
int
{
// setup timer for flashing
TCCR0A |= _BV(WGM01); // clear timer on match
TCCR0B |= _BV(CS02); // added /256 prescaler for timers
OCR0B = off_until; // set first compare target
OCR0A = OCR0B + LED_ON_CYCLES; // set second compare target, after which the timer zeros
TIMSK0 |= _BV(OCIE0B) | _BV(OCIE0A); // enable both
DDRB |= LEDS; // set LED pins for output
// setup INT0 interrupt for switch
GIMSK |= _BV(INT0); // external INT0 interrupt enable
MCUCR |= _BV(ISC01); // generate interrupt on falling edge (when the button is pressed)
sei(); // enable global interrupts
while (1); // do nothing but wait for interrupts
}