Страница 10 из 20

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 16 янв 2017, 13:51
MX_Master
Механизм отлова внешних прерывания работает отлично! А вот моя опторазвязка на монтажке явно теряет шаги. Выяснил это, поиграв с переменными резисторами. Где-то с 2 КГц это очень заметно по текущей позиции оси в шагах.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 17 янв 2017, 04:22
Impartial
MX_Master писал(а):Далее для отладки нужен счетчик шагов и замер частоты,
Выгоднее измерять период сигналов шага.
Период характеризует основной параметр движения - мгновенную скорость. Перед умножением необходимо отфильтровать скачки скорости превышающие параметр максимального ускорения. Эти скачки - отражение недостатка операционной системы в плане реалтайма. Для этой цели наиболее подходящим является медианный фильтр который уберет эти скачки.
Но проще и правильнее сделать свою подсистему управления движением на основе получаемых из ЕМС заданий скорости или координат.
Эта задача наиболее эффективно реализуется на плисине.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 17 янв 2017, 04:45
Сергей Саныч
Impartial писал(а):Но проще и правильнее сделать свою подсистему управления движением на основе получаемых из ЕМС заданий скорости или координат.
Ключевое слово - EMC. В системах с закрытым кодом такое не всегда проходит. Приходится работать с тем сигналом, что есть. Не зря тот же Степмастер пользуется неплохим спросом.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 13:06
MX_Master
Проверял вчера быстродействие последней версии кода на STM32F4. Скорость работы всего кода получается на уровне 1 Мгц при постоянном STEP входе в 17 КГц для одной оси и умножителе = 2. Думаю, если все 5 осей подключить, то скорость работы будет в разы меньше.

Закралась мысль проверить как вообще падает скорость работы МК на простейших операциях. Создал чистый проект в Кубике, выставил все частоты на максимум (168Мгц) и в основной цикл программы добавил всего одну строчку

Код: Выделить всё

for (;;) {
  ++cnt;
}
это глобальная переменная, объявленная чуть выше как

Код: Выделить всё

volatile uint32_t cnt = 0;
компилирую, заливаю прошивку в МК и в STM Studio через ST-Link 2 SWD отслеживаю значение этой переменной.

За 1 минуту насчитывает примерно 1 680 000 000 циклов, т.е. в секунду это 28 000 000. Что теоретически можно считать за 28 МГц, что в 6 раз меньше максимума. Далее добавляем в главный цикл еще 4 паразитных операции (всего 5) и смотрим сколько насчитает на этот раз

Код: Выделить всё

for (;;) {
  ++cnt;
  --cnt;
  ++cnt;
  --cnt;
  ++cnt;
}
на этот раз в секунду отработало примерно 6 500 000 циклов. Что в теории 6.5 МГц. Получается уже в 24 раза меньше максимума. Далее добавил 8 паразитных действий (всего 9).

Код: Выделить всё

for (;;) {
  ++cnt;
  --cnt;
  ++cnt;
  --cnt;
  ++cnt;
  --cnt;
  ++cnt;
  --cnt;
  ++cnt;
}
на этот раз в секунду отработало примерно 3 500 000 циклов. Что в теории 3.5 МГц. И получается уже в 48 раз меньше максимума (168 Мгц).

На этом наглядном примере видно, что STM32F4 (168МГц), конечно, быстрее Меги2560 (16 Мгц). Но получить на нем отлов, обработку, умножение и вывод STEP сигналов на частоте более 1 МГц это из разряда фантастики (: Это надо на ассемблере прошивку писать, оптимизируя любую мелочь, чтобы добиться приемлемых результатов. Помню кто-то писал, что перестал считать такты МК, когда пересел на STM32 :hehehe: У меня так не получилось, я теперь каждую мелочь должен считать. Пойду делать ревизию на предмет ускорения...

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 13:47
AndyBig
Сгенерированный ассемблерный листинг не смотрели? Оптимизацию для компилятора указывали?

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:01
Serg
Надо не просто значения в регистрах менять, а выводить данные в порты - это ещё медленнее будет...

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:07
ozzy_sv
я извиняюсь но у меня есть идея )
есть такой себе драйвер TMC2100 https://www.trinamic.com/fileadmin/asse ... asheet.pdf

, и у него есть фишка - он шаг 16 размножает внутри cебя до 256
Так вот , сам драйвер слаботочный, до 2х ампер, но вот если к нему прикрутить внешние ключи :eat: или не пройдет :thinking: ??

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:11
ozzy_sv
Создал чистый проект в Кубике
индусы накодили HAL на славу :hehehe:

попробуйте перелезть на CMSIS

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:15
selenur
Что-бы выжать максимальную производительность, ассемблер не поможет, нужно с уметь правильно организовать логику, распределив операции которые выполняются на МК, и периферии. Т.к. некоторые вещи периферия может делать с большей частотой, чем это будет делать МК.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:21
selenur
ozzy_sv писал(а):
Создал чистый проект в Кубике
индусы накодили HAL на славу :hehehe:

попробуйте перелезть на CMSIS
индусы тут ни причем, это особенность работы МК, вот представим что у нас есть всего одна ассемблерная команда NOP, а частота МК 168 МГц, частота выполнения одной команды составит 84 Мгц, т.к. один такт на выполнение команды, и один на переход в начало программы, если код будет состоять из 2-х команд NOP то уже будет расходоваться на один цикл 3 такта МК, но с ростом количества команд, время выполнения одной команды не будет так резко падать.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 16:51
michael-yurov
А еще можно, выводя значение в порт менять состояние сразу 16 линий.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 18:52
MX_Master
AndyBig писал(а):Сгенерированный ассемблерный листинг не смотрели? Оптимизацию для компилятора указывали?
Для боевого кода оптимизация -O3, а в примере - только по размеру (-Os). Листинг не смотрел.
michael-yurov писал(а):А еще можно, выводя значение в порт менять состояние сразу 16 линий.
Я так делал в проекте на ардуине. Но на макетке с STM32F4 на любом порту всегда найдутся хотя бы пара пинов, которые чем-то заняты, то под отладку, то под светодиоды, то под кнопки. Так что слёту не получилось найти два абсолютно свободных порта под вход и выход. Но это всё поправимо, если надо - физически очищу занятые пины :hehehe: чтобы атомарно читать и писать сразу в порт.
selenur писал(а):Что-бы выжать максимальную производительность, ассемблер не поможет, нужно с уметь правильно организовать логику, распределив операции которые выполняются на МК, и периферии. Т.к. некоторые вещи периферия может делать с большей частотой, чем это будет делать МК.
А какая периферия в этой задаче поможет кроме встроенных таймеров/счетчиков и обработки внешних прерываний (EXTI)?

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 12 фев 2017, 23:11
Serg
MX_Master писал(а):Но на макетке с STM32F4 на любом порту всегда найдутся хотя бы пара пинов, которые чем-то заняты, то под отладку, то под светодиоды, то под кнопки.
Битбандинг работает так-же быстро...
Но проблема не в скорости записи бита или слова, проблема в частоте тактирования gpio.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 13 фев 2017, 06:51
MX_Master
UAVpilot писал(а):
MX_Master писал(а):Но на макетке с STM32F4 на любом порту всегда найдутся хотя бы пара пинов, которые чем-то заняты, то под отладку, то под светодиоды, то под кнопки.
Битбандинг работает так-же быстро...
Но проблема не в скорости записи бита или слова, проблема в частоте тактирования gpio.
Недавно читал пару статей с тестами частоты тактирования gpio (например). Мой код все равно работает куда медленней ))

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 17 фев 2017, 10:52
MX_Master
Убрал всё из основного цикла. Любой, даже мелкий, кодик в основном цикле мешает процессору нормально работать. Взамен перешёл на более продуманную работу со встроенным таймером. Причем, прерывания по переполнению счётчика таймера происходят не чаще, чем требуется для генерации выходного сигнала. Например, если частота на входе у нас до 20 КГц от LinuxCNC, а выходной множитель = 8 (для получения 160 КГц), то прерывание по таймеру происходит с частотой 20 * 8 * 2 = 320 КГц. Проц будет занят не сильно и позволит проводить доп. обработку буфера входа/выхода.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 17 фев 2017, 17:06
u37
Нет нужды разгружать фоновый процесс. Его задача - управление. Прерывания от таймеров (и др.) работают одинаково стабильно и при разгруженном и полностью заваленном фоновом процессе.
Просто перераспределите приоритеты - что должно выполняться вначале (в первую очередь), а что может немного подождать.
Кстати, вы в курсе, что у NVIC есть приоритеты прерываний. В том числе, разделение их на "группы". Нюанс - в возможности прерывать или не прерывать чужие прерывания того-же уровня.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 17 фев 2017, 21:35
michael-yurov
Можно еще и свое же собственное прерывание прерывать или не прерывать, в зависимости от задачи.
Т.е. процедура обработки прерывания может быть запущена во времы выполнения этого же самого прерывания.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 18 фев 2017, 19:19
MX_Master
Спасибо всем за советы. Прерывания изучил в самую первую очередь, еще до первой рабочей версии кода.
Ну что ж, последняя моя задумка оказалось самой живучей :) Воплотил в жись. Докладываю..

Тестировал только одну ось, т.к. опторазвязка на остальные еще не прилетела из Китая. Для тестов использовал тот же китайский CNC USB Controller MK1 (максимум 17 КНz). Умножение наблюдал только в STM Studio, т.к. логический анализатор также в пути.

Задача минимум для меня была - размножить шаги, выдаваемые LinuxCNC (20 КГц) до 200 КГц, которые поддерживает шаговый драйвер. Попробовал множитель = 8 при входящей частоте 17 КГц. При продолжительном тесте на одной из программок, не один шаг на входе и выходе не был потерян. Все чётко множилось и в итоге вернулось в 0. Полноценные масштабные тесты в живую будут по прибытии опторазвязки и логического анализатора. Заодно и осцилом потом глянем.

Код можно глянуть здесь - https://github.com/MX-Master/STEP_DIR_multiplier. Подробности в двух словах..

Используются только три файла:
  • shared.h - общак с настройками и переменными
  • main.c - краткая инициализация
  • stm32f4xx_it.c - всё, что касается прерываний
Настройки сейчас выглядят довольно просто

Код: Выделить всё

#define AXES                        5 // 1..5
#define MULT                        8 // output steps multiplier

#define INPUT_MAX_FREQUENCY         20000 // Hz

// direction change delays
#define OUTPUT_DIR_DELAY_BEFORE     50 // us
#define OUTPUT_DIR_DELAY_AFTER      50 // us
Входные/выходные пины лежат здесь, но их лучше настраивать в проекте CubeMX.
2017-02-18_220200.png (2611 просмотров) <a class='original' href='./download/file.php?id=103709&mode=view' target=_blank>Загрузить оригинал (42.56 КБ)</a>
2017-02-18_220445.png (2611 просмотров) <a class='original' href='./download/file.php?id=103710&mode=view' target=_blank>Загрузить оригинал (40.16 КБ)</a>
Заказал еще макетку с STM32F103C8Tx на борту (2$). Под нее код будет доработан и выложен чуть позже.

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 18 фев 2017, 19:53
MX_Master
Забыл в двух словах принцип работы объяснить..

Входные шаги и смену направлений у нас ловят обработчики внешних прерываний (EXTI). Шаги ловят 5 первых отдельных линий EXTI (от 0 до 4) по фронту или спаду (на выбор). Смену направлений ловит общая линия EXTI (от 5 до 9). Соответственно, можно умножать шаги для 5-ти осей. Каждое входное прерывание добавляет данные сразу в выходной буфер.

Выходом занимается отдельное прерывание по таймеру, в котором идёт генерация шагов и направлений на основе выходного буфера. Прерывание запускается с частотой 2 * МНОЖИТЕЛЬ * МАКС. ВХОДНУЮ ЧАСТОТУ. Например, для множителя = 8 и 20 КГц на входе, генерация выхода будет работать на частоте 320 КГц. Сделано так, чтобы не отнимать у процессора больше времени, чем нужно.

Фильтров на входе/выходе пока никаких нет. Поэтому, если скважность входного сигнала будет плясать влево/вправо, на выходе будет примерно также :hehehe: Со временем чё-ньть придумаем с фильтрами..

Re: Умножитель STEP/DIR на STM32 F1/F4

Добавлено: 18 фев 2017, 21:06
Serg
MX_Master писал(а):#define AXES 5 // 1..5
Это какие 5 топоров?.. Ты вроде умножитель для осей (AXIS) делал... :)