Наш магазин на eBay Наш магазин на AliExpress Наш канал в telegram

Простая программа для управления bldc-моторами

Итак, ранее мы собрали базовую схему для экспериментов с bldc-моторами, а сейчас напишем для этой схемы первую программку и попробуем запустить какой-нибудь моторчик. Но для начала немного обсудим поставленную задачу и то, как мы будем её решать.

алгоритм блочной коммутации

Задача заключается в том, чтобы реализовать на микроконтроллере ATtiny2313 алгоритм блочной коммутации. При этом величину напряжения питания мы будем регулировать с помощью ШИМ-модуляции.

Один из вариантов решения подобной задачи показан на рисунке справа. Суть этого решения для каждой из обмоток можно описать так:

  • в те моменты, когда обмотка двигателя должна быть запитана — мы организуем это питание при помощи ШИМ, регулируя скважностью уровень подаваемого напряжения (участки, обозначенные на картинке красным);
  • когда обмотка должна быть подключена к общему проводу — открываем нижнее плечо полумоста и закрываем верхнее (участки, обозначенные на картинке синим);
  • когда обмотка ни к чему не должна быть подключена — оба плеча полумоста должны быть закрыты (пустые участки).

Для первого пункта (питание обмотки при помощи ШИМ) нужно будет учесть, что все переключения можно делать только через состояние, когда обмотка ни к чему не подключена (чтобы были задержки между переключениями транзисторов). То есть обмотка будет переключаться между тремя состояниями: подключена к питанию, ни к чему не подключена и подключена к общему проводу.

В собранной нами схеме, для обоих плеч полумостов действует следующая логика управления: единица на выходе микроконтроллера открывает соответствующее плечо, а ноль — закрывает. При этом все управляющие сигналы выведены на PORTB и распределены следующим образом:

  1. PB2 — нижнее плечо фазы U;
  2. PB3 — верхнее плечо фазы U;
  3. PB4 — нижнее плечо фазы V;
  4. PB5 — верхнее плечо фазы V;
  5. PB6 — нижнее плечо фазы W;
  6. PB7 — верхнее плечо фазы W;

Всего у нас получится 18 различных состояний порта B, но на каждом шаге мы будем переключаться только между тремя из них. Поэтому выделим под это дело три переменных (CurrentState0, CurrentStateZ, CurrentState1), в которых будем хранить текущие состояния порта B, между которыми мы переключаемся.

В качестве источника ШИМ-сигнала будем использовать таймер TMR0. А определять, на какую фазу этот ШИМ-сигнал подавать, будем с помощью специальной переменной, которая будет хранить номер текущего шага (StepCounter).

Ещё две переменных понадобятся нам для того, чтобы задавать скорость вращения. Одна переменная (Speed) будет хранить количество периодов ШИМ, приходящихся на один шаг (а следовательно и количество периодов, приходящихся на весь 6-ти шаговый цикл, а значит и скорость вращения). А вторая переменная (SpeedCounter) будет счётчиком периодов.

Для того, чтобы реализовать плавное изменение скорости, — нам понадобится ещё три переменных. 1) NewSpeed — здесь будет храниться значение, к которому мы будем плавно двигать текущую скорость. 2) Acceleration — ускорение. Эта переменная будет хранить количество полных 6-ти шаговых циклов, после которых мы будем на единицу изменять текущую скорость. 3) AccelerationCounter — счётчик полных 6-ти шаговых циклов.

Но, вернёмся к ШИМ. Учитывая, что наши транзисторы переключаются с задержкой в 1 мкс, мы, должны будем выключать одно плечо и включать другое с задержкой более 1 мкс. Это наложит ограничения на выбираемую нами частоту ШИМ — она должна быть минимум раз в 100 больше.

Возможность изменения скважности ШИМ-сигнала тоже придётся несколько ограничить, — оставим себе в конце периода ШИМ гарантированное время, равное 10-15% периода, для разных полезных дел (шаги переключать, загружать 3 переменные состояния выводов порта для текущего шага, по UART общаться).

Чтобы было понятнее — изобразим то, что будет происходить во время каждого периода ШИМ, на отдельной картинке:

действия программы для каждого периода ШИМ

Через UART программа будет выполнять следующие команды:

программа для компьютера, позволяющая управлять BLDC-мотором через UART

  1. 0x01 — старт двигателя
  2. 0x02 — стоп двигателя (в этом режиме просто не будем подключать фазу к питанию)
  3. 0x03 — направление вращения — вперёд
  4. 0x04 — направление вращения — назад
  5. 0x05 — загрузить новое значение длительности импульса ШИМ (следующий принятый после этой команды байт будет считаться новым значением длительности импульса, то есть будет загружен в OCR0A)
  6. 0x06 — загрузить скорость (следующий принятый после этой команды байт будет считаться новой скоростью, — NewSpeed)
  7. 0x07 — загрузить ускорение (следующий принятый после этой команды байт будет считаться новым значением ускорения, — Acceleration)

После приёма каждой команды, а также новых значений скорости и ускорения, контроллер в ответ будет посылать один из следующих кодов: 0x00 — ожидание данных (этот код посылается в ответ на успешный приём команд 0x05, 0x06, 0x07), 0x01 — команда успешно выполнена, 0xFE — ошибка выполнения команды, 0xFF — неизвестная команда.

Ну вот, самое важное я описал, остальное, надеюсь, будет понятно из текста программы (если не будет — задавайте вопросы на форуме). Алгоритм и сам текст в статье приводить не буду, — качайте и читайте (ссылки — ниже), а здесь и так слишком много букв получилось.

Скачать текст программы (*.asm) и прошивку (*.hex) для контроллера.

Как вы понимаете, прошивка позволяет рулить подключенным к нашей схеме bldc-мотором через любую терминалку (которая умеет работать с hex-ом), но я для удобства написал специальную небольшую программку (её внешний вид показан на картинке справа).

Скачать программу для ПК и её исходники на C++ Builder 6.

Вот здесь можно посмотреть видео

Добавить комментарий