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

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

34 минуты назад, gerber сказал:

Да. И правильно тут советуют, рассчитать значения CCR таблично и обработчике UIF только перенести очередное значение в CCR. Нехорошо в обработчике прерывания вести float-вычисления.

Городить какие-то монстроидальные "таблицы", вместо элементарного вычисления?? И причём тут "флоаты"? Зачем они для синуса?

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


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

2 часа назад, Variant99 сказал:

Вначале посмотрите, что там написано, потом будете писать очередную глупость.

"Очередную глупость" сделали учителя, когда выдали вам свидетельство о среднем образовании. Если вы даже математикой средней школы не владеете.  :unknw:

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


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

1 hour ago, amaora said:

Делали бы с помощью поворота вектора, и не нужны ни тригонометрический функции ни таблицы.

при повороте там ошибка будет копиться и за стабильностью приглядывать надо.

 

осциллятор стабильнее, да и умножение всего одно.

https://godbolt.org/z/Wd4M7e8Tb

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


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

3 часа назад, Variant99 сказал:

. . . .
Нет особого смысла высчитывать в каждом приращении угла синусоиды новое значение . . . 

Кроме случая, когда, в дополнение к собственно ШИМ-формированию синусоиды требуется управлять ее амплитудой и/или фазой.

Что не исключает использования таблицы синуса.

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


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

3 hours ago, _pv said:

при повороте там ошибка будет копиться и за стабильностью приглядывать надо.

Да, нормировать надо (можно приближенно). Но это будет удобнее для управления фазой/амплитудой.

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


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

Спасибо за помощь! У меня возникли непонятки. А именно, почему не сбрасывается UIF в обработчике прерываний?

void TIM1_UP_TIM10_IRQHandler(void)
{
	TIM1->SR &= ~TIM_SR_UIF;
}

Когда заходит в обработчик делаю по шагам, но эта строка инструкций не сбрасывает UIF. Вроде же правильно? Или еще что то надо сбрасывать?

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


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

Во-первых, можно писать просто TIM1->SR = ~TIM_SR_UIF; там для сброса бита имеет значение только 0, запись 1 на биты не влияет никак, поэтому выполнять &= не нужно. Во-вторых, добавьте после этой строчки еще несколько строчек прог.кода или просто __NOP(); Такое поведение известно с таймерами. А если в обработчике шагаете по шагам, то пока вы шагаете, интервал времени проходит и успевает выставиться новое прерывание. Чтобы этого не происходило, можно в регистре DBGMCU включить бит DBG_TIM1_STOP для остановки таймера во время пошаговой отладки.

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

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


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

50 минут назад, Variant99 сказал:

Во-первых, можно писать просто TIM1->SR = ~TIM_SR_UIF; там для сброса бита имеет значение только 0, запись 1 на биты не влияет никак, поэтому выполнять &= не нужно. Во-вторых, добавьте после этой строчки еще несколько строчек прог.кода или просто __NOP(); Такое поведение известно с таймерами. А если в обработчике шагаете по шагам, то пока вы шагаете, интервал времени проходит и успевает выставиться новое прерывание. Чтобы этого не происходило, можно в регистре DBGMCU включить бит DBG_TIM1_STOP для остановки таймера во время пошаговой отладки.

 

Variant99благодарю за ответ! Помогло.)

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


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

15 hours ago, Variant99 said:

А потом подставляйте в CCR1 значения из этого массива, по событию (прерыванию) обновления счета.

А разве это через DMA сделать нельзя? Странно, что никто этот вариант тут не озвучил.

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


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

Да без вопросов, конечно можно. Однако, если использовать таблицу только на четверть периода, то не получится - DMA считать назад не умеет, да и проводить вычитание константы тоже нет.  
Ну и автор сказал, что он хочет вычислять значение в каждом шаге, потому что значения в формуле могут меняться. В принципе, его право, пусть делает как хочет.

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


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

С прерыванием тоже не получается.

void TIM1_UP_TIM10_IRQHandler(void)
{
	static uint16_t ind;
	static uint16_t Amp = 1600, accur = 4000;

	TIM1->SR &= ~TIM_SR_UIF;

	TIM1->CCR1 = (uint16_t)(1818 + (Amp * sinf(ind * 6.283f / accur)));
	TIM1->CCR2 = (uint16_t)(1818 + (Amp * sinf((ind + accur/3.0f) * 6.283f / accur)));
	TIM1->CCR3 = (uint16_t)(1818 + (Amp * sinf((ind + accur/1.5f) * 6.283f / accur)));

	if(ind < accur) ind++;
	else ind = 0;
}

 

Тут надо бы в каждом прерывании выдавать на выход свой импульс со своим значением. У меня частота 2кГц. Выравнивание по центру. В голове крутятся варианты, не могу ухватить. 

Не, он конечно выдает каждые 500мсек. свое значение, но это получается, что просто меняется скважность. Вот как только этот сигнал развернуть?

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


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

Хотя в режиме сингл осциллографа, все встает на свои места. Так, что я вам похоже мозги пудрил). Но зато узнал от вас много полезного. Спасибо.

IMG_20230305_104124.jpg

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


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

А, ну дак время развертки на осцилле у вас короче, чем интервалы изменения ШИМа. Я уж было достал плату и анализатор, показать на деле...

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


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

Вообще не понятно, что хочет ТС.

ШИМ это широтно-импульсная модуляция. Это такая модуляция, у которой скважность меняется по закону модулирующего сигнала, а несущая частота модулируемого сигнала постоянная.

Обращаясь к ТС, так что вы на самом деле хотите реализовать и что у вас не получается ?

Может вы хотите, чтобы период меандра менялся по закону синуса ? Тогда это не ШИМ.

Или вы хотите, чтобы у вас длительность импульса была постоянная, а период следования этих импульсов менялся по закону синуса ? 

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


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

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

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

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

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

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

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

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

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

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