Сервоприводы не работают должным образом на AVR

Я не собираюсь тратить ваше время, а просто выложить код вместе с объяснением

#define F_CPU 8000000UL

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

int main(void){
    sei(); //Enable interrupts 
    DDRB = (1 << PORTB3);//Set pin P3 as an output and other pins as inputs
    //PORTB = 0xff;
    DDRA = (1 << PORTA7);//Set pin A7 as an output and other pins as inputs
    //PORTA = (1 << PORTA7);
    TCCR0 = (1 << WGM00) | (1 << WGM01) | (1 << COM01);//Enable PWM, and configure Timer
    TIMSK = (1 <<  TOIE0);//Enabling an interrupt
    OCR0 = 255;//Setting comparison value for the Output compare unit
    TCCR0 |= (0b110 << CS00);//Selecting the clock as the falling edge on a certain pin

    while(1){
    /*
     * The portion of the code creates a square wave with a period of 39 us, which means that the falling edge occurs at a period of 78us, and since the output period of 
     * the PWM is 50Hz for a servo, that fits perfectly (1/(79*10^-6 * 256) ~ 50), but for some reason, the servo doesn't move...*/
       PORTA ^= (1<< PORT7);
       _delay_us(39);
    }
}

Так в чем проблема?? У меня нет осциллографа для измерения частоты, поэтому не просите меня об этом, но я заметил одну особенность: напряжение на проводах сервопривода составляло 2,7 В, тогда как должно было быть 5 В, но сам блок питания питал 5В, и это произошло только тогда, когда я подключил сигнальный контакт к выводу ШИМ, и это произошло независимо от того, была ли подключена шина 5В к сервоприводу или нет... Есть идеи, в чем проблема является??

1 ответ

Ваш выход ШИМ имеет рабочий цикл 50%, поэтому эффективное выходное напряжение порта уменьшается с 5 В до 2,5 В при измерении с помощью вольтметра. Предполагая, что вы измеряете напряжение относительно земли, не будет никакой разницы, если линия 5 В подключена к сервоприводу, но это будет иметь значение, если сигнал ШИМ не подключен.

Если сервопривод двунаправленный, то, возможно, 50-процентный рабочий цикл сохраняет его неподвижным - попробуйте другой рабочий цикл, похоже, что вы жестко закодировали период ШИМ, инвертируя выходной сигнал в каждом полупериоде. Попробуйте что-то вроде

PORTA ^= (1<< PORT7);
_delay_us(28);
PORTA ^= (1<< PORT7);
_delay_us(50);
Другие вопросы по тегам