Durante un tiempo, he estado trabajando con Arduino, pero hace aproximadamente un mes, cambié a usar únicamente el microcontrolador ATmega328-PU. Yo uso el IDE de Atmel Studio. Hasta ahora, he hecho parpadear con éxito un LED, he usado programas que involucran botones/interruptores y he usado la función Fast PWM para atenuar un LED. Actualmente, estoy intentando conducir un servomotor usando Fast PWM, pero he tenido poco éxito. No he encontrado ningún código fuente que funcione para las necesidades específicas de mi microcontrolador, y realmente no tengo la capacidad de cambiar todos los parámetros, ya que todavía estoy aprendiendo.
El siguiente es el código que he desarrollado. No funciona, pero esperaba que alguien pudiera arreglarlo. El servo se mueve en una dirección, pero no se detiene y simplemente termina moliendo el engranaje del eje del motor, lo que indica que esto podría ser un problema con la longitud de onda. Una pregunta adicional: ¿existe una ecuación para convertir grados a longitud de onda PWM? ¡Gracias!
Especificaciones del microcontrolador:
servo:
Código:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD |= (1 << DDD6);
// PD6 is now an output - corresponds to OCR0A
TCCR0A |= (1 << COM0A1);
// set non-inverting mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// set fast PWM Mode
ICR1 = 39999;
OCR0A = ICR1 - 2000;
// gives servo motor position
TCCR0B |= (1 << CS01);
// set prescaler to 8 and starts PWM
while(1)
{
}
}
Hay varios problemas con su código: -
En el modo de no inversión, el pulso PWM comienza con un conteo de 0 y termina con la coincidencia de comparación, por lo que debe cargar el ancho de pulso directamente en el registro de comparación (no restarlo del período).
ICR1 es parte del Timer1 de 16 bits, no del Timer0 de 8 bits.
Un temporizador de 8 bits no aceptará valores de 16 bits.
Para producir PWM de 16 bits, debe usar Timer1, luego los números 2000 (para un ancho de pulso de 1 ms) y 3999 (para un período de 20 ms) funcionarán correctamente. Así que cambie todas las referencias de Timer0 a sus equivalentes de Timer1, es decir. TCCR0A -> TCCR1A, COM0A1 -> COM1A1, etc. y configure PB1 para generar el pulso del servo.
chris stratton
ciudad traviesa
chris stratton