¿Cómo lograr el servocontrol posicional con un Atmega328P?

-1

Estoy tratando de conducir mi servo SG90 usando los temporizadores en el Atmega329P usando PWM de fase correcta. He configurado mi motor lo suficientemente bien como para que gire, pero no puedo hacer que se detenga: el servomotor simplemente sigue girando.

Aquí está mi código actual:
servo.c

#define F_CPU 16000000L

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

#define TOP 500 // 1000*(64/16000000)

void servo_delay() {
   _delay_ms(1500);

}


void setup_servos() {
   DDRD = (1 << DDD5) | (1 << DDD6);
   TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1 << WGM00) | (1 << COM0B1);
   TCCR0B |= (1 << CS00) | (1 << CS01);
   OCR0A = 0x00;

}

void move_servos() {
   for (int i = 100; i < TOP; i++) {
      OCR0A = i;
      servo_delay();
      if (OCR0A == 300) {
          PORTD &= ~ (1 << PD5);
        }

    }
}

servocontrol.h

#ifndef SERVOCONTROL_H
#define SERVOCONTROL_H

void servo_delay();

void setup_servos();

void move_servos();

#endif

main.c

#define F_CPU 16000000L

#include <avr/io.h>
#include "servocontrol.h"

int main() {
    setup_servos();
    move_servos();
}

Estoy intentando usar timer0 en el modo de no inversión de fase correcta, pero experimenté el mismo problema cuando usé timer1 .
¿Cómo consigo que el servo se detenga en la ubicación que deseo? Siento que hay una parte del proceso de PWM que actualmente estoy perdiendo, pero parece que no puedo resolverlo. Apreciaré enormemente cualquier ayuda.

    
pregunta HGitere

1 respuesta

0

A 16 Mhz y con una fuente de reloj de 1/64, tiene una frecuencia TC de 250 kHz. Establece TOP en FF (WGM00), por lo que su período de PWM es de 2 ms. Los servos normales de hobby necesitan un período de aproximadamente 20 ms (50 Hz).

Puede probar 1/1024 horas durante un período de 32 ms (en TOP = FF). Luego, OCR0A entre 8 y 16 le dará 1 a 2 ms de ancho de pulso, para 8 posiciones de resolución de servos.

Puede usar el modo PWM rápido durante un período de 16 ms. Luego, OCR0A entre 16 y 32 le dará el mismo ancho de pulso de 1 a 2 ms, para 16 posiciones de resolución de servo.

O puede usar Timer1 con OCR1A como TOP para un control preciso del período y OCR1B como ciclo de trabajo con una resolución mucho mejor.

    
respondido por el Maple

Lea otras preguntas en las etiquetas