Trying to wrap my head around these overflow timers for the ATTinyx5 (45 in this particular case). I seemed to have a great handle on it with the ATMega328 but I cannot get it to work the way I want on the tiny chips.
I'm trying to achieve a 1 second pulse (for the purposes of testing, LED on for 1s then off for 1s). I know there are many ways to achieve this, but the simplest seem to be by utilizing the overflow ISR. Here's what I've got so far:
//Who can ever remember what the prescaler combinations are?
//These are for Timer0
#define PRESCALE0_1 _BV(CS00)
#define PRESCALE0_8 _BV(CS01)
#define PRESCALE0_64 (_BV(CS00) | _BV(CS01))
#define PRESCALE0_256 _BV(CS02)
#define PRESCALE0_1024 (_BV(CS02) | _BV(CS00))
void setup()
{
DDRB |= _BV(PINB0); // Set Pin 5 (PB0) as output;
PORTB &= ~_BV(PINB0); //Set it to low, just to be safe
cli();
TIMSK |= _BV(TOIE0);
TCCR0B |= PRESCALE0_64;
sei();
}
uint8_t _interval = 2;
uint16_t _pulseCount = 0;
uint16_t _pulseMax = 15625; // = 1s / 0.000064s
bool state = false;
ISR(TIM0_OVF_vect)
{
_pulseCount++;
if(_pulseCount >= _pulseMax)
{
_pulseCount = 0;
if(!state)
{
PORTB |= _BV(PINB0);
state = true;
}
else
{
PORTB &= ~_BV(PINB0);
state = false;
}
}
}
As you can see, I'm doing little more than enabling the Timer0 overflow ISR and setting the prescaler to 8. Now, I'm running the chip at 1Mhz by setting the /8 clock fuse.
Given that 1 / (F_CPU / 64) = 0.000064 or 64 uS that should mean that 1/0.000064 = 15625 overflows per second. So, the general plan was to count overflows in a uint16_t variable util it reached 15625 and then do what I needed to do at 1 second. Sort of an overflow for the overflow.
But instead, I get a pulse every couple of minutes!. To get the pulse I need I have to set _pulseMax to more like 128 which should be 0.000064s * 128 = ~8ms.
I'm sure whatever I'm doing is terribly stupid, but I can't see it. What am I doing wrong here?