For a driving application I need the PWM mode to be phase correct and the prescaler to be 1. The issue is that the board I am working with has the load hooked up to a PWM pin reliant on timer0. The firmware running on this board makes use of the delay()
, delayMicroseconds()
, and millis()
functions from wiring.c. The goal is to make the timer0 change, shown below, and then make small modifications where the firmware calls the wiring.c timing functions. My approach was to find a scaling factor to be applied to the call of these functions. The scaling factor I came to was 32.12549, calculated by taking the wiring.c expected timer0 behavior: prescaler=64 and TOV0 flag every 256 counts, and comparing it to the actual values after my change: prescaler=1 and TOV0 flag every 510 counts
Calculation: 64*256/510=32.12549
Timer0 change:
// Set timer0 to phase correct PWM
TCCR0A = TCCR0A & 0b11111100 | 0x01;
// Set prescaler for timer0 to 1
TCCR0B = TCCR0B & 0b11111000 | 0x01;
...When I apply this scaling factor to a value returned from millis() to keep time it works well. For example the two pieces of code below proved to be equivalent through the timer0 change:
Use of millis()
before timer0 change:
//current time
long unsigned now = millis();
//delay for 1 second
while(millis() - now < 1000){}
Use of millis()
after timer0 change:
//current time
long unsigned now = millis();
//delay for 1 second, with x32.125 scaling coefficient
while(millis() - now < 32125){}
The two snippets of code above both delayed for 1 second
Now comes the problem: when I try to apply that same scaling factor to delay()
or delayMicroseconds()
it seems to give unreasonable delays...
Use of delayMicroseconds()
before timer0 change:
// wait 1.5ms for mux to switch
delayMicroseconds(1500);
...this delays for 1.5ms
Use of delayMicroseconds()
after timer0 change:
// wait 1.5ms for mux to switch, with x32.125 scaling coefficient
delayMicroseconds(48188);
...this delays for ~20ms.
Assuming this is still linearly scalable:
if 48188 -> 20ms, therefore 1.5ms -> 3614
But when the following code is used...
// wait 1.5ms for mux to switch, scaled
delayMicroseconds(3614);
...the delay isthis delays for ~4.5ms
Why is it that delayMicroseconds()
and delay()
cannot be linearly scaled to account for a timer0 change? Furthermore, is there any simple modification to how these functions are called or utilized that can account for the effect of changing timer0?