Pull to refresh

Comments 10

Использование дма снижает нагрузку процессора, да это так. Но с другой стороны порождает ещё большую проблему — где я сейчас.
В момент пропуска шага программа просто встанет колом, определить текущее положение — это обратная функция, требующая многократно больших ресурсов. Которых явно не хватит для решения проблемы в реальном времени.
В место этого имеет смысл сразу рассчитывать время текущей точки положения и серии новых точек. Как не крути, получается векторное управление.
Главная проблема Marlin (о которой я писал в первой части, ссылка — в начале статьи) как раз состоит в том, что там одна задача строит эти самые вектора, а другая — выдаёт шаги. И вот эти самые шаги съедают почти всю процессорную мощь, так как прерывания приходят безумно часто. Подробнее — во введении к первой части (оно огромное, перетаскивать в комментарий не стоит).

Предлагаемое решение — именно для второй задачи. Нам построили вектор. В классике — дальше начинаем шагать средствами процессора (с возможными вылетами за допустимую производительность, решаемой подачей двух или более шаговых импульсов на прерывание). В нашем случае — строим график шагов в памяти, после чего за нас шагает аппаратура (причём для каждого двигателя — независимо, так как у каждого свой UDB). И как дошагает, так мы знаем, где мы. Полная аналогия с шагающим обработчиком прерываний Marlin, только без отвлечения ЦП. И с возможной большей частотой шагов.

Процессорному ядру никто не мешает в это время строить график шагов для следующего вектора, чтобы не было задержек. Уж что-что, а задержки мне знакомы, я ради них три версии Wifi «прошивки» для ESP8266 делал, первые две подтормаживали чуть-чуть.

Но главное применение данной информации — это изучение возможностей UDB. Потому что интереснее изучать такие вещи на чём-то, более серьёзном, чем мигание светодиодами. Вот, хороший повод.
Если все правильно понял, то в первой части сделано: два таймера связанных паровозиком( в блоках STM32).
Первый генерит импульсы( в режиме ШИМ), а второй их считает. Да это преимущество перед STMом, т.к. ему на 5 шаговиков потребовалось бы 10 таймеров.

А вот во второй уже используется DMA( в том числе в качестве счетчика циклов), а из UDB собраны аналоги PWMа?
т.е. в данной ситуации выигрыша перед STM уже нет( как минимум, а то и хуже ибо тыкать(конфигурировать) придется дольше)?
По первой части — не совсем два таймера. Если уж на то пошло, то три таймера.

1) Одновибратор, вырабатывающий сигнал Step нужной длины
2) Таймер задержки одного шага
3) Счётчик шагов

Только они связаны логикой, недоступной центральному процессору. Не факт, что STM32 сможет их переключать так же без отвлечения на каждом шаге.

По второй части — как Вы обычному ШИМу обеспечите точную подстройку частоты? Когда двигатель работает в одиночку — это не критично, но когда они шагают вместе — важно, чтобы средняя частота у них была завязана так, чтобы они остановились все в один и тот же момент времени. Но беда в том, что здесь совсем не ШИМ. Отличительная особенность ШИМ — постоянная частота, но разная скважность. У меня частота при разгоне и торможении — разная (при этом одновибратор, вырабатывающий импульс STEP никто не отменял). Так что и тут Вы не совсем правы.

И опять же, главная фишка в том, что подстройка всех этих параметров на критичном по времени участке не отвлекает ЦП. ЦП построил задание и ушёл. Строить он может с любой скоростью и любыми отвлечениями. Главное — чтобы успел построить к моменту, когда пора начинать. Шагать надо — точно. И именно этим занимается UDB, а не ЦП. Именно он отмеряет время между шагами, именно он формирует ход шагов.

Но ещё раз повторю, я тут не защищаю какую-то новую систему управления двигателями. Банальному STM32 в режиме прерываний от таймера уже хватает мощи на всё про всё, это Меге не хватало при микрошаге 1/32. Я просто нашёл интересные красивые решения для UDB. А на некрасивых всё уже давно работает.
1) Одновибратор, вырабатывающий сигнал Step нужной длины
2) Таймер задержки одного шага

Просто не вижу функциональных отличий от таймера( 1шт) в режиме ШИМ с фиксированной длительностью( 92 цикла) и изменяемым периодом.
Преложенный вариант требует 2х счетчиков и 2х компараторов, а ШИМ: 1 счетчик и 2 компаратора( Тут даже интересно потребление ресурсов UDB для этих вариантов).

По второй части — как Вы обычному ШИМу обеспечите точную подстройку частоты?

А вот это аппаратно уже «STMе» сделать уже не получится. Только программно модулировать период ШИМа( через DMA).
Просто не вижу функциональных отличий от таймера( 1шт) в режиме ШИМ с фиксированной длительностью( 92 цикла) и изменяемым периодом.
Хорошо. Согласен. Правда, пока не ясно, как завязать работу этих двух таймеров (шагающего и считающего шаги), чтобы после каждого шага не задействовать ЦП. А ещё 32 битных таймеров у STM32 не так много, а 16 битов нам не хватит для хорошего задания всех требуемых частот. А если в ход пойдёт перепрограммирование делителей входной частоты, то тут уже пойдёт такая математика (чтобы константу 92 поменять), что проще не извращаться, а построить систему по классическому варианту, что на STM32, собственно и делается на практике.

Но ещё раз повторю, что цель цикла статей — показать, как можно работать с UDB. Не по принципу «Товарищи! Все переходим на это!», а просто чтобы все имели в виду. Меня оно в одном проекте сильно выручило. Детали из-за NDA не могу раскрыть, но на STM32 оно не решалось (требуемая скорость великовата была), а добавлять ПЛИС — это ещё один корпус с обвязкой и кучей ног STM на связь с ПЛИС (скорость же нужна была высокая). На UDB же всё прекрасно сделалось с применением единственного корпуса самого PSoC. Причём эта штука может даже без стабилизатора работать — она почти всеядна по питанию (от 2.7 до 5.5В). Поэтому владеть навыками программирования таких систем — стоит. Практиковаться лучше на чём-то интересном и более-менее сложном. Посему управление шаговиками — всего лишь иллюстрация на более-менее боевых вещах, что отражено в тексте.

Так что мне кажется, что говорить «На STM32 в целом, можно достичь примерно того же» — не совсем корректно. Ключевое слово — «примерно». Тут или всё, или ничего. Или очень красиво, но на UDB, или «в лоб», но на STM32. Полумеры нужны только когда для решения «в лоб» не хватает мощности, но её же хватает. А для такой же красоты — не хватает связующих звеньев, которые живут в UDB.

Иногда дело не только в красоте, но это уже не учебные задачи. Но я зацикливаюсь в рассуждениях… Поэтому обрываю их.
У меня сейчас сходная задача, но я не стал напрягаться, сделал на М3 и профиль трапеция по Austin/AVR446. Но интересно поиграться
как завязать работу этих двух таймеров (шагающего и считающего шаги)
Попробовать на перемычке TIO и ICP?
Попробовать на перемычке TIO и ICP?
Кстати, чисто к слову. У PSoC есть две очень приятных особенности по сравнению с обычными контроллерами

1) Если мы хотим соединить ножки — мы это просто через внутреннюю коммутацию делаем. Точнее, мы соединяем сигналы, а ресурс «ножки» при этом не расходуется.

2) Не надо думать о схождении пасьянса ножек. Я когда перетаскивал Marlin с Ардуино на STM32, долго и упорно раскладывал пасьянс, ведь часть ножек может быть выходом таймера, часть — входами АЦП, часть — SPI, часть — UART, причём часто на одной ноге может быть часть функций на выбор, а одна функция выбрасывается всего на 2-3 ножки. Короче, пасьянс я раскладывал долго. А тут всё через трассировку делаем. Какую ножку на функцию назначили, на ту нам и выбросят сигнал. Ибо всё-таки простенькая, но ПЛИС внутри. Теоретически, даже аналоговая коммутация есть, но на практике не проверял, только видел, что сопротивление будет килоомное.

Но это так, просто к месту высказывание. Само собой, за это надо платить. Причём рублями. При равных ядрах Cortex M3 в PSoC5LP и STM32F103, первый дороже. Но если его уж по тем или иным причинам взяли, то эта особенность очень греет душу.
Only those users with full accounts are able to leave comments. Log in, please.