Урок 18
Часть 3
Подключаем шаговый двигатель
Продолжаем работать с шаговым двигателем.
В прошлой части занятия мы его подключили и уже начали писать исходный код, написав инициализацию ножек порта, отвечающих за управление нашим шаговым двигателем.
Продолжим писать остальные функции в файле stepmotor.c.
Так как мы будем использовать полушаговый режим, в котором основных положений у ротора нашего шагового мотора будет 8, то и создадим мы целых 8 функций, то есть для каждого положения функция будет своя. Можно, конечно, обойтись и одной функцие, но мы попробуем именно 8 ради научного эксперемента.
Первая функция:
void SM_set1(void)
{
SM_port |= 1<<IN1;
SM_port &= ~(1<<IN2);
SM_port &= ~(1<<IN3);
SM_port &= ~(1<<IN4);
SM_delay;
}
Данная функция включает 1-ю ножку порта, тем самым подаёт напряжение на 1 катушку мотора, остальные лапки мы здесь отключаем.
Теперь следующая функция:
void SM_set2(void)
{
SM_port |= 1<<IN1;
SM_port |= 1<<IN4;
SM_port &= ~(1<<IN2);
SM_port &= ~(1<<IN3);
SM_delay;
}
Судя по алгоритму тела данной функции, при её вызове ротор мотора устремится в положение между первой и второй катушкой.
Я думаю, теперь мы, понимая принцип управления шаговым двигателем, без труда напишем и остальные функции для остальных 6 положений ротора
void SM_set3(void)
{
SM_port |= 1<<IN4;
SM_port &= ~(1<<IN1);
SM_port &= ~(1<<IN2);
SM_port &= ~(1<<IN3);
SM_delay;
}
void SM_set4(void)
{
SM_port |= 1<<IN4;
SM_port |= 1<<IN3;
SM_port &= ~(1<<IN1);
SM_port &= ~(1<<IN2);
SM_delay;
}
void SM_set5(void)
{
SM_port |= 1<<IN3;
SM_port &= ~(1<<IN1);
SM_port &= ~(1<<IN2);
SM_port &= ~(1<<IN4);
SM_delay;
}
void SM_set6(void)
{
SM_port |= 1<<IN3;
SM_port |= 1<<IN2;
SM_port &= ~(1<<IN1);
SM_port &= ~(1<<IN4);
SM_delay;
}
void SM_set7(void)
{
SM_port |= 1<<IN2;
SM_port &= ~(1<<IN1);
SM_port &= ~(1<<IN3);
SM_port &= ~(1<<IN4);
SM_delay;
}
void SM_set8(void)
{
SM_port |= 1<<IN2;
SM_port |= 1<<IN1;
SM_port &= ~(1<<IN3);
SM_port &= ~(1<<IN4);
SM_delay;
}
Ниже мы напишем ещё пару функций, которые будут использовать эти 8 функций, но мало ли, нам захочется в других модулях шагать по 1 шагу, напишем всё-таки для них прототипы в заголовочном файле
void SM_ini(void);
void SM_set1(void);
void SM_set2(void);
void SM_set3(void);
void SM_set4(void);
void SM_set5(void);
void SM_set6(void);
void SM_set7(void);
void SM_set8(void);
Вернёмся в файл реализации функций и напишем там функцию, которая будет проворачивать наш мотор сразу на 8 положений вперёд
void SM_forvard(void)
{
SM_set1();
SM_set2();
SM_set3();
SM_set4();
SM_set5();
SM_set6();
SM_set7();
SM_set8();
}
Ну и напишем такую же функцию для проворачивания двигателя на 8 шагов назад, или правильно сказать, полушагов
void SM_back(void)
{
SM_set8();
SM_set7();
SM_set6();
SM_set5();
SM_set4();
SM_set3();
SM_set2();
SM_set1();
}
Я думаю, код функций понятен, он очень прост.
Также создадим для данных функций прототипы в хедере
void SM_set8(void);
void SM_forvard(void);
void SM_back(void);
В функции main() создадим переменную для счётчика
int main(void)
{
int i = 0;
В бесконечном цикле напишем цикл и попробуем повернуть мотор на все 360 градусов.
Для этого мы делим 4096 на 8, получаем 512, вот столько мы полных циклов по 8 полушагов должны и сделать. Ну считаем мы конечно от 0 до 511
while(1)
{
for (i=0;i<=512;i++)
{
SM_forvard();
}
_delay_ms(300);
}
В конце цикла мы приостановим двигатель на некоторое время, включив в код задержку после цика. Во первых мы так лучше увидим положение остановки ротора, а во-вторых, теперь мы будем вращать его назад, а задержка не даст ему резко изменить направление, чтобы не было каких-нибудь пагубных инерционных явлений.
Ну, собственно теперь повернём его на столько же шагов назад, используя вторую функцию
_delay_ms(300);
for (i=0;i<=512;i++)
{
SM_back();
}
_delay_ms(300);
}
В конце также вставим задержку.
Вот теперь соберём код, прошьём контроллер и посмотрим на поведение ротора по движению нашей прикрепленной скрепочки.
Мы видим, что мотор будет медленно вращаться на 360 градусов сначала по часовой стрелке, а затем против часовой стрелки (видим мы это конечно только в видеоверсии, поэтому я не буду здесь это показывать на рисунке, так как это показать на рисунке невозможно, видеоверсия находится ниже на данной странице).
Также можно попробовать пошагать на другой угол, что мы в видеоверсии и проделали.
Предыдущая часть Программирование МК AVR Следующий урок
Техническая документация на шаговый двигатель
Программатор и шаговый двигатель 28YBJ-48 с драйвером ULN2003 можно приобрести здесь:
Программатор USBASP USBISP с адаптером USBASP USBISP 3.3 с адаптером
Шаговый двигатель 28YBJ-48 с драйвером ULN2003
Смотреть ВИДЕОУРОК (нажмите на картинку)
Добрый день! Хороший пример, нужная вещь. Только одно НО! А как изначально спозиционировать двигатель в нужной точке по сигналу с внешнего мира. Например на колесе закрепить маленький магнит и ловить на ножке сигнал с геркона. Потому как обычный шаговик уперся в ограничитель и выставился в "ноль", а здесь редукция большая, такой вариант не пройдет.
В принципе такое может быть и возможно, но мне кажется овчина не стоит выделки. Для этого есть уже сервоприводы. Поэтому как-то не вселялась в мою бренную голову данная идея. Но всё равно спасибо за неё! Подумаем.
Добрый день.
Спасибо за доступный материал.
Может Вам расширить этот урок и сделать возможность управлять шаговым двигателем от внешнего сигнала по принципу STEP/DIR шаг например по прерыванию, а направление по свободной ножке порта.
Вместо установки нуля на лапу мы используем сброс высокого уровня.
Важно заметить.