Skip to main content
Arduino

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

Adjust time calculation after Timer0 frequency change

I have an Arduino Nano with an 328P and need all 6 PWM pins.

Thus, I had to adjust the prescaler and WGM Mode of Timer0.

It is now in phase correct PWM mode with a prescaler of 1.

TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
TCCR0B = _BV(CS00);

Now I need a working time calculation for other libraries, but since Timer0 had that duty everything is out of order now.

I tried adjusting the wiring.c

// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

to this

#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(1 * 510))

But it's like I didn't change anything. (tested other settings that were changed so it was compiled anew )

Whole Code:

void setup() {
 // Set Timer 0, 1 and 2
 // Register A: Output A and B to non-inverted PWM and PWM mode to phase correct.
 // Register B: Pre Scaler to 1.
 TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
 TCCR0B = _BV(CS00);
 TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
 TCCR1B = _BV(CS10);
 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
 TCCR2B = _BV(CS20);
 pinMode(8, OUTPUT);
}
void loop() {
 digitalWrite(8, LOW);
 delay(65000);
 digitalWrite(8, HIGH);
 delay(65000);
}

Answer*

Draft saved
Draft discarded
Cancel
7
  • Thanks for the sophisticated answer! At this point also thanks to @jakec for discussing the problem with me! Commented Jul 17, 2015 at 8:51
  • Since your counter is now going alternatively up and down Why is the TCNT0 going up or down? It's going up and every time it overflow the ISR is called. Am I missing something? I tried to solve this by increasing the timer0_overflow_count once every 64 times only, and on the micros() function return the time as return ((m << 8) + (t % 64)) * (64 / clockCyclesPerMicrosecond()); So I do a mod on the TCNT0 counter as my Timer is ticking 64 times faster. But although the micros() seem to be ok delay() is still running faster and I'm not understanding why... Commented Nov 20, 2017 at 8:07
  • @Lefteris: The counter is going up and down because the OP configured it in "phase correct PWM" mode. Commented Nov 20, 2017 at 8:23
  • Correction on the above, modulo was wrong, I'm dividing by 64 on the return function now: return ((m << 8) + (t/64) ) * (64 / clockCyclesPerMicrosecond()); Still the problem remains with delays function which I don't understand Commented Nov 20, 2017 at 8:25
  • @EdgarBonet If I have understood correct, the TCTN0 register increases every CLK/64 tick. So it is only going up. It is reset every time it overflows and TIMER0_OVF_vect ISR is called. So still not understanding what phase correct PWM has to do with this. Commented Nov 20, 2017 at 8:29

AltStyle によって変換されたページ (->オリジナル) /