Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: генерация 12 шимов
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
srm
сейчас переделываю своё устрорйство с atmega32 на at91sam7. с последним контроллером я не знаком и не знаю с какой стороны лучше подойти к следующей задаче. нужно сгенерировать 12 шимов с периодом повторения T = 20мс и длительностью импульса 0.9 .. 2.1 мс. На авре я использовал прерывание от таймера и по нему устанавливал/сбрасывал нужный пин. в результате период повторения был несколько больше 20 мс, но всё работало.

pin0 _--______
pin1 ___--____
pin2 ____--___
..

вобщем на арме скорее всего придётся делать подобным образом, но может есть какой-нибудь более красивый способ..?
aaarrr
Цитата(srm @ Jan 9 2010, 21:39) *
вобщем на арме скорее всего придётся делать подобным образом, но может есть какой-нибудь более красивый способ..?

Если взять SAM7A3, то можно и аппаратно устроить 12 каналов. На остальных придется программно. Если не нужна большая разрядность (которую не грех было бы указать сразу) и какие-то особые требования к джиттеру, то способ вполне сойдет за "красивый".
srm
Цитата(aaarrr @ Jan 10 2010, 00:26) *
Если взять SAM7A3, то можно и аппаратно устроить 12 каналов. На остальных придется программно. Если не нужна большая разрядность (которую не грех было бы указать сразу) и какие-то особые требования к джиттеру, то способ вполне сойдет за "красивый".

at91sam7s256. пасиб. есть идейка генерировать не так:

pin0: __--__________--_____
pin1: ____--__________--___
pin2: ______--__________--_

а так:

pin0: __--__________--_____
pin1: __--__________--_____
pin2: __--__________--_____

т.е. устонавливать все пины в один момент, а сбрасывать по мере срабатывания. только есть подозрение, что при одинаковых временах будет сильно глючить из-за отложенных прерываний. так было на авре, на арме, думаю, данный способ может быть прокатит...?
aaarrr
Цитата(srm @ Jan 9 2010, 22:34) *
т.е. устонавливать все пины в один момент, а сбрасывать по мере срабатывания. только есть подозрение, что при одинаковых временах будет сильно глючить из-за отложенных прерываний. так было на авре, на арме, думаю, данный способ может быть прокатит...?

Синхронные 12 каналов сделать много проще, естественно. Почему только "одинаковые времена" должны как-то сказываться? Все каналы обрабатываются в одном прерывании, на ARM'е можно задействовать под это дело FIQ для пущей пущести.
srm
Цитата(aaarrr @ Jan 10 2010, 01:10) *
Синхронные 12 каналов сделать много проще, естественно. Почему только "одинаковые времена" должны как-то сказываться? Все каналы обрабатываются в одном прерывании, на ARM'е можно задействовать под это дело FIQ для пущей пущести.


ну.. я не знаю как арм, но авр как-то долго обрабатывает прерывание. на сохранение регистров уходит довольно большое время, что приводит к глюкам.
aaarrr
Цитата(srm @ Jan 10 2010, 02:39) *
ну.. я не знаю как арм, но авр как-то долго обрабатывает прерывание. на сохранение регистров уходит довольно большое время, что приводит к глюкам.

ARM обрабатывает еще дольше, если считать в тактах. Только вот к глюкам приводит отнюдь не долгое сохранение регистров.
На частоте MCK 48MHz и восьмибитном 50Hz ШИМе на один такт последнего придется 3750 тактов процессора, что более чем достаточно хоть для 12, хоть для 120 каналов.
ReAl
Цитата(srm @ Jan 9 2010, 20:39) *
нужно сгенерировать 12 шимов с периодом повторения T = 20мс и длительностью импульса 0.9 .. 2.1 мс.
Не совсем понятны требования.
Длительность импульса изеняется только в пределах 0,9-2,1, длиннее не быват? А с какой дискретностью?
srm
Цитата(ReAl @ Jan 10 2010, 13:27) *
Не совсем понятны требования.
Длительность импульса изеняется только в пределах 0,9-2,1, длиннее не быват? А с какой дискретностью?

да, должны быть такие пределы. что касается разрешения по времени, то, думаю, достаточно разбить весь промежуток на 100 частей, т.е. ~16 us.
ukpyr
сервы smile.gif ?

должно хватить одного таймера, импульсы формировать можно программно (прерывание таймера с высоким приоритетом).
если нужна субмикросекундная точность и контроллер серезно нагружен другими задачами, нужен таймер с ШИМом и внешним коммутатором (напр. 2x74HC4051). по переполнению таймера включается соответствующий канал коммутатора и загружается значение ШИМа.
хотя для точной выдержки 20мс цикла нужно 2 ШИМа, в 20мс влезет макс.9 каналов.

Цитата
Длительность импульса изеняется только в пределах 0,9-2,1, длиннее не быват? А с какой дискретностью?
думаю 8 бит хватит http://www.hooked-on-rc-airplanes.com/servo-tutorial.html
ReAl
Цитата(srm @ Jan 10 2010, 14:33) *
достаточно разбить весь промежуток на 100 частей, т.е. ~16 us.
Тыщща тактов процессора на тик. "Швабода"
Посмотрите тему http://electronix.ru/forum/index.php?showtopic=61182&hl=
Для всех каналов одновременно выводить значение из подготовленного массива, т.е. все импульсы начинаются одновременно, заканчиваются кто когда. Если несколько должны заканчиваться одновременно, то так и будет за одно прерывание, просто в следющей маске для вывода будет несколько бит взведено.
На AT91SAM7 маски формировать удобнее под вывод в PIO_СODR, тогда для каждого выхода 1-ка в массиве будет в одном слове.

p.s[0] Жаль, что DMA у AT91 не умеет по таймеру пересылать из памяти PIO_SODR (по сути тоже в память), было бы вообще чудесно, джиттр минимальный и нагрузка на ядро никакая.

p.s[1] А DMA ATXmega умеет пересылать откуда угодно куда угодно по event-ам, которые могут и таймером активироваться, но порты 8-битные, а инкремент адреса получателяв burst-е на расстояние между двумя портами невозможен (хотя можно и два канал задействовать, но это уже жирно).
"нет в жизни совершенства"
srm
Цитата(ukpyr @ Jan 10 2010, 18:03) *
сервы smile.gif ?[/url]

угум. сервы. просто я видел в продаже плату, насколько мне помнится, на 20 серв. плата эта собрана на восьмой меге. вобщем скорее всего они извратились и разбросали сервы на все 3 таймера, вобщем сделали гавнокод, хоть и рабочий. а может и как-то по другому - не знаю. вот и спрашиваю - может быть есть мегаспособ завязать всё красиво, на одном таймере. хотя, можно разделить во времени, скажем на 1 мс. совпадения возможны, но будут происходить редко:

pin0: __--_____
pin1: ___--____
pin2: ____--___
ReAl
Цитата(srm @ Jan 10 2010, 16:22) *
угум. сервы. просто я видел в продаже плату, насколько мне помнится, на 20 серв. плата эта собрана на восьмой меге.
Ну так для 100 градаций у меги 300 байт под массив для 20 выходов найдётся.
Тактовая ниже, 16мкс*16МГц = 256, но если писать на асме - то с указателем и счётчиком, находящимися уже в регистрах, прерывание будет очень коротким.
ukpyr
Цитата
вот и спрашиваю - может быть есть мегаспособ завязать всё красиво, на одном таймере. хотя, можно разделить во времени, скажем на 1 мс. совпадения возможны, но будут происходить редко
на одном таймере на получится выдержать период повторения 20мс на 12 каналов. В 20мс поместится 9 тайм-слотов по 2.1мс на серву. Если нарушить ограничение периода повторения, наверно можно впихнуть 12 каналов на один таймер (непонятно как к этому отнесутся сервы, нужно проверять, не думаю что это так критично). Поэтому или 1 таймер с периодом 26мс, или 2 с периодом 20мс.
srm
вот такой вопрос ещё. чтобы сгенерировать шим с заданной длиной импульса нужно значть частоту, насколько я понимаю. как можно вычислить частоту? только разобрав значение регистра AT91C_BASE_PMC?
aaarrr
Цитата(srm @ Jan 10 2010, 23:29) *
вот такой вопрос ещё. чтобы сгенерировать шим с заданной длиной импульса нужно значть частоту, насколько я понимаю. как можно вычислить частоту? только разобрав значение регистра AT91C_BASE_PMC?

AT91C_BASE_PMC - это совсем даже не регистр.

Обычно частоту MCK задает (и знает) программист. И так уж случилось, что в большинстве случаев для SAM7 она оказывается равна 48MHz (т.к. на борту только одна PLL, а хочется еще и USB).
srm
Цитата(aaarrr @ Jan 11 2010, 01:45) *
AT91C_BASE_PMC - это совсем даже не регистр.

Обычно частоту MCK задает (и знает) программист. И так уж случилось, что в большинстве случаев для SAM7 она оказывается равна 48MHz (т.к. на борту только одна PLL, а хочется еще и USB).

это понятно, просто хочется абстрагировать код от конктретного состояния PLL. чтобы если что-нибудь менять, то потом по всей программе бегать, а поменять только в одном месте.
aaarrr
Ну, заведите переменную или дефайн, содержащий частоту MCK в герцах.
adnega
Можно все 20мс разбить на куски по 2.5 мс, генерить 2 однократных PWM-импульса и подавать их на входы управления двух дешифраторов, по окончании PWM изменять адрес дешифратора на следующий -> 16 каналов PWM
koyodza
Возьмите STM32 - там 16 каналов таймеров (4х4) можно замутить
skripach
Цитата
Возьмите STM32 - там 16 каналов таймеров (4х4) можно замутить

Расчудесный программный шим работает на STM32 10бит, 16каналов,~100Гц, и времени ещё куча smile.gif
nicks80
используй за ранее подготовленный табличный шим его и выводи.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.