I recently encountered a need to dynamically generate high resolution time delays on an Arduino platform (YUN, ATmega), and this thread is to share the solution in case it helps others.
This gives run-time adjustable delays as low as 625ns and with resolution steps of 62.5ns to 96.25us.
If others have superior solutions, I’m all ears.
/*————————————————————–*/
/* Delay loop functions so we can do single cycle programmable */
/* delays (62.5ns resolution). */
/*————————————————————–*/
byte tune_delay=20; // nominal starting value
unsigned long freq;
void Delay_Plus0(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
}
void Delay_Plus1(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
DELAY_63NS;
}
void Delay_Plus2(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
DELAY_63NS; DELAY_63NS;
}
void Delay_Plus3(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
DELAY_63NS; DELAY_63NS; DELAY_63NS;
}
void Delay_Plus4(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
DELAY_63NS; DELAY_63NS; DELAY_63NS; DELAY_63NS;
}
void Delay_Plus5(byte ticks)
{
for (; ticks; ticks–) DELAY_63NS; // 375ns/tick
DELAY_63NS; DELAY_63NS; DELAY_63NS; DELAY_63NS; DELAY_63NS;
}
// —————- Setup for changing the delay:
byte tune_delay_div;
void (*delay_func_ptr)(byte);
switch (tune_delay%6) {
case 0 : delay_func_ptr = &Delay_Plus0; break;
case 1 : delay_func_ptr = &Delay_Plus1; break;
case 2 : delay_func_ptr = &Delay_Plus2; break;
case 3 : delay_func_ptr = &Delay_Plus3; break;
case 4 : delay_func_ptr = &Delay_Plus4; break;
case 5 : delay_func_ptr = &Delay_Plus5; break;
}
tune_delay_div = tune_delay/6
// —————- Using the delay in the timing critical section
(*delay_func_ptr)(tune_delay_div); // (625 + tune_delay*62.5) ns