My program isn't being compiled using a GCC AVR compiler. It's a small game on a microprocessor and an LCD screen.
move_delay = 200;
_delay_ms( move_delay );
It doesn't like that this _delay_ms is a variable, but it needs to be a variable because I can adjust the screen action through an ADC. Is there a way I can make it a constant but still usable with the ADC?
You could roll you own by looping around the minimal delay you need as often as necessary to get the other delays you need.
void my_delay_ms(int ms)
{
while (0 < ms)
{
_delay_ms(1);
--ms;
}
}
This probably isn't 100% accurate due to time spend for calling _delay_ms()
and decrementing ms
. But for small ms it might be sufficient.
For larger values of ms
you could introduce
void my_delay_ms_10ms_steps(int ms)
{
while (0 < ms)
{
_delay_ms(10);
ms -= 10;
}
}
and so on ...
Also a sort of dynamical approach is possible:
void mydyn_delay_ms(unsigned ms)
{
unsigned i = 0;
while (0 < ms)
{
if (0 != (ms % 2))
{
switch (i)
{
case 0:
_delay_ms(1 << 0);
break;
case 1:
_delay_ms(1 << 1);
break;
case 2:
_delay_ms(1 << 2);
break;
/* and so on */
case <what ever bit-width unsigned uses> -1:
_delay_ms(1 << (<what ever bit-wdith unsigned uses> -1));
break;
}
}
ms >>= 1;
++i;
}
}
Update:
Following up vaxquis comment an alternative way to implement the functionality above would be:
void mydyn_delay_ms(unsigned ms)
{
for (
unsigned i = 0; /* requires at least C99 */
0 < ms;
++i)
{
if (0 != (ms % 2))
{
switch (i)
{
case 0:
_delay_ms(1 << 0);
break;
case 1:
_delay_ms(1 << 1);
break;
case 2:
_delay_ms(1 << 2);
break;
/* and so on */
case <what ever bit-width unsigned uses> -1:
_delay_ms(1 << (<what ever bit-wdith unsigned uses> -1));
break;
}
}
ms >>= 1;
}
}