Общение

russian-robots@conference.jabber.ru - Чат, в котором можно поболтать об электронике, создании роботов и программировании.
Как мне зайти в чат?

 Обсуждение

Не стесняйтесь оставлять комментарии, мне интересно и важно ваше мнение!
  • Wadimka: Подскажу где взять недорого строчники, идете/едите в любую контору которая ...
  • Vladimir: Об этом датчике я тоже знаю, хотелось с чегото начать изучать МК, а не слеп ...
  • Vladimir: Спсиба
  • Евгений: Стоит поставить инфракрасный датчик движения и не городить ничего :) Литера ...
  • Vladimir: Добрый день Евгений. Это мне для дома в кладовку. При входе на двери стоит ...
  • Евгений: Фотобарьер? По подробнее расскажите.
  • Vladimir: Добрый день. Прошу вас помочь в реализации пректа фотобарер на Tiny45, со с ...
  • Евгений: С таким кодом даже http://caxapa.ru/codebook/?search=BLSH ничего не находит ...
  • Управление сервомашинкой при помощи аппаратного ШИМ

    27th Август 2010 | Метки: , ,

    Робототехники-любители (такие как я :-) ) рано или поздно сталкиваются с проблемой управления сервой.

    Управлять сервомашинкой можно генерируя ШИМ программно, но это не удобно из-за того что процессор микроконтроллера всё время занят генерированием ШИМа, то есть мы не можем выполнять полезную программу и генерить ШИМ одновременно. Конечно, можно исполнять программу в прерываниях, но к чему такие извращения? :) Для того, чтобы проверить серву, посмотреть как она вращается, такой вариант подходит 100%, но не для использования в роботе.

    Выход есть

    В большинстве  микроконтроллеров семейства AVR  есть несколько таймеров с кучей режимов работы, среди которых несколько видов аппаратного ШИМа (PWM). При использовании аппаратного ШИМа процессор не занят, мы можем генерить ШИМ и выполнять какую-нибудь программу.

    Несколько слов о сервах

    Положение аналоговой сервы зависит от длительности импульса на сигнальном входе. Для удерживания позиции сервы импульсы на её входе должны повторяться. Иллюстрация с robocraft:

    Для управление сервой мы будем использовать Timer1 микроконтроллера atmega16. Режим: phase & frequency correct PWM. Тем самым мы получаем 2 канала ШИМа, что позволяет подключить 2 сервы.

    Немного расчетов

    Для того, чтобы настроить ШИМ одного Code Wizard’a не достаточно, придется кое что рассчитать самому :)

    Частота ШИМа (режим Phase & Frequency correct PWM)

    focnxPFCPWM =  fclk/(2 * N * TOP), где TOP – максимальное значение таймера 1, N – делитель тактовой частоты, fclk –  тактовая частота МК

    Максимальное значение таймера хранится в регистрах:

    ICR1H – старшие 8 бит

    ICR1L – младшие 8 бит

    Как видно из формул, от числа в регистре ICR1H & ICR1L зависит частота ШИМа, а следовательно скорость поворота сервы. Например, нам нужно генерить ШИМ с частотой 50 Гц, МК тактируется от кварца на 8 МГц, делитель частоты таймера N=8, путем не сложных вычислений находим  значение в регистре ICR1(TOP) = fclk/(2*N*f) = 8000000 / (2 * 50 * 8 ) =  10000.

    Значение в регистре OCRnx расчитывается по этой формуле:

    Длительность импульса

    t = OCRnx/(f * TOP) , где f – частота ШИМа

    Зная TOP и частоту ШИМа можно упростить формулу:

    OCRnx = t* f * TOP = t * 10^-6 * 50 * 10000 = 0.5t = t/2

    Пример программы:

    /*
    Code Vision AVR C Compiler
    MCU atmega16
    CLOCK 8 MHz RC INT
    */
    #include<mega16.h>
    #define TOP 10000
    void servo1_position(int pos)
    {
    OCR1A = pos/2;
    }
     
    void servo2_position(int pos)
    {
    OCR1B = pos/2;
    }
     
    void main(void)
    {
    //настраиваем Timer1
    TCCR1A=0xA0;
    TCCR1B=0x12;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=TOP>>8;
    ICR1L=TOP; //максимальное значение таймера
    OCR1B=0x00;
    OCR1A=0x00;
     
    DDRD=0x30; //PORTD4 & PORTD5 сконфигурированы на выход
     
    servo1_position(1000); //на PD5 появится ШИМ с частотой 50 гц и длительностью имлуьса 1000 мксек
    servo2_position(1300); //на PD4 аналогично, но длительность импульса уже 1300 мксек
    while(1);
    }

    Форма напряжения на выходе PD5: Длина импульса 1 мС = 1000 мкС.

    Не обязательно писать функции для управления сервами, в этом примере можно использовать 2 макроса:

    #define servo1(a) OCR1B=a/2
    #define servo2(b) OCR1A=b/2

    Вызывать их вот так:
    servo1(1400);
    servo2(1400);

    Тем самым работает это дело быстрее, т.к. компилятор просто заменяет servo1(1400); на OCR1B=1400/2, не тратится несколько тактов на переход в функцию.

    На этом все, желаю успехов :)

    Понравилась статья? Нажмите на любую из кнопок:

    0

    :D :-) :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: