Контроллер bldc на stm32 своими руками

Добавил пользователь Alex
Обновлено: 10.09.2024

В качестве контроллера возьмем Arduino DUE. Предвижу шквал критики в свой адрес по поводу контроллера, но цель данного видео не сделать промышленный вариант сервопривода, а показать принцип работы двигателя BLDC и принцип построения сервопривода. Для этих целей, на наш взгляд нужно использовать наиболее простое наглядное решение. Поэтому DUE. Также для критиков сразу отмечу, что мы не делаем сервоприводов на arduino. В данном видео мы сделаем анализ почему обычные контролеры не подходят для построения промышленных приводов и каким требованиям должен удовлетворять контроллер, для построения промышленного привода.

Прототип промышленного сервопривода мы разберем в третьем видео, в котором будет запускать двигатель PMSM. Как учили в учебном заведении, прежде чем что-то сделать, нужно провести обзор литературы. Мы поступим примерно таким же способом. Вскроем сервопривод Leadshine, сервопривод Hiwin и частотник Delta и посмотрим какие контроллеры установлены в промышленных приводах. Забегая вперед, скажу, что это будут не Atmel не PIC и не STM. PMSM мы будем запускать на таком же контроллере, который установлен в сервоприводах Hiwin серии D2.

1. Сам двигатель. Это будет двигатель от сервопривода Leadshine – ACM 604. Мощностью 400 Вт. Благодаря наличию датчиков холла, мы сможем его запустить в режиме BLDC. Также данный двигатель содержит инкрементный энкодер с количество рисок 2500. Выход инкрементного энкодера – это квадратурный дифференциальный сигнал A B и индексной меткой Z в соответствии со стандартом RS-422. Сигналы с датчиков Холла – U V W также дифференциальные. Дифференциальные сигналы являются более помехозащищенными по сравнению с обычными TTL и передаются по витым парам. Силовая часть запитывается на три фазы. По энкодеру мы будем отслеживать положение вала двигателя, по датчикам холла будет определяться положение постоянных магнитов относительно обмоток статора.

2. Драйвер бесколлекторных двигателей. Будем использовать DRV8323 от Texas Instruments. Этот драйвер с обвязкой распаян вот на такой платке. Цена платы в магазине TI 79$. Тянет эта платка 15 ампер в длительном режиме на напряжении до 54В, а это целых 810 Вт, так, что на наш двигатель с двукратным запасом хватит. Mosfet-ы от TI поражают, вот эти чипы тянут 15 ампер без каких-либо радиаторов. Конфигурируется драйвер по шине SPI. Драйвер имеет встроенный управляемый преобразователь напряжения и сконфигурирован на данной плате на 3,3В с током до 650 mA. Питается этот преобразователь от напряжения питания двигателя. Силовое питание драйвера и двигателя подключается вот к этим клеммам, к этим клеммам подключаются силовые обмотки двигателя. Особенностью данного драйвера, является, то, что он может работать в режиме PWMx1. Это как раз тот режим, что нам нужен, плюс ко всему драйвер имеет встроенную логическую таблицу на переключение Mosfet-ов в зависимости от положения ротора двигателя, т.е. от сигналов с датчиков холла. Причем делает это на аппаратном уровне, а не на уровне контроллера в цикле, съедая и без того драгоценные вычислительные ресурсы контроллера.

3. Далее нам потребуется Arduino DUE. Один из самых быстрых контроллеров в семействе ардуино. Одной из самых важных характеристик сервопривода – это время серво цикла, т.е. время за которое контроллер получил данные обработал их и выдал управляющее воздействие. Чем меньше данное время, тем лучше регулирование и тем более качественным считается сервопривод. Поэтому берем контроллер побыстрее.

4. Для подсчета импульсов квадратурного энкодера нам нужен счетчик. Имея максимальную скорость двигателя по каталогу 4500 об/мин и разрешение энкодера в 2500 рисок нам нужно считать импульсы с частотой 4500/60*2500*4 = 750 кГц. (а если бы количество рисок было 5000, то мы бы получили все 1,5 МГц.). Понятно, что обычный контроллер не сможет считать импульсы с такой скоростью. Для этих целей возьмём аппаратный счетчик для квадратурных сигналов. Микросхемка называется IC-MD. Имеет разрядность счетчика до 48 бит и может считать импульсы с частотой до 40 МГц. Данная микросхема на вход может принимать сразу дифференциальный сигнал, чем мы и воспользуемся. Получать данные с квадратурного счетчика наша Arduino будет по SPI.

5. Далее нам потребуется высокоскоростной квадратурный дифференциальный линейный ресивер AM26LV32. Работает на частоте 32 МГц, напряжение питания 3,3 В. Дело в том, что драйвер DRV8323 принимает на вход датчиков холла сигналы TTL, а как мы помним с двигателя у нас идут дифференциальные сигналы RS-422. Квадратурный ресивер будет принимать на вход дифференциальный сигнал, а выдавать TTL, по сути, выполнять функцию преобразования сигналов.

6. Поскольку мы задались целью также подключить наш сервопривод к Mach 3 и поуправлять приводом с его помощью, нам потребуется любой контроллер для Mach 3. Я буду использовать самый простой USB контроллер, который на выходе эмулирует обычный 25 пиновый LPT порт. С данного порта мы заберем два сигнала. Первый сигнал – это Step. Он у нас будет на втором пине. И второй сигнал – это DIR он у нас будет на 6-м пине. И не забываем землю. Максимальная частота импульсов Step с данного контроллера 100 кГц. Не очень много, но для теста нам хватит. Для того чтобы раскрутить наш двигатель на максимальные обороты, нам необходимо 750 кГц. При коэффициенте делителя 1 к 1. Например в своих станках мы используем, в том, числе контроллер SmoothStepper, который способен выдавать сигнал Step с частотой до 4 МГц.

7. Далее нам потребуется еще один счетчик, который будет считать импульсы Step/Dir. Для этих целей возьмем микросхемку LS7366 – это 32 битный квадратурный счетчик, способный считать импульсы с частотами до 20 или 40 МГц, в зависимости от питающего напряжения. Данная микросхема в отличии от IC-MD требует некоторой обвязки, поэтому воспользуемся готовым модулем от SuperDroidRobotics. Данная микросхема умеет сразу считать Step/Dir, хотя если немного подумать, то эту же функцию можно осуществить и на микросхеме IC-MD. Наш контролер также будет получает значение счетчика по SPI.

8. Из необходимого нам еще потребуется три светодиода, кнопка, два сопротивления 1,2 кОм, три сопротивления 500 ом. Два сопротивления 4,7 кОм.

(Схема доступна по ссылке ниже)

Электрическая схема серводрайвера, а также схемы на все модули и даташиты будут доступны по ссылке под видео.

Собирать будем по этапам.

На первом этапе

Подключим дифференциальный приемник к датчикам холла и включим светодиоды через сопротивления 500 Ом на выходы дифф. приемника, чтобы видеть визуально, как будут срабатывать датчики холла.

Для подключения энкодера двигателя к макетной плате я сделал вот такую распайку. Здесь, две группы. Первая группа это квадратурный энкодер, вторая группа, это датчики холла.

Питать цифровую часть нашего серводрайвера будет 3,3 вольтами от преобразователя, который встроен в драйвер DRV8232.

Сам драйвер будем питать от лабораторного блока питания напряжением 42В.

Включаем питание. Медленно проворачивая вручную вал двигателя, можно видеть, как срабатывают датчики холла. Три датчика имеют всего 6-ть логических положения, положения в котором все датчики включены или выключены логически исключены. Можно видеть, что за один полный оборот вала двигателя датчики проходят 4-е полных цикла, что свидетельствует о том, что в двигателе 4-е пары полюсов.

На втором этапе

Подключим наш квадратурный счетчик и Arduino. Терминальные резисторы устанавливать не будем ввиду того, что длина дифференциальной линии мала. Сконфигурируем счетчик энкодера по SPI на разрядность счета в 32 бит. Исходный код для Arduino я также выложу под видео. Будем в бесконечном цикле с периодичностью в 1 секунду считывать показания счетчика и выводить их в консоль. Посмотрим, как это работает. Можно видеть, что примерно один полный оборот вала двигателя соответствует 10000 импульсов. У данного счётчика есть особенность, первые два импульса индексной метки он сбрасывается, таким образом он калибрует количество импульсов между Z метсками.

На третьем этапе

Подключим драйвер мотора. Датчики холла подключим к контактам на боковых пинах. У драйвера есть отдельные пины для подключения датчиков холла, но они не подключены на самой плате. Посмотрим на схему. Если есть желание подключить датчики холла именно к этим пинам нужно будет вооружившись паяльником впаять сюда перемычки. Сигнал ШИМ будем брать с 9 пина Arduino. Также нужно не забыть про Enable. В отличии от драйвера шагового мотора DRV8711, который мы запускали в первом видео, у нашего драйвера DRV8323 SPI не будет работать, если не подан сигнал Enable. Также подключим кнопку, она будет задавать направление.

Конфигурируем драйвер на режим PWMx1. Зададим некоторое значение ШИМ. ШИМ будем задавать с разрядностью 12 бит. С периодичностью в 1 секунду будем выводить значение счетчика энкодера в консоль. Прошиваем ардуино и видим, как двигатель начал вращаться. Кнопка меняет направление вращения мотора.

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

Одним из недостатков режима BLDC от PMSM, является, то, что поле статора изменяет направление дискретно, что вызывает скачкообразное изменение момента двигателя, а также сопровождается незначительной вибрацией при работе двигателя. Да этот эффект несколько нивелирован увеличением количества пар полюсов двигателя, но он все равно присутствует. Попробуем увидеть этот эффект. Для этого заставим вращаться мотор максимально медленно. Можно видеть, как при переключении датчиков холла происходит скачкообразное изменение скорости вращения двигателя.

Теперь немного теории, что такое сервопривод и почему его основная настройка – это коэффициенты ПИД регулятора.

Возможно, Вы знаете, что сервопривод может работать в трех режимах:

1. Режим поддержания заданного момента на валу.

2. Режим поддержания заданной скорости.

3. Режим следования заданного положения.

Давайте разберемся как это достигается. Каждый из этих режимов реализуется так называемым контуром регулирования, контур регулирования момента, скорости и положения.

Рассмотрим на примере контура регулирования скорости. Мы задали некоторое значение скорости, которое хотим достигнуть, сервопривод это значение сравнивает с текущим значением и посредством ПИД регулятора осуществляет регулирование. Далее опять сравнивает заданное значение (причем это значение могло уже измениться, мы уже могли задать новое) с текущим значением и опять осуществляет регулирование посредством ПИД регулятора. Таким образом сервопривод циклично сравнивает текущее значение скорости с заданным и осуществляет регулирование посредством ПИД регулятора. Именно время на такую итерацию и называется временем сервоцикла. Логично, что чем меньше время сервоцикла, тем лучше мы осуществляем регулирование и быстрее достигаем заданного значения. Величина обратная времени называется частотой сервоцикла. Эта частота разная для разных контуров регулирования, как правило, выше всего для момента (или что тоже самое – тока), у контура положения меньше и у контура скорости медленнее всего. Для применения в ЧПУ наибольший интерес представляет частота сервоцикла контура положения. В китайских сервоприводах частота сервоцикла составляет 500 Гц, в сервоприводах среднего класса Delta Hiwin 1-1,5 кГц. В Yaskawa и Panasonic – это 5-6 кГц. В Специализированных контроллерах 20-25 кГц.

Поскольку регулирование в сервоприводе осуществляется посредством ПИД регулятора, рассмотрим кратко, что такое ПИД регулятор.

(Схема доступна по ссылке ниже)

ПИД регулятор — это, по сути, математический алгоритм, который рассчитывает корректирующее воздействие, т.е. например на сколько нам нужно увеличить текущую скорость, чтобы достигнуть заданную. Величина корректирующего воздействия состоит из трех составляющих, пропорциональной, интегральной и дифференциальной. Данные составляющие входят в регулирование с некоторыми коэффициентами Kp, Ki, Kd (пропорциональный коэффициент, интегральный и дифференциальный). Чем больше коэффициенты, тем быстрее регулирование и жёстче система, но тем больше вибраций и ее неустойчивость. Именно подбор этих коэффициентов и является основной настройкой сервопривода. Эти коэффициенты разные для разных контуров регулирования.

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

Давайте запустим наш двигатель в режиме контура скорости. Зададим скорость в 40000 импульсов в /секунду (это 4 оборота в секунду).

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

Аналогично контуру скорости мы можем сделать контур положения. Для этого будем считывать текущее положение с энкодера, рассчитывать ПИД регулятором корректирующее воздействие, задавать его и будем делать это в бесконечном цикле. Если заданное положение будет равно 0, то соответственно при попытке провернуть вал двигателя, серво драйвер будет пытаться вернуть вал мотора в исходное положение. Оценим также время серво цикла в этом режиме.

Добавим в нашу схему контроллер для Mach 3 и счетчик импульсов Step/Dir. Значение с данного счетчика будем читать в Arduino по SPI. Таким образом будем задавать значение для ПИД регулятора. Оценим также время серво цикла в этом режиме. В Mach 3 зададим количество импульсов на 1 мм = 2000, ускорение 500 мм/с2, скорость максимальную 2250 мм/мин. Данная величина скорости ограничена максимальной частотой импульсов step используемого контроллера.

К сожалению, Arduino не позволяет силами своего АЦП построить контур тока. Драйвер двигателя выдает аналоговый сигнал пропорциональный току, но для того, чтобы его включить в АЦМ нужно также подать опорное напряжение. DUE отказалась работать с внешним опорным напряжением, да и считать нужно ток в каждой из фаз, а для каждой из фаз свое опорное напряжение.

1. Аппаратные счетчики энкодера и Step/Dir. (быстродействие от 20 МГц)

2. Быстродействующие АЦП. (разрядность не менее 16 bit, скорость не менее 40 ksps).

3. Высокоскоростной 6х канальный ШИМ, разрядность не менее 16 bit и частота не менее 50 кГц.

Представленная ниже схема является основой для экспериментов с bldc-моторами. Для тех, кто не в курсе, BLDC — это одна из разновидностей синхронных моторов, которая используется, например, в винчестерах, сидирумах, дисководах и т.п. (типа таких, как на картинке справа).

Теорию работы синхронных движков в общем виде можно почитать здесь, чуть конкретнее про BLDC — вот здесь.

Схема позволяет организовать необходимое для питания BLDC-моторов трёхфазное напряжение из обычного однофазного (с помощью ШИМ-модуляции).

Никаких специальных возможностей управления работой мотора (по датчикам Холла или по обратной ЭДС обмоток) в этой схеме не предусмотрено. Про различные варианты такого управления мы поговорим позже, а здесь я постараюсь подробно описать исходя из каких соображений и как рассчитываются элементы именно базовой схемы.

Как видите, нам понадобятся: 1 контроллер ATtiny2313, 3 микрухи спаренных полевиков FDS4542 (N- и P-channel в одном восьминогом корпусе), 6 биполярных транзисторов (я использовал FMMT2222 — маленькие биполярнички в корпусах SOT23 c маркировкой 1P), 3 диода (я взял LL4148) и некоторое количество всяких резисторов и кондёров. (их номиналы будут указаны ниже).

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

То есть каждое из плеч можно включать и выключать независимо от другого, что даёт возможность получить на выходе полумоста три разных состояния: Hi — выход полумоста подключен к питанию (верхний полевик открыт, нижний — закрыт), Lo — выход полумоста подключен к общему проводу (верхний полевик закрыт, нижний — открыт) и Z — выход полумоста отключен и от питания, и общего провода (оба полевика закрыты).

В принципе, можно получить ещё и четвёртое состояние — когда оба полевика открыты, но в этом случае получится КЗ и один из полевиков просто сгорит. Поэтому такое состояние мы будем считать запрещённым и с ним нам как раз придётся всеми способами бороться.

В схеме предусмотрено отдельное питание для схемы управления (+5В) и для силовой части (+12В), поэтому для верхнего плеча пришлось делать развязку на транзисторах T1, T2. Два транзистора были использованы для того, чтобы умощнить эту развязку и сделать её характеристику симметричной, чтобы она могла не только быстро заряжать, но и разряжать затвор верхнего полевика (то есть это ещё и драйвер).

Нижний полевик управляется без всякого драйвера, напрямую от ноги микроконтроллера.

Резисторы R7, R8 — это необязательные подтяжки, назначение которых — предотвратить самопроизвольные открытия полевиков в тот момент, когда ноги микроконтроллера ещё не настроены на выход и находятся в Z-состоянии (при старте). Соответственно, номиналы этих резисторов не очень важны, они просто должны быть намного больше номиналов резисторов R5 и R6, чтобы не мешать нормальной работе схемы после запуска контроллера. Более того, поскольку нам главное, чтобы полевики оба сразу не открылись (если один откроется — шут с ним), можно оставить только R8. Я так и сделал, — взял номинал резистора R8 равным 10 кОм, а резистор R7 вообще выкинул.

Стоит отметить, что помимо функции подтяжки, R7 может выполнять ещё и функцию борьбы с наводками на линию управления транзистором T2. Ток в этой линии очевидно будет гораздо меньше, чем через R5 и в случае, если такие наводки всё же будут, резистор R7 придётся вернуть (это если вы свою разводку платы будете делать).

Ну что, дальше давайте считать. Исходить будем из двух предпосылок: 1) полевиками нужно рулить максимально быстро, но без фанатизма; 2) высшая математика — удовольствие на любителя (особенно когда есть осциллограф и можно всё проверить на практике). В связи с этими, особой точностью и правильностью я увлекаться не буду, но, по крайней мере, рассчёты позволят на что-то ориентироваться.

Начнём с нижнего полевика (N-канальник). Для максимально быстрого управления этим полевиком нам нужно выжать с ноги микроконтроллера максимальный ток и в то же время эту ногу не поджарить.

Пиковый ток на ногу в документации на ATtiny2313 не указан, поэтому будем исходить из значений, указанных в Absolute maximum ratings — 40 мА. При этом максимальный ток у нас будет протекать в самом начале заряда, когда разность потенциалов на затворе и ножке микроконтроллера максимальна. Таким образом, получается R5=5В/40мА=125 Ом. Ближайшее большее значение стандартного номинала — 150 Ом, но мы возьмём 200 Ом, чтобы был небольшой запас. Максимальный ток при этом получится 5/200=25 мА.

Теперь давайте оценим время переключения нашего полевика с резистором 200 Ом в затворе. Оценить это время можно по формуле t=Qg/I, где Qg — total gate charge (берём из документации на FDS4542), I — ток драйвера (мы возьмём максимальный расчётный зарядный ток, чтобы точно не ошибиться в меньшую сторону). Получаем t=28 нК / 25 мА = 1,12 мкс.

Зачем нам нужно время переключения? Очень просто. Когда мы будем писать программу управления — мы должны будем учитывать, что полевики закрываются не мгновенно и вводить задержки между закрытием полевика в одном плече и открытием полевика в другом плече, во избежание возникновения сквозных токов (когда полевики в обоих плечах приоткрыты).

Переходим к P-канальному полевику. Тут ситуация попроще и ногу контроллера нам нагружать не нужно, зато нужно не спалить биполярные транзисторы и диод.

Резисторы R1 и R3 в обвязке p-канальника — это просто высокоомные подтяжки и их номиналы не должны нас особо сильно волновать, поэтому я для начала взял их по 10 кОм (чтобы токи через них можно было не учитывать) и про них забыл.

Затворные токи здесь определяются резисторами R2 и R4, а сама обвязка работает следующим образом: при открытии транзистора T2 потенциал базы транзистора T1 падает ниже потенциала его эмиттера, T1 закрывается, а затвор полевика разряжается через диод и резистор R4; при закрытии транзистора T2 потенциал базы транзистора T1 растёт быстрее, чем на его эмиттере, что приводит к открытию T1 и резкому заряду затвора через R2.

Сначала разберёмся с зарядом. По документации ток через FMMT2222 может быть до 600 мА, а для LL4148 — до 450 мА импульсный и до 150 постоянный, поэтому ориентироваться будем на диод и возьмём для расчётов, скажем 150 мА (чтобы ничего сильно не грелось). Исходя из этого, получим сопротивление резистора R4 = (12-0,5)В/150мА = 76,6 Ом. Далее аналогично, — возьмём ближайший стандартный номинал больше расчётного — 100 Ом. Пересчитываем обратно в ток, получаем I = 115 мА. Ну что ж, пусть будет так. При этом время заряда можно оценить на уровне t = 36 нК / 115 мА = 313 нс.

Чтобы сильно не заморачиваться, возьмём R2 такого же номинала, как и R4, и будем считать, что время закрытия будет примерно такое же, как и время открытия.

Теперь проверим, насколько правильно мы выбрали R1. Чтобы транзистор T1 нормально открывался, ток базы должен быть не более чем в h21 раз меньше тока коллектора. Ток коллектора у нас 100 мА, h21 (из доки) не менее 35, значит ток базы нам нужен не менее 2,86 мА. А он у нас получается 12В/10кОм = 1,2 мА. Ну, тогда возьмём R1 = 3,3 кОм. В этом случае ток базы = 12/3,3 = 3,6 мА. Так и оставим.

Тот же расчёт проделаем для транзистора T2. Ток коллектора у него такой же, как и у T1, значит ток базы тоже должен быть не менее 2,86 мА. Значит R6 должен иметь номинал менее 5/2,86=1,75 кОм. Возьмём с запасом резистор на 1 кОм.

В итоге получилось: R1=3,3 кОм, R2=R4=100 Ом, R3=10 кОм, R5=200 Ом, R6=1 кОм, R7 мы выкинули, R8=10 кОм. При этом время переключения нижнего полевика мы ожидаем на уровне 1,12 мкс, а верхнего — на уровне 313 нс.

Что у нас осталось? Во-первых, конденсаторы. С1=С2=20 пФ, С3=100 мкФ, С4=0,1 мкФ. При проектировании платы C3,C4 нужно расположить как можно ближе к силовым ногам ключей. Во-вторых, на схеме не полностью показана обвязка микроконтроллера. Нужно подтянуть ногу MCLR к питанию через резистор 1 — 10 кОм, а так же поставить конденсатор 0,1 мкФ между питанием и общим проводом поближе к ножкам контроллера.

Что ж, — собираем и тестим.

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

Как видите, наши рассчёты дали примерно адекватные результаты, по крайней мере корректировать ничего не нужно.

Простейшая программка для контроллера (пуск / стоп / реверс / изменение питающего напряжения и частоты вращения)

STM32F частотный преобразователь для трёхфазного асинхронного двигателя.

В данном проекте в отличие от предыдущего будут использованы более продвинутые основные компоненты это конечно контроллер STM32F030C8 и драйвер силовых ключей IR2136 а вот драйвер LCD TM1628 был заменен с TM1638 просто из за дешевизны, в статье я тоже покажу принципиальную схему своего устройства, код программы, проект написанный для IAR который сможете запустить в компиляторе и конечно попробую всё это описать.


Но НЕ выкладываю печатную плату потому что возможно допущены нарушения разводки силовой части которые могут быть опасны поэтому предлагаю включить голову и сделать самим!


Драйвер IR2136 и дополнительных сведения о несущей частоте.

Давайте разберем эти две проблемы, первая решается просто перед пуском мотора мы должны выключить верхние ключи а нижние включить, переждать некоторое время пока зарядятся конденсаторы bootstrap схемы( на рисунке ниже C2-C4 ёмкостью 4.7u).

нет рисунка

И немного о выборе несущей частоты генерации ШИМ, в частотных преобразователях с мощностью от 0.4 кВт до 4 кВт используются несущая частота в районе до 8 кГц и для мощностью более 5.5 кВт не должна превышать 4 кГц, что гарантирует самые низкие потери в преобразователе. Частота выбирается из рекомендуемого диапазона в зависимости от мощности двигателя, чем мощней тем ниже частота. Высокие частоты переключения создают в преобразователе дополнительное тепло, которое уменьшает срок службы преобразователя, потери являются результатом искажений в кабелях двигателя при высоких частотах. Это означает, что если бы преобразователь работал на более низкой частоте переключения, он мог бы обслуживать двигатель при меньших затратах энергии или обслуживать более крупный двигатель, но слишком сильное занижение частоты вызывает резонанс магнитных полей в статоре и роторе двигателя на определённых скоростях вращения, что приводит к вибрациям.

нет рисунка


Схема устройства.

Устройство состоит из двух плат, платы управления и силовая часть.

нет рисунка
нет рисунка

И фотографии плат, как получилось у меня.

нет рисунка
нет рисунка


Код программы.

Основная часть программы где происходит всё управление работой частотного преобразователя, для IAR качаем готовый проект STM32_3_fase_moto.

int main() RCC_DeInit();
FLASH_PrefetchBufferCmd( ENABLE);
FLASH_SetLatency( FLASH_Latency_1);
RCC_PLLConfig( RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);//SYSCLK=4Мгерц*12=48Мгерц.
RCC_PLLCmd( ENABLE); //Доступ к PLL разрешен.
while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY)== RESET);//Ждем пока PLL не будет готов.
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK); //Выбираем PLL как источник частоты.
while( RCC_GetSYSCLKSource()!= 0x08);//Ждем пока PLL не станет источником.
//Включаем тактирование выводов TIM1, LCD и управления IR2136.
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA |RCC_AHBPeriph_GPIOB, ENABLE);
//Настраиваем контроллер для работы с LCD.
Init_Lcd( );
//Настраиваем TIM1 и его выводы для работы с IR2136.
Init_Tim1( );
//Настройка выводов ENABLE ir2136 и включение реле питания ключей.
GPIO_InitTypeDef gpio_control;
gpio_control.GPIO_Pin= GPIO_Pin_9| GPIO_Pin_8;//Вывод включение реле и вывод включение ENABLE IR2136.
gpio_control.GPIO_Mode= GPIO_Mode_OUT;
gpio_control.GPIO_OType= GPIO_OType_PP;
gpio_control.GPIO_PuPd= GPIO_PuPd_NOPULL;
GPIO_Init( GPIOB, &gpio_control);
GPIO_ResetBits( GPIOB, GPIO_Pin_9);//Выключаем реле питания силового модуля.
GPIO_SetBits( GPIOB, GPIO_Pin_8);//Включаем ENABLE IR2136.
for( uint32_t i=0; i //Отображаем на LCD начальное состояние частотника.
Display_Rotation_Lcd( work, 0);

while( 1) for( uint32_t i=0; i //Сканирование кнопок.
scan_button= Scan_Button_Lcd();
for( uint32_t i=0; i //Меняем направление.
case 4:
work= 1;
if( TIM1->BDTR & TIM_BDTR_MOE)< Display_Rotation_Lcd( work, 5);>else< Display_Rotation_Lcd( work, 0);>
break;
//Меняем направление.
case 8:
work= 0;
if( TIM1->BDTR & TIM_BDTR_MOE)< Display_Rotation_Lcd( work, 5);>else< Display_Rotation_Lcd( work, 0);>
break;
//Остановка частотника.
case 16:
Stop_Pwm_Tim1( );
Display_Rotation_Lcd( work, 0);
break;
//Экстренное торможение.
case 32:
work= 2;
Display_Rotation_Lcd( 0, 0);
break;
//Пуск частотника.
case 64:
Start_Pwm_Tim1( );
Display_Rotation_Lcd( work, 5);
break;
default:
//По умолчанию.
break;
>
>
return 0;
>

void TIM1_BRK_UP_TRG_COM_IRQHandler( void) //Прерывание от аварийной ситуации в драйвере IR2136.
if( TIM_GetFlagStatus( TIM1, TIM_FLAG_Break)) TIM_ClearFlag( TIM1, TIM_FLAG_Break);
TIM_Cmd( TIM1, DISABLE);
>
//Прерывание от переполнения периода TIM1.
if( TIM_GetFlagStatus( TIM1, TIM_FLAG_Update)) TIM_ClearFlag( TIM1, TIM_FLAG_Update);
//Вращение в одну сторону.
if( work== 0) TIM_SetCompare1( TIM1, Sin_pwm_tab[ Fase1]);
TIM_SetCompare2( TIM1, Sin_pwm_tab[ Fase2]);
TIM_SetCompare3( TIM1, Sin_pwm_tab[ Fase3]);
Fase1++;
Fase2++;
Fase3++;
if( Fase1== 60) Fase1=0;
if( Fase2== 60) Fase2=0;
if( Fase3== 60) Fase3=0;
> //Вращение в другую сторону.
if( work== 1) TIM_SetCompare1( TIM1, Sin_pwm_tab[ Fase2]);
TIM_SetCompare2( TIM1, Sin_pwm_tab[ Fase1]);
TIM_SetCompare3( TIM1, Sin_pwm_tab[ Fase3]);
Fase1++;
Fase2++;
Fase3++;
if( Fase1== 60) Fase1=0;
if( Fase2== 60) Fase2=0;
if( Fase3== 60) Fase3=0;
>
//Экстренное торможение.
if( work== 2) if( cycle_stop

Код где выполняется настройка TIM1 для управления частотным преобразователем.

//+++Все настройки TIM1.+++
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE);
//Основная настройка.
TIM_TimeBaseInitTypeDef Timer1_init;
Timer1_init.TIM_ClockDivision= TIM_CKD_DIV4;//Предделитель равный четырём для TIM_DeadTime.
Timer1_init.TIM_CounterMode= TIM_CounterMode_Up;//Отсчёт периода вверх TIM1.
Timer1_init.TIM_Prescaler= 1;//Предделитель 2 счётчика TIM1, продолжительность одного такта таймера 1/24000000=0.000 000 041.
Timer1_init.TIM_Period= 8000;//48000000/(8000*2)=3000Гц частота несущей, если частота генерации синусоиды 50Гц то массив синуса состоит из 3000/50=60 элементов.
Timer1_init.TIM_RepetitionCounter= 0;//Прерывание сразу после отсчёта периода таймера.
TIM_TimeBaseInit( TIM1, &Timer1_init);
TIM_ARRPreloadConfig( TIM1, ENABLE);
TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig( TIM1, TIM_OCPreload_Enable);

//Настройка управления выводами при работе и остановке.
TIM_OCInitTypeDef pwm_fase;
pwm_fase.TIM_OCMode= TIM_OCMode_PWM1;//Выводы будут отрабатывать прямой сигнал ШИМ.
pwm_fase.TIM_OCPolarity= TIM_OCPolarity_Low;//Активное состояния выводов низкое прямых выводов.
pwm_fase.TIM_OCNPolarity= TIM_OCNPolarity_Low;//Активное состояния выводов низкое обратных выводов.
pwm_fase.TIM_OutputState= TIM_OutputState_Enable;//Включаем выводы прямой полярности.
pwm_fase.TIM_OutputNState= TIM_OutputNState_Enable;//Включаем выводы обратной полярности.
pwm_fase.TIM_OCIdleState= TIM_OCIdleState_Set;//При остановке TIM1 на прямых выводах будет низкий уровень.
pwm_fase.TIM_OCNIdleState= TIM_OCNIdleState_Reset;//При остановке TIM1 на обратных выводах будет низкий уровень.
pwm_fase.TIM_Pulse= 0;
TIM_OC1Init( TIM1, &pwm_fase);
TIM_OC2Init( TIM1, &pwm_fase);
TIM_OC3Init( TIM1, &pwm_fase);
//Включаем прерывание от окончания отсчёта периода TIM1 и от аварийной ситуации.
NVIC_InitTypeDef i_tim1;
i_tim1.NVIC_IRQChannel= TIM1_BRK_UP_TRG_COM_IRQn;
i_tim1.NVIC_IRQChannelCmd= ENABLE;
i_tim1.NVIC_IRQChannelPriority= 0;
NVIC_Init( &i_tim1);
TIM_ClearFlag( TIM1, TIM_FLAG_Update);
TIM_ITConfig( TIM1, TIM_IT_Update, ENABLE);
TIM_ClearFlag( TIM1, TIM_FLAG_Break);
TIM_ITConfig( TIM1, TIM_IT_Break, ENABLE);
//Настройка мёртвого времени и как должна срабатывать защита от аварийной ситуации.
TIM_BDTRInitTypeDef Protection_pwm;
Protection_pwm.TIM_AutomaticOutput= TIM_AutomaticOutput_Disable;//Разблокировка выводов при срабатывании защиты, установлено программное.
Protection_pwm.TIM_Break= TIM_Break_Enable;//Включен вывод защиты TIM1_BKIN( PB12).
Protection_pwm.TIM_BreakPolarity= TIM_BreakPolarity_Low;//При срабатывании защиты выводы в низком состоянии.
Protection_pwm.TIM_DeadTime= 12;//Значение 12 Dead-time 1 микросекунда, для IR2136( Data Sheet No. PD60166 revU, стр 5 в первой таблице) должно быть не меньше External dead_time>400 ns.
Protection_pwm.TIM_LOCKLevel= TIM_LOCKLevel_OFF;//Защита регистров от случайной перезаписи отключена.
Protection_pwm.TIM_OSSIState= TIM_OSSIState_Enable;//Состояние выводов во время остановки( IDLE) TIM1 включена.
Protection_pwm.TIM_OSSRState= TIM_OSSRState_Enable;//Состояние выводов во время работы TIM1 включена.
TIM_BDTRConfig( TIM1, &Protection_pwm);
>
//Функция запуска генерации ШИМ.
void Start_Pwm_Tim1( void) TIM_CtrlPWMOutputs( TIM1, ENABLE);
TIM_Cmd( TIM1, ENABLE);
>
//Функция остановки, установкой бита генерируем аварийную остановку и вызывается прерывание.
void Stop_Pwm_Tim1( void)< TIM1->EGR|= 0x80;>

Код настройки контроллера для работы с драйвером LCD TM1628 через интерфейс SPI и управления индикацией.


Хроника неудач в процессе разработки частотного преобразователя.

Первый испытательный пуск на двигателе 180 Ватт удачно, аппарат оставлен включенным, через две минуты взрыв выгорели дорожки вокруг диодных мостов. Причина не удачи забыл смыть активный флюс, урон не значительный убило стабилизатор L7805CV всё остальные компоненты живы.

нет рисунка

Второй испытательный пуск на двигателе 2.2 кВатт в жёстком режиме сразу 50 герц без плавного пуска и снижения коэффициента мощности, не запускается срабатывает защита по току с одной стороны радует с другой хотелось что бы он покрутился проверить нагрев транзисторов, решил закоротить шунты то есть убрать защиту. Пуск что то затрещало но двигатель не закрутился, выключил сразу включил тут сразу бабах, вывод не фига отключать защиту, итог ниже.

нет рисунка

goodspeedmen 2020-01-11 22:57:05
Я вижу проект претерпел серьёзные изменения! stm8 что отпал?

goodspeedmen 2020-01-11 22:59:15
Как на счет модулей типа FSBB30CH60C цена невелика (в Китае) а если стрельнет то все одно все выгорает.

teseiaaw 2020-01-14 00:03:18
stm8 вполне пригодны, но stm32f030 почти та же цена но больше возможностей!

teseiaaw 2020-01-14 00:06:56
FSBB30CH60C к этим модулям нужен радиатор который очень дорого стоит, транзисторы меньше греется.

transcription 2020-04-22 12:51:15
Добрый день! Отличная статья и видео. Можете помочь с поиском инфы или статей чтобы пересчитать на другой двигатель. У меня есть в наличии IR2136, STM32, разные мосфеты (IRF5330N, FPQ85N06, IRFZ44N, BUK7575-100A). Мне нужно управлять двигателем 500 Вт. Рабочее напряжение 60 В. Собираем электромашину для соревнования Shell-Eco marathon.

За активное участие

Оригинальный код контроллера был предложен mm.Mike, а я его сильно модернизировал под свои нужды (большой экран, пробник, карта высот, железо, которое сейчас продается на Али и т.д.). Сначала делал чисто для развлечения, Мач меня вполне устраивал. А потом понял, что для работы этот контроллер существенно удобнее и комфортнее, чем Мач.

Результаты тестирования подстройки по карте высот - здесь.

Сейчас занимаюсь переводом контроллера со 103-его на 407 процессор, он в два раза мощнее. Практически закончил, скоро выложу прошивку, печатную плату и инструкции по сборке.

Читайте также: