I want to change timer0 frequency because I need to use 4 PWM pins at a frequency lower than 500Hz and the SPI on an ATmega328. So I changed timer2 to Fast PWM with 64 divisor, enabled the overflow interrupt for timer2 and disabled the overflow interrupt for timer0:

  TCCR2A = _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS22);
  TIMSK2 |= (1 << TOIE2); // enable overflow interrupt for timer2
  TIMSK0 &= ~(1 << TOIE0); // disable overflow interrupt for timer0

and changed the ISR vector in wiring.c from ISR(TIMER0_OVF_vect) to ISR(TIMER2_OVF_vect).

But delay doesn't work. What can be the problem?

  • I would guess Serial and delay rely on timer 2 and you have just changed it. Jan 24 '18 at 11:38
  • HardwareSerial does not use timers. delay uses Timer 0.
    – Nick Gammon
    Feb 9 '18 at 5:13
  • Please post a Minimal, Complete, and Verifiable example.
    – Nick Gammon
    Feb 9 '18 at 5:13
  • I don't know if millis() and micros() work - why not? Write a "blink" sketch and find out.
    – Nick Gammon
    Feb 9 '18 at 5:13

Now everything works except for delay()

delay() uses micros() and micros() reads the hardware registers, like this:

unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;

    m = timer0_overflow_count;
#if defined(TCNT0)
    t = TCNT0;
#elif defined(TCNT0L)
    t = TCNT0L;
    #error TIMER 0 not defined

#ifdef TIFR0
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
    if ((TIFR & _BV(TOV0)) && (t < 255))

    SREG = oldSREG;

    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());

You would need to change all those references (TCNT0, TIFR0, TOV0 etc.) to use the Timer 2 equivalents.

  • This fixed it. Strange that micros() works fine without the fix? Feb 14 '18 at 5:07
  • Appeared to work. I'm sure over a longer interval you would have seen anomalies.
    – Nick Gammon
    Feb 14 '18 at 8:28

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.