Перейти к содержанию
    

Как состряпать алгоритм синусоидального ШИМ?

ТС-у всего лишь генерировать ровный синус, а не рваный модулированный сигнал.

Так что даже таблица избыточна. Простое вычисление (1-2 такта на отсчет) в самый раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Сергей Борщ сказал:

У меня по такому принципу ATmega88

Вот именно, что Атмега. А у ТС-а - ARM. Зачем это безобразие тащить в ARM, который имеет нормальную математику???

Уже 100500 раз говорил: для генерации синусоиды на ARM достаточно одной MAC-операции на отсчёт. Надо просто вспомнить школьный курс тригонометрии. Это гораздо быстрее, чем даже просто из флеша МК читать.

У меня сейчас, в текущем проекте, как раз работает генератор синусоиды. Генератор работает на частоте сэмплирования ЦАП = ~13 МГц на МК работающем на тактовой 144 МГц (XMC4700) занимая ~73% времени CPU на расчёт (в буфер DMA с двойной буферизацией). Т.е. - тратится примерно 8 тактов на сэмпл (учитывая все накладные расходы: умножение на требуемую амплитуду, ограничение, сохранение в ОЗУ, обслуживание цикла и т.д.). И никаких монстроидальных таблиц в ОЗУ или флешь. На таблицах во флешь такой скорости работы не достичь в принципе. Какими бы большими их не делай. И работает прекрасно - генерит синусоиду около 200 кГц, такую гладкую, что даже фильтр после ЦАП оказался не нужен.  :wink:

;Генератор синусоиды (рекуррентный).
GenSineR:      PUSH     {R4, R5, LR}
               LDR      R4, sineT
               LDRD     R12, LR, [R4, #GenPrm_magn]
               MOVS     R5, #0
genSineR_01:   SUBS     R0, R5, R0, ASR #2
               SMMLA    R0, LR, R1, R0
               SSAT     R0, #30, R0
               LSLS     R0, R0, #2
               SMMUL    R4, R12, R0
               ;;;UBFX     R4, R4, #0, #12
               STR      R4, [R2, #4]!
               SUBS     R1, R5, R1, ASR #2
               SMMLA    R1, LR, R0, R1
               SSAT     R1, #30, R1
               LSLS     R1, R1, #2
               SMMUL    R4, R12, R1
               ;;;UBFX     R4, R4, #0, #12
               SUBS     R3, R3, #2
               STR      R4, [R2, #4]!
               BNE.N    genSineR_01
               POP      {R4, R5, PC}

Вот и весь генератор. Нетрудно убедиться, что затраты на 1 генерируемый сэмпл == ~8 тактов. 2 отсчёта синуса генерятся полиномом (~30 тактов на отсчёт). Затем: (2048-2) отсчётов - рекуррентно этим кодом (на основании первых двух отсчётов). Накапливаемая ошибка - значительно ниже используемых старших 12 разрядов. Поэтому никак не влияет на результат.

 

PS: Только смотреть его не советую некоторым особо упёртым персонажам, гнущим вовсю таблицы. И называющих глупцами всех, кто умеет думать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, jcxz said:

PS: Только смотреть его не советую некоторым особо упёртым персонажам, гнущим вовсю таблицы

Так через таблицу это всё делает контроллер DMA, не тратя такты процессора. Проц рассчитал значения в таблице- и всё, дальше само крутится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, tonyk_av сказал:

Так через таблицу это всё делает контроллер DMA, не тратя такты процессора. Проц рассчитал значения в таблице- и всё, дальше само крутится.

Вы путаете. "Проц рассчитал" - это про алгоритм, о котором я говорю. А те табличные методы, о которых тут говорилось выше - проц не рассчитывает в runtime, они в постоянной памяти хранятся.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, Arlleex сказал:

ТС-у всего лишь генерировать ровный синус, а не рваный модулированный сигнал.

Так что даже таблица избыточна. Простое вычисление (1-2 такта на отсчет) в самый раз.

Мне нужно оперативно менять частоту синусоиды при постоянном периоде ШИМ, также оперативно менять амплитуду синусоиды. Если можно приведите простое вычисление, ну пусть в 10 тактов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А один участвующий поцык тут обещал "~1 такт (ARM)" 🙂 А тут уже и 8, и 30 тактов. Эх, вот так и верь ...

Изменено пользователем Variant99

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

24 минуты назад, jcxz сказал:

Насколько оперативно?

Это предполагается частотный привод.Так, что он постоянно в слежении и на входе постоянно меняется задание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, khlenar сказал:

Это предполагается частотный привод.Так, что он постоянно в слежении и на входе постоянно меняется задание.

"сколько вешать в граммах"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, jcxz сказал:

"сколько вешать в граммах"?

Я не знаю как вам ответить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, khlenar сказал:

Я не знаю как вам ответить...

Как же тогда вам примеры приводить, если вы даже не можете сказать что вам нужно в числах?

"Оперативно" - понятие растяжимое. Раз в 1мкс - оперативно? Или раз в 1сек - оперативно? ...

PS: Приведённый мной выше код, работает в моём генераторе и позволяет менять частоту хоть каждый период 13000000/2048=6.34кГц. Всего лишь изменив размер буфера DMA, можно изменить это значение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если бы jcxz хоть раз делал бы частотный привод, он бы знал, "насколько оперативно" надо :))) А коль спрашивает - значит не делал. :)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, jcxz said:

проц не рассчитывает в runtime, они в постоянной памяти хранятся.

С чего бы это вдруг? Таблица в ОЗУ, значения рассчитываются в зависимости от управления. ТС нужно менять скважность, мне нужно было менять частоту для управления шаговым двигателем.

14 minutes ago, khlenar said:

Все основные расчеты делаются в период 1мсек.

Это ж какая частота несущей? И откуда взялась 1мс? и что понимается под "основные расчеты"? Если параметры одного импульса, то выше показали примеры вычислений. Пока не очень понятно, что нужно.

Изменено пользователем tonyk_av

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, tonyk_av сказал:

С чего бы это вдруг? Таблица в ОЗУ

6 часов назад, Сергей Борщ сказал:

Имеем предварительно рассчитанную таблицу одного (половины/четверти/одной восьмой) периода в постоянной памяти

9 минут назад, tonyk_av сказал:

ТС нужно менять скважность

Для изменения скважности ШИМ по синусоидальному закону, достаточно значения вычисленные например с помощью моего кода, подать не в ЦАП, а в регистр сравнения ШИМ.

Опять же - таблицы в постоянной памяти не нужны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...