Search code examples
cembeddedavratmelservo

How can I fix this. "__builtin_avr_delay_cycles expects a compile time integer constant"


I'm using a servo motor with atmega32A MCU. I want to turn the motor by sending the degree to a function. Here is my main method.

#ifndef F_CPU
#define F_CPU 8000000UL 
#endif

#include <avr/io.h>
#include <util/delay.h>
#include "servo.h"

int main(void)
{
    DDRC = 0b00000001; 
    PORTC = 0x00;

    while(1)
    {
        turnTo(90);
    }
}

And this is my Servo motor code.

#ifndef F_CPU
#define F_CPU 8000000UL // 8 MHz clock speed
#endif

#include <avr/io.h>
#include <util/delay.h>

int turnTo(double degree){
    int pulse=(degree*500/90)+1000;
    PORTC = 0x01;

    _delay_us(pulse);

    PORTC = 0x00;
    
    return 0;
}

I tried the below answers. But anything didn't work. How can I fix this?

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


Solution

  • Delay function calculates the no operation loops during compile time and can not be dynamically on the controller. So try to add a function like this:

    void wait(unsigned int us)
    {
      for(unsigned int i=0; i < us; i++)
      {
        _delay_us(1);
      }
    }
    

    and adapt your program

    
    int turnTo(double degree){
        unsigned int pulse=(degree*500/90)+1000;
        PORTC = 0x01;
    
        wait(pulse)
    
        PORTC = 0x00;
        
        return 0;
    }
    

    It is not exactly cause the for loop also takes some assembler instructions. At the moment i have got no compiler to check but you can correct the result by counting the assembler instructions that the compiler uses and adapt us variable. A better solution is to use timer instead of delay. They have got a better accuracy as delay and the controller can do other things during counting!