How to fix error message "__builtin_avr_delay_cycles expects a compile time integer constant make"?

c adc
James picture James · May 24, 2015 · Viewed 11.1k times · Source

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?

Answer

alk picture alk · May 24, 2015

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;
  }
}