1
\$\begingroup\$

I am trying to use Timer1 on the ATtiny85 (Adafruit Trinket) to blink an LED every second. The prescaler value is 1024, and the compare register value is 28. I loop through this 279 times to get a delay of 1 second.

$$\frac{1024\ . 28\ . 279}{8\ .10^6}\simeq1$$

With the code below I get something like 8.5 seconds. I set -mmcu=attiny85 and -DF_CPU=8000000UL when compiling. What could I be missing.

#include <stdint.h>
#include <avr/interrupt.h>

#define TIMER_OVERFLOW_COUNT 279

volatile uint16_t timerCount = TIMER_OVERFLOW_COUNT;
ISR(TIMER1_OVF_vect)
{
    timerCount++;
}

int main(void)
{
    DDRB = 1 << DDB1;
    OCR1C = 28;
    TIMSK = 1 << TOIE1;
    sei();
    TCCR1 = (1 << CS13) | (1 << CS11) | (1 << CS10);
    while( 1)
    {
        if( timerCount >= TIMER_OVERFLOW_COUNT)
        {
            timerCount = 0;
            PORTB ^= 1 << PORTB1;
        }
    }
    return 0;
}
\$\endgroup\$
21
  • 1
    \$\begingroup\$ Updating the timerCount in both interrupt handler and the loop is a bad idea. You have a race condition here. Why not put all of the logic in the handler? It's not that heavy. \$\endgroup\$ – Eugene Sh. Aug 30 '16 at 14:42
  • 2
    \$\begingroup\$ Wait. You don't want to interrupt on overflow, you want to interrupt on compare match \$\endgroup\$ – Eugene Sh. Aug 30 '16 at 14:56
  • 1
    \$\begingroup\$ @SubaThomas I am right for sure. But the way to do it should be described in the datasheet an demonstrated in some tutorials around. \$\endgroup\$ – Eugene Sh. Aug 30 '16 at 15:17
  • 1
    \$\begingroup\$ @EugeneSh and Bence Kaulics, thanks for your help. I read the datasheet with a bit more care and found this: "In the normal mode an overflow interrupt (TOV1) is generated when Timer/Counter1 counts from $FF to $00..." Essentially the compare match option is not available in the normal mode. I changed TIMER_OVERFLOW_COUNT to 31 and set OCR1C to 255 (which is really superfluous) and things work as expected. \$\endgroup\$ – Suba Thomas Aug 30 '16 at 16:51
  • 1
    \$\begingroup\$ @BenceKaulics, this timer does not have a CTC mode. There is a CTC1 bit that resets the timer counter when there is a match with OCR1C, but no interrupt to capture when it happens. \$\endgroup\$ – Suba Thomas Aug 30 '16 at 18:41
1
\$\begingroup\$

The CKDIV8 fuse is programmed on devices fresh from the factory. If you forget to unprogram this fuse then the device will run at 1/8 the expected clock speed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.