4
\$\begingroup\$

I'm trying to setup Timer0 on an ATTiny45 using the arduino-tiny core. TIM0_COMPA_vect works fine for prescalers 1,8 and 64, but 256 and 1024 cause the ISR to not fire. I am running the chip at 1MHz.

Setup code is as follows:

void setup()
{
  ADCSRA &= ~(1<<ADEN); //Disable ADC
  ACSR = (1<<ACD); //Disable the analog comparator
  DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins.

  DDRB |= _BV(PINB0); // Set Pin 5 (PB0) as output;
  PORTB &= ~_BV(PINB0); //Set it to low, just to be safe

  //cli();
  TCCR0A |= _BV(WGM01); //CTC Mode
  TCCR0B |= (_BV(CS02) | _BV(CS00)); //Prescale 1024
  TIMSK  |= _BV(OCIE0A); //enable CTC interrupt
  OCR0A = 243; 

  sei();
}

fuses are:

low_fuses=0x62
high_fuses=0xD7
extended_fuses=0xFF

Any thoughts on why this might be the case?

Update: Not only do prescalers /256 and /1024 not work for COMPA or COMPB but they do not work for the overflow ISR either. I don't really get it since according to table 11-6 in the ATTinyx5 datasheet, it supports prescalers /1, /8, /64, /256, and /1024 via the TCCR0B register.

\$\endgroup\$
4
  • \$\begingroup\$ One thing to check is that the watchdog is definitively turned off, or longer delays will result in watchdog timeouts instead! Does a short delay (OCR0A=small) work with higher prescale settings? \$\endgroup\$
    – user16324
    Jun 30, 2013 at 12:34
  • \$\begingroup\$ Hmmm... will check tonight on the small OCR0A. But how do you turn off the watchdog? \$\endgroup\$
    – Adam Haile
    Jun 30, 2013 at 16:16
  • \$\begingroup\$ No joy... tried both setting OCR0A to 1 and wdt_disable(); to turn of the WDT. Still nothing when using /256 or /1024 \$\endgroup\$
    – Adam Haile
    Jul 1, 2013 at 1:08
  • \$\begingroup\$ BTW... the overflow ISR doesn't work either when using /256 or /1024 \$\endgroup\$
    – Adam Haile
    Jul 1, 2013 at 1:10

1 Answer 1

5
+150
\$\begingroup\$

I suspect the Arduino startup code is setting the timer registers, especially TCCR0B to a value other than the startup default of zero. Try the following code that removes the OR:

TCCR0B = (_BV(CS02) | _BV(CS00)); //Prescale 1024

Looking at the datasheet / 256 and /1024 both have CS02 set to one. If CS01 is set to one by the Arduino code that will be enabling the external clock source when you're trying to set the higher divisor values.

The only other thing worth pointing out is that Arduino tends to use TIMER0 for functions like delay() and millis(). Once you've changed the timer setup those functions won't operate as per usual so you might need to write your own timing routines if required.

\$\endgroup\$
1
  • \$\begingroup\$ Correct you are! Worked like a charm. Guess the |= was just habit. A habit I should break. \$\endgroup\$
    – Adam Haile
    Jul 2, 2013 at 2:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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