0

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"?

Jonny
  • 73
  • 8
  • 1
    Please describe what you tried from that answer and how it "didn't work". Rolling your own loop is a good way to solve this problem. So if you tried it and it didn't work then you need to show exactly what you tried and explain what problems you got. – kaylum Nov 15 '20 at 21:44
  • 1
    It's not a brilliant idea to use floating point on an old 8-bitter with no FPU. Because... it's not a PC. – Lundin Nov 16 '20 at 07:32
  • Anyway, the answer you are looking for in on-chip hardware timers. Forget about using busy-delay loops, that's not how real-time systems are designed. – Lundin Nov 16 '20 at 07:33
  • @kaylum , I tried with that loop solution. It also not work. Showing the same error. – Jonny Nov 16 '20 at 10:03

1 Answers1

2

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!

sunriax
  • 592
  • 4
  • 16