Управление шаговым двигателем на STM32

Автор
avatar-alexevsalexevs
Соавторы
avatar-andrewraysandrewrays
Notebook

Генерация кода для STM32 (Полношаговое управление шаговым двигателем)

Введение

В этом демонстрационном примере реализуется аппаратное воплощение примера полношагового управления биполярным шаговым двигателем.

Аппаратная часть

Объект управления этого примера - биполярный шаговый двигатель 17HS1352-P4130, как и было уже указано в примере моделирования. В качестве преобразователя используется двойной полномостовой MOSFET-драйвер L6206PD на базе платы расширения X-NUCLEO-IHM04A1. Эта плата совместима с отладочной микроконтроллерной платой STM NUCLEO F446RE, работа с цифровыми входами/выходами которой рассмотрена в соответствующем примере.

На рисунке ниже приведена схема соединений привода.

scheme.png

Согласно распиновке и принципиальной схеме платы IHM04A1, а также функциональной схеме драйвера, входы EN-A и EN-B предназначены для аппаратного включения/отключения мостов А и B драйвера. Входы IN1A и IN2A управляют первым и вторым плечами моста А, входы IN1В и IN2В - моста В.

image.png

Входы управления подключены к GPIO отладочной платы, как указано на схеме соединений. Частота следования сигналов на управляющие входы, согласно данным мотора, не более 250 Гц. Ввиду этого для реализации управления достаточно использовать периферийный модули цифровых входов, модули ШИМ в этом примере рассматриваться не будут.

Модель системы управления

В сравнении с моделью, используемой в исходном примере, новая модель отличается только блоками периферии контроллера на базе блоков C Function и блоками согласования типов данных/размерности входных сигналов. Все они внесены в подсистему "Control System".

image.png

Блоки C Function "BUTTON_GPIO_PC13" и "LED_GPIO_PA5" уже были показаны в примере цифровых входов/выходов STM32. Блок C Function "NUCLEO_IHM04A1" необходим для реализации взаимодействия управляющего алгоритма с периферией, используемой для управления драйвером - цифровыми входами PA10, PB4, PB5, PC1, PA0, PA1. Также этот блок реализует исключительно полношаговое управление драйвером.
При подаче на вход блока enable высокого уровня сигнала, высокий уровень устанавливается и на GPIO PA10, PC1, что включает оба моста драйвера. На вход pulses блока передаётся вектор состояний GPIO PB4, PB5, PA0 и PA1, тем самым включая/выключая соответствующие ключи драйвера.

В данном блоке также следует обратить внимание на то, что состояния входов на прошлом шаге сохраняются в глобальных переменных flag и flags. Эти переменные объявляются во вкладке Shared Code блока.

Пользовательская программа со сгенерированный из подсистемы "Contol System" алгоритмом будет работать следующим образом: по заднему фронту сигнала после нажатия на кнопочный контакт, встроенный в плату, зажигается встроенный в плату светодиод, включаются мосты драйвера и начинается последовательное формирование управляющих импульсов. Последовательность импульсов для вращения валом двигателя по часовой стрелке соответствует выдаче импульсов на входы в очерёдности PB4-PB5-PA0-PA1. После повторного нажатия на кнопочный контакт мосты драйвера и светодиод выключаются, выдача импульсов прекращается.

Результаты моделирования

Так как мы внесли изменения в первоначальную модель, смоделируем её снова, повторяя аналогичные шаги исходного примера Так мы удостоверимся в идентичности работы алгоритмов и проверим корректность работы с сигналами, поступающими на блоки C Function.

Загрузка нужных библиотек:

In [ ]:
using Plots
using DataFrames
plotlyjs();

Запуск модели:

In [ ]:
modelName = "stm32_sm_fullstep_control";
if modelName  getfield.(engee.get_all_models(), :name)
    engee.load( "$(@__DIR__)/$(modelName).engee");
end

model = engee.run(modelName);

Чтение данных о мгновенных значения напряжений и токов, а также скорости вращения и положения вала:

In [ ]:
t = model["Speed"].time;
Ia = model["Ia"].value;
Ib = model["Ib"].value;
Va = model["Va"].value;
Vb = model["Vb"].value;
Speed = model["Speed"].value;
Position = model["Position"].value;

Построение графиков положения и скорости вращения вала:

In [ ]:
plot(t, Position, layout = (2,1), ylabel = "Положение, град", legend = :none)
plot!(t, Speed, subplot = 2, ylabel = "Скорость вращения, рад/с", xlabel = "Время, c", legend = :none)
Out[0]:

Построение графиков фазных токов и напряжений:

In [ ]:
plot(t, [Va Vb], label = ["Va" "Vb"], ylabel = "Фазные напряжения, В", color = [:red :blue], layout = (2,1), subplot = 1)
plot!(t, [Ia Ib], label = ["Ia" "Ib"], ylabel = "Фазные токи, А", xlabel = "Время, c", color = [:green :black], subplot = 2)
Out[0]:

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

Генерация кода и сборка проекта

Сгенерируем код из подсистемы Control System:

In [ ]:
engee.generate_code("$(@__DIR__)/$(modelName).engee",
                    "$(@__DIR__)/code/";
                    subsystem_name = "Control System")
[ Info: Generated code and artifacts: /user/start/examples/codegen/stm32_sm_fullstep_control/code

Полученные файлы скачаем и добавим в проект в среде разработки VS Code + PlatformIO. Код пользовательской программы примера приведён в файле /stm32_sm_fullstep_control/main.c, его также добавим в проект. Работа со сгенерированными файлами в VS Code + PlatformIO во фрэймворке stm32cube показа в примере мигающего светодиода на STM32.

Выполнение кода на STM32

После загрузки кода в микроконтроллер перейдём к выполнению программы.

vid480.gif

По нажатию на кнопку, встроенную на плате NUCLEO, шаговый двигатель запускается и останавливается.

Вывод

В этом примере мы доработали модель полношагового управления шаговым двигателем, добавив блоки периферии микроконтроллера. Алгоритм управления работает корректно на реальном объекте управления.