HardEgor 68 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба А проблема в чем? В том что 16-битный таймер вылетит в оверфлоу не закончив хода двигателя? Так там прескейлер можно задать. Вы попробуйте решить задачу для одного двигателя одним контроллером. Тогда и ясность появится. А то сейчас не имея внятной постановки задачи, можно много чего нафантазировать. Возможно проще будет поставить три простых контроллера, чем искать один супернавороченный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Мне нужно сделать драйвер для 3-х двигателей. Двигатели обычные DC Motors 24V. Двигатели имеют энкодеры для отслеживания позиции. Хотелось чтоб энкодеры были апаратные. Обычно это делается на таймерах. Вот задумался какой контроллер выбрать. PWM+Encoders требуют таймера. К тому же на мои нужды нужно еще 3 таймера. У ST вроде нет контролеров заточенных под motion. У TI есть но что то не хочется связываться с TI. К тому же 3 двигателя. Есть контроллеры под такую задачу? Основная проблема - аппаратно обработать 3 энкодера. На атмеловских AVRках я пользовался внешними интераптами но это, как мне кажется, не очень хороший способ. так не проще сделать это на плис программируемый PWM library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pwm_prog is generic( N : integer := 8); -- number of bit of PWM counter port ( i_clk : in std_logic; i_rstb : in std_logic; i_sync_reset : in std_logic; i_pwm_module : in std_logic_vector(N-1 downto 0); -- PWM Freq = clock freq/ (i_pwm_module+1); max value = 2^N-1 i_pwm_width : in std_logic_vector(N-1 downto 0); -- PWM width = (others=>0)=> OFF; i_pwm_module => MAX ON o_pwm : out std_logic); end pwm_prog; architecture rtl of pwm_prog is signal r_max_count : unsigned(N-1 downto 0); signal r_pwm_counter : unsigned(N-1 downto 0); signal r_pwm_width : unsigned(N-1 downto 0); signal w_tc_pwm_counter : std_logic; begin w_tc_pwm_counter <= '0' when(r_pwm_counter<r_max_count) else '1'; -- use to strobe new word -------------------------------------------------------------------- p_state_out : process(i_clk,i_rstb) begin if(i_rstb='0') then r_max_count <= (others=>'0'); r_pwm_width <= (others=>'0'); r_pwm_counter <= (others=>'0'); o_pwm <= '0'; elsif(rising_edge(i_clk)) then r_max_count <= unsigned(i_pwm_module); if(i_sync_reset='1') then r_pwm_width <= unsigned(i_pwm_width); r_pwm_counter <= to_unsigned(0,N); o_pwm <= '0'; else if(r_pwm_counter=0) and (r_pwm_width/=r_max_count) then o_pwm <= '0'; elsif(r_pwm_counter<=r_pwm_width) then o_pwm <= '1'; else o_pwm <= '0'; end if; if(w_tc_pwm_counter='1') then r_pwm_width <= unsigned(i_pwm_width); end if; if(r_pwm_counter=r_max_count) then r_pwm_counter <= to_unsigned(0,N); else r_pwm_counter <= r_pwm_counter + 1; end if; end if; end if; end process p_state_out; end rtl; квадратурный декодер например (по ссылке можно купить для "тренировки") (реализация учитывает направление вращения): library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity QuadratureDecoder is Port ( QuadA : in STD_LOGIC; QuadB : in STD_LOGIC; Clk : in STD_LOGIC; Position : out STD_LOGIC_VECTOR (7 downto 0)); end QuadratureDecoder; architecture Behavioral of QuadratureDecoder is signal QuadA_Delayed: unsigned(2 downto 0) := "000"; signal QuadB_Delayed: unsigned(2 downto 0) := "000"; signal Count_Enable: STD_LOGIC; signal Count_Direction: STD_LOGIC; signal Count: unsigned(7 downto 0) := "00000000"; begin process (Clk) begin if Clk='1' and Clk'event then QuadA_Delayed <= (QuadA_Delayed(1), QuadA_Delayed(0), QuadA); QuadB_Delayed <= (QuadB_Delayed(1), QuadB_Delayed(0), QuadB); if Count_Enable='1' then if Count_Direction='1' then Count <= Count + 1; Position <= conv_std_logic_vector(Count, 8); else Count <= Count - 1; Position <= conv_std_logic_vector(Count, 8); end if; end if; end if; end process; Count_Enable <= QuadA_Delayed(1) xor QuadA_Delayed(2) xor QuadB_Delayed(1) xor QuadB_Delayed(2); Count_Direction <= QuadA_Delayed(1) xor QuadB_Delayed(2); end Behavioral; или энкодер в плис это обычный счетчик импульсов... Далее добавляем двупортовую память в которую будем писать данные для выполнения и конфигурирования PWM В первый порт пишем принятые данные по UART (вы писали), я предлагаю SPI (не требуется синхронизации приемника и передатчика) С второго порта читаем данные и выдаем на PWM - результат контролируем с помощью квадратурного декодера (в реализации обычный компаратор) Вместо двупортовой памяти можно взять двуклоковое фифо Как в плис сделать из одного модуля три думаю догадаетесь :) Если хотите внешний MCU то предлагаю сделать соединение с ПЛИС с помощью external memory interfacе, т.е чтобы MCU видело ПЛИС как свою память ОЗУ + пару пинов для организации обмена прерываниями(окончанием работы(выполнения команды и др)) тогда в ПЛИС делаете двойной буфер и будет отличное решение Возможно не понадобится делать протокол обмена (парсер как Вы это назвали) Как то так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Возможно проще будет поставить три простых контроллера, чем искать один супернавороченный. Вот это, кстати, верно замечено. Я и сам предыдущей железяке (5 шаговиков, куча концевиков и Холлов, затвор на TLE5205 с контролем замыкания/обрыва, 8 платиновых термодатчиков, 8 DS18S20…) делал модуль управления на одном МК. Замучился, но работает. Но кабель получился жирным! Правда, там все механизмы внутри криостата — МК и силовые ключи туда не засунуть. Но вот новые железки, которые при Н.У. работают, собираюсь все-таки модульными делать: проще по 1МК (+драйвер[ы]) на 1-2 ШД с концевиками сделать и связать их CAN-шиной, нежели городить жуткий жгут проводов и огромную плату-контроллер! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Вот это, кстати, верно замечено. Я и сам предыдущей железяке (5 шаговиков, куча концевиков и Холлов, затвор на TLE5205 с контролем замыкания/обрыва, 8 платиновых термодатчиков, 8 DS18S20…) делал модуль управления на одном МК. Замучился, но работает. Но кабель получился жирным! Правда, там все механизмы внутри криостата — МК и силовые ключи туда не засунуть. Но вот новые железки, которые при Н.У. работают, собираюсь все-таки модульными делать: проще по 1МК (+драйвер[ы]) на 1-2 ШД с концевиками сделать и связать их CAN-шиной, нежели городить жуткий жгут проводов и огромную плату-контроллер! Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU? ПЛИС производит считывание с датчиков и управляет моторами. MCU производит управление ПЛИС и связь с внешним миром Сейчас SoC относительно не дорогие Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VCucumber 0 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба зачем брать N микропроцессоров(соответственно плат) N микропроцессоров всё ещё гораздо дешевле, чем 1 fpga, проще, потому что абсолютно одинаковые, и могут быть пространственно разнесены, потому что на разных платах, и маленькие одинаковые платы дешевле в мелкой серии, даже при равной площади, чем одна большая Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 68 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU? Вы почитайте другие темы ТС - у него не хватает желания или знаний или еще чего разобраться с простейшими вещами, а вы ему ПЛИС предлагаете.... С другой стороны, откуда взялось несколько плат? Надо просто сделать одну плату на 3 микроконтроллера. Все контроллеры будут иметь одинаковую программу, а управляющие сигналы запараллелить(хотя если там будет протокол с ответами, то сложнее) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 4 июля, 2017 Опубликовано 4 июля, 2017 (изменено) · Жалоба Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU? 1. Цена: 20-ногие STM8S003 стоят рублей 15 за штучку, 32-ногие STM32F103 — не больше сотни. 2. Простота: ПЛИСину запрограммировать намного сложней. Я, например, ни разу не сталкивался с ПЛИС, и даже не представляю, как в линухе с ними работать! 3. Аппаратный CAN позволяет сильно упростить низкоуровневую составляющую протокола. 4. И самое главное — намного меньше проводов! Если двигатели разнесены по закоулкам прибора, а места там — хоть отбавляй, то куда как красивее и проще будет сделать распределенную систему. К тому же, ее будет проще чинить: легче заменить один выгоревший блок и в офлайне перепаять выгоревшую деталь, нежели выдирать целиком плату управления всем. Если же и в случае централизованной системы делать такой ЗИП, чтобы просто поменять плату, то будет намного дороже и сложней в изготовлении, чем в распределенном варианте. И да, для совсем уж разовых штучек можно модуль МК делать съемным — берем на ибее "девборды" на STM32F103 по ~120р за штучку — вуаля! Не нужно паять МК (особенно это ценят люди с плохим зрением/моторикой) с обвязкой. Если ток небольшой, силовые ключи без радиаторов поместятся на плате прямо под МК — получится компактный "пирог" суммарной стоимостью максимум рублей в 500. Изменено 4 июля, 2017 пользователем Эдди Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 4 июля, 2017 Опубликовано 4 июля, 2017 (изменено) · Жалоба так не проще сделать это на плис да я бы с превеликим удовольствием сделал на FPGA. У меня все модули уже реализованы на FPGA. Но я столкнулся с проблемой которую озвучил в теме - Строковый парсер на VHDL. Это единственная проблема - сопряжение с РС (пользователем). ставить CPU+FPGA это оверкил. ставить несколько камней - не вижу смысла. STM32F3 имеет достаточно таймеров для 3-х энкодеров и 3-х PWM. Хотя я думал сделать модулярно - один аксис мэнэджер и модули отдельно. Есть система с 2 моторами - поставил 2 модуля, с 3 - поставил 3 модуля. Но я отказался от этой затеи. Слишком громоздко. Изменено 4 июля, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khach 35 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Для надежности как раз и применяют два STM32 - один занимается математикой и управлением, второй- управляет ШИМ и меряет токи по фазе. На начальной уровне так проще и надежнее. Запихнуть три канала по двигателям в один камень сложновато. Сами STM-ы максимум два двигателя на один контроллер сажали, но там было трехфазное векторное управление. Хотя по слухам были проблемы при большой разности скоростей или режимов двигателей. Для движков постоянного тока вообще самых мелких STM достаточно, главное чтобы ног на управление ШИМом и энкодером хватило. Ну и система защиты ( датчики тока, температуры, напряжения питания итд). Был еще вариант с обслуживанием аналоговых синус-косинусных линейных датчиков положения (оптических линеек) за счет АЦП STM32. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба А ведь по ним придется принемать решения(т.е. обрабатывать их) вне зависимости от того будет ли там у вас таймер или не таймер.... Около 170кГц? Ну и что? А нужно-ли принимать решение на каждом импульсе от энкодера? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба А нужно-ли принимать решение на каждом импульсе от энкодера?Ну учитывая, что по условию задачи энкодеры используются для отслеживания именно положения, то я думаю в том или ином виде обработать каждый импульс придется обязательно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Ну учитывая, что по условию задачи энкодеры используются для отслеживания именно положения, то я думаю в том или ином виде обработать каждый импульс придется обязательно! Что-то я не понимаю - зачем для определения положения ротора нужно на каждый импульс что-то делать?? Большое кол-во импульсов - это только для увеличения разрешения по углу. как я понимаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Большое кол-во импульсов - это только для увеличения разрешения по углу. как я понимаю. Правильно. Но если начать их пропускать то о каком отслеживании положения тогда идет речь? Ну т.е. как минимум нужно крутить в программе какой-нибудь счётчик угла.... Именно поэтому я ТСу давно говорил, что исходя из требуемой точности нужно выбрать энкодер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Правильно. Но если начать их пропускать то о каком отслеживании положения тогда идет речь? Ну т.е. как минимум нужно крутить в программе какой-нибудь счётчик угла.... А почему пропускать-то? Эти импульсы учитываются аппаратным счётчиком, процессор для этого не нужен. Процессор только в какой-то момент времени считывает накопленное значение из счётчика. Вот такие чтения, как я понимаю, совсем не нужно делать каждый импульс. Таких чтений наверное всего нужно одно или несколько на один оборот вала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khach 35 4 июля, 2017 Опубликовано 4 июля, 2017 · Жалоба Энкодер с аппаратным таймером считает все импульсы. Таймер генерит прерывание при переполнении и тогда программно учитываются старшие разряды счетчика положений. Другой таймер генерит прерывания с частотой петли ПИД по положения. Вот этот обработчик прерывания и берет текущее положение из энкодера и его старших битов и рассчитывает ошибку по положению. Вообще то в нормальном сервоприводе еще как минимум две петли ПИД будут- по току и по скорости. И петля по положению- самая медленная. Так что никакие шаги не теряются, вернее могут теряться, если сервопривод пытается делать удержание исполнительного механизма в неподвижности и попадает в дребезг. Тогда могут теряться позиции из за неправильного определения направления. Обычно это корректируется по прерыванию от индексной метки энкодера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться