PWM, использующий timer3 для сервоуправления, не генерирует выходных данных

Я делаю программу для небольшого манипулятора, управляемого четырьмя сервоприводами. Проблема: мне нужны выходы PWM, у timer1 их три, поэтому мне нужно использовать timer3 для последнего

Основная программа и выходы таймера 1 работают отлично, манипулятор работает. Моя проблема заключается в инициализации ШИМ. ШИМ для таймера 1 настроен на фазовую коррекцию, предварительное масштабирование 64 и использование WGM1[0-3] до 1010, так что я могу использовать ICR1 в качестве верхнего значения, оставляя OCR1[0-2] для подсчета, чтобы выход был включен OCR[0-2].

Согласно справочнику ATMEGA 2560, я должен иметь возможность инициализировать идентичный ШИМ с таймером 3 только с одним выходом точно так же, но он просто не даст мне никакого выхода на OC3A.

Любая помощь приветствуется! :)

PS это для проекта класса, так что никаких сервобиблиотек и серьезных изменений в программе (текущий код уже одобрен моим профессором, также срок выполнения в течение 24 часов, поэтому у меня нет времени . Да, я знаю, это звучит как проблема, но технически проект завершен, я просто очень-очень хочу получить полный диапазон движений моего маленького робота из плексигласа)

ШИМ.c:

// ИНИЦИАЛИЗАЦИЯ ФАЗЫ ПРАВИЛЬНОГО ШИМ ---------------------------- --------------------------------------------------
void initPWM()
{
    DDRB |= (1<<DDB7);      // Выходной контакт 5 OC3A
    DDRB |= (1<<DDB5);      // Выходной контакт 11 OC1A
    DDRB |= (1<<DDB6);      // Выходной контакт 12 OC1B
    DDRB |= (1<<DDB7);      // Выходной контакт 13 OC1C


    // Инициализировать TIMER1 для OC1A, OC1B, OC1C:
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11);     // Очистить OCnA при совпадении сравнения (режим без инвертирования), коррекция фазы ICRn top Mode
    TCCR1B |= (1<<WGM13)|(1<<CS11)|(1<<CS10);                     // Верхний режим ICRn с корректировкой фазы, предварительное масштабирование 64 для сигнала 50 Гц
    // Инициализировать TIMER3 для OC3A
    TCCR3A |= (1<<COM3A1)|(1<<WGM31);                            // Очистить OCnA при совпадении сравнения (режим без инвертирования), коррекция фазы ICRn top Mode
    TCCR3B |= (1<<WGM33)|(1<<CS31)|(1<<CS30);                     // Верхний режим ICRn с корректировкой фазы, предварительное масштабирование 64 для сигнала 50 Гц


    // ТАЙМЕР1 Верхнее и нижнее значение:
    ICR1 = 5000;
    TCNT1 = 0;
    // ТАЙМЕР3 Верхнее и нижнее значение:
    ICR3 = 5000;
    TCNT3 = 0;


    // Запуск PWM в OCR = 200 (среднее значение для сервопривода)
    OCR3A = 200;
    OCR1A = 200;
    OCR1B = 200;
    OCR1C = 200;


}

, 👍1


1 ответ


1

Я не вижу ничего плохого в вашей программе, кроме этого:

DDRB |= (1<<DDB7);      // Выходной контакт 5 OC3A

Это установка контакта PB7 в качестве выхода, тогда как цифровой контакт 5 (OC3A) — PE3.

,

Я обнаружил это через несколько часов после публикации, несмотря на то, что копался в моем коде два дня, и теперь я чувствую себя немного идиотом... Большое спасибо за помощь., @Star_bb