This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| ru:examples:motor:servo [2010/12/26 19:25] – eduardtlmk | ru:examples:motor:servo [Unknown date] (current) – removed - external edit (Unknown date) 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Серводвигатель ====== | ||
| - | // | ||
| - | |||
| - | ===== Теория ===== | ||
| - | |||
| - | [{{ : | ||
| - | |||
| - | [{{ : | ||
| - | |||
| - | RC (сокращение, | ||
| - | |||
| - | Управляющим сигналом серводвигателя является специфический сигнал широтно-импульсной модуляции (PWM), где длительность импульса определяет положение ротора. Период сигнала - 20 мс (частота 50 Hz) и ширина высокого полупериода 1-2 мс. 1 мс обозначает одно крайнее положение ротора и 2 мс другое крайнее положение ротора. 1,5 мс обозначает среднее положение ротора. | ||
| - | |||
| - | Традиционный RC серводвигатель носит и имя аналогового серводвигателя. Причина в том, что в последнее десятилетие появились так называемые дигитальные серводвигатели. Разница между ними заключается в том, что в аналоговом серводвигателе мотор управляется входным сигналом 50 Hz PWM, а в дигитальном серводвигателе мотором управляет отдельный микроконтроллер с более высокой частотой. Входной сигнал у дигитального серводвигателя такой же, но высокая частота модуляции двигателя позволяет определять положение точнее и быстрее. | ||
| - | |||
| - | ~~CL~~ | ||
| - | ~~PB~~ | ||
| - | |||
| - | ===== Практика ===== | ||
| - | |||
| - | На плате модуля «Двигатели» Домашней Лаборатории есть два разъема для подключения RC серводвигателя. Концы разъемов PWM сигнала подсоединены к выводам PB5 и PB6 микроконтроллера, | ||
| - | |||
| - | Таймер 1 нужно настроить на режим создания PWM сигнала, | ||
| - | |||
| - | <code c> | ||
| - | // | ||
| - | // Значение таймера для достижения полного периода (20 мс) PWM. | ||
| - | // F_CPU - тактовая частота микроконтроллера, | ||
| - | // | ||
| - | #define PWM_PERIOD | ||
| - | |||
| - | // | ||
| - | // Центрально положение серво PWM (1,5 мс / 20 мс) | ||
| - | // Центральное положение достигается взятием из полного периода 15/200 | ||
| - | // | ||
| - | #define PWM_MIDDLE_POS | ||
| - | |||
| - | // | ||
| - | // Повторный фактор, | ||
| - | // в процентах (-100% до 100%) складывается для того, чтобы полупериод точно достигал | ||
| - | // границ 1 и 2 мс или немного выще. | ||
| - | // | ||
| - | #define PWM_RATIO | ||
| - | |||
| - | // | ||
| - | // Настройка выводов | ||
| - | // | ||
| - | static pin servo_pins[2] = | ||
| - | { | ||
| - | PIN(B, 5), PIN(B, 6) | ||
| - | }; | ||
| - | |||
| - | // | ||
| - | // Подготовка к работе выбранного серводвигателя. | ||
| - | // | ||
| - | void servomotor_init(unsigned char index) | ||
| - | { | ||
| - | // Вывод PWM сигнала выходом | ||
| - | pin_setup_output(servo_pins[index]); | ||
| - | |||
| - | |||
| - | // Настройка таймера 1 | ||
| - | // Делитель такта 8 | ||
| - | // Быстрый PWM режим, где TOP = ICR | ||
| - | // OUTA и OUTB низким при сравнении | ||
| - | timer1_init_fast_pwm( | ||
| - | TIMER1_PRESCALE_8, | ||
| - | TIMER1_FAST_PWM_TOP_ICR, | ||
| - | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
| - | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
| - | TIMER1_FAST_PWM_OUTPUT_DISABLE); | ||
| - | |||
| - | // Определение периода с помощью максимального значения | ||
| - | timer1_set_input_capture_value(PWM_PERIOD); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Обозначение позиции серводвигателя | ||
| - | // Параметр позиции от -100 до 100 процентов | ||
| - | // | ||
| - | void servomotor_position(unsigned char index, signed short position) | ||
| - | { | ||
| - | switch (index) | ||
| - | { | ||
| - | case 0: | ||
| - | timer1_set_compare_match_unitA_value( | ||
| - | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
| - | break; | ||
| - | |||
| - | case 1: | ||
| - | timer1_set_compare_match_unitB_value( | ||
| - | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
| - | break; | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Пример программы использует функции, | ||
| - | |||
| - | ~~PB~~ | ||
| - | |||
| - | <code c> | ||
| - | // | ||
| - | // Тест программа серводвигателя | ||
| - | // модуля «Двигатели» Домашней Лаборатории. | ||
| - | // | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | // | ||
| - | // Основная программа | ||
| - | // | ||
| - | int main(void) | ||
| - | { | ||
| - | short position; | ||
| - | |||
| - | // Настройка ADC | ||
| - | adc_init(ADC_REF_AVCC, | ||
| - | |||
| - | // Настройка двигателя | ||
| - | servomotor_init(0); | ||
| - | |||
| - | // Бесконечный цикл | ||
| - | while (true) | ||
| - | { | ||
| - | // Считывание позиции потенциометра и перевод | ||
| - | // в область серводвигателя | ||
| - | position = ((short)adc_get_value(3) - (short)512) / (short)5; | ||
| - | |||
| - | // Обозначение позиции серводвигателя | ||
| - | servomotor_position(0, | ||
| - | } | ||
| - | } | ||
| - | </ | ||