С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62

Генератор синусоидального сигнала на STM32

29.04.2022, 16:36. Показов 7024. Ответов 15

Студворк — интернет-сервис помощи студентам
Здравствуйте, реализую получить синус через ШИМ. Вроде все получилось, но нижняя полу волна отличается от верхней. Совсем не могу сообразить как исправить. Подскажите, пожалуйста, как сделать сдвиг по фазе между двумя синусоидами?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define CPU_Freq 168000000 
#define PWM_Freq 100000    
#define MOD_Freq 50       
 
 
#define steps  (PWM_Freq/MOD_Freq)
#define precision (CPU_Freq/PWM_Freq/8)
#define pi  3.1415926535
 
void sinus_init(void);
 
unsigned int sin_ar[steps];
 
void sinus_init(void)
{
  for(int i = 0; i<steps; i++)
        sin_ar[i] = (unsigned int)(fabs(sin((i +2) * pi / steps)) * precision);
}

Main:
C
1
2
sinus_init();
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_4, (uint32_t *)sin_ar, steps*2);
Миниатюры
Генератор синусоидального сигнала на STM32  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.04.2022, 16:36
Ответы с готовыми решениями:

Подача синусоидального сигнала
Доброго времени суток! С помощью контроллера нужно подать синусоидальный сигнал вида A*sin(w*t) на серву, чтобы она непрерывно двигалась....

генерация синусоидального сигнала через ЦАП STM32F407VG
есть код, написанный в cosox: #include &quot;stdyo.h&quot; #include &quot;stdlib.h&quot; #include &quot;stm32f4xx.h&quot; #include &quot;stm32f4xx_gpio.h&quot; ...

Регулятор частоты синусоидального сигнала на МК PIC16
Доброго времени суток, форумчане! Задача такова: требуется сделать регулятор частоты синусоидального сигнала от 50 до 400 Гц с помощью...

15
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62
29.04.2022, 16:53  [ТС]
Умножил на 2 Пи стало получше.
C
1
2
3
4
5
void sinus_init(void)
{
  for(int i = 0; i<steps; i++)
        sin_ar[i] = (unsigned int)(fabs(sin((i) * 2*pi / steps)) * precision);
}
Миниатюры
Генератор синусоидального сигнала на STM32  
0
60 / 185 / 31
Регистрация: 14.02.2013
Сообщений: 1,688
29.04.2022, 17:03
Что то не пойму как так можно из ШИМ синус построить? Интересно. И до каких частот можно псевдо синус генерировать?
0
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62
29.04.2022, 17:30  [ТС]
Цитата Сообщение от VladimirU Посмотреть сообщение
Что то не пойму как так можно из ШИМ синус построить? Интересно. И до каких частот можно псевдо синус генерировать?
Используя ФНЧ и меняя коэфф. заполнения ШИМ. Сначала рассчитывается таблица синуса, умноженная на период таймера. Потом эта таблица передается ДМА, она кидает по элементно в регистр сравнения таймера( меняется коэфф заполнения ШИМ). В итоге получается синус.
До каких частот сказать не могу. Протестировал пока только на 50 и 100 Гц.
0
60 / 185 / 31
Регистрация: 14.02.2013
Сообщений: 1,688
29.04.2022, 19:22
А вообще 100% програмно можно синус получить из модуля ШИМ?
0
 Аватар для COKPOWEHEU
4082 / 2680 / 432
Регистрация: 09.09.2017
Сообщений: 11,900
29.04.2022, 22:14
Цитата Сообщение от Briergo Посмотреть сообщение
реализую получить синус через ШИМ
Цитата Сообщение от Briergo Посмотреть сообщение
sin_ar[i] = (unsigned int)(fabs(sin((i +2) * pi / steps)) * precision);
(построил модуль от синусоиды)
Цитата Сообщение от Briergo Посмотреть сообщение
Умножил на 2 Пи стало получше.
(добавил какого-то шаманства без малейшего понимания сути)
Я так понимаю, автора не волнует ни то, что синус - штука знаковая, а ШИМ нет, ни что функцию sin контроллер будет вычислять очень долго.
Цитата Сообщение от VladimirU Посмотреть сообщение
Что то не пойму как так можно из ШИМ синус построить? Интересно. И до каких частот можно псевдо синус генерировать?
Можно, конечно. Собственно, частотники и контроллеры многофазных двигателей именно так и работают. Частота вычисляется исходя из необходимой точности (разрядности) ШИМ и его частоты.
Цитата Сообщение от Briergo Посмотреть сообщение
Сначала рассчитывается таблица синуса
Вы забыли уточнить, что рассчитывается она еще на компьютере и в целых числах в диапазоне от 0 до модуля счета таймера. А дальше уже либо частота таймера подгоняется, либо пропускаются отсчеты.
0
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62
11.05.2022, 12:56  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
(построил модуль от синусоиды)

(добавил какого-то шаманства без малейшего понимания сути)
Я так понимаю, автора не волнует ни то, что синус - штука знаковая, а ШИМ нет, ни что функцию sin контроллер будет вычислять очень долго.

Можно, конечно. Собственно, частотники и контроллеры многофазных двигателей именно так и работают. Частота вычисляется исходя из необходимой точности (разрядности) ШИМ и его частоты.

Вы забыли уточнить, что рассчитывается она еще на компьютере и в целых числах в диапазоне от 0 до модуля счета таймера. А дальше уже либо частота таймера подгоняется, либо пропускаются отсчеты.
В той реализации было множество ошибок. Я неправильно настроил DMA, вместо 2 байт записывалось 4 байта.
Поэтому здесь количество точек умножалось на 2
C
1
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_4, (uint32_t *)sin_ar, steps*2);
Исправил DMA и запуск таймера:
C
1
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_4, (uint32_t *)sin_ar, steps);
Сделал синус в пределах от 0 до 2.
C
1
2
3
4
5
6
  for(int i = 0; i<steps; i++)
  {
    sinn[i] = (unsigned int)(fabs(sin(2* i * pi / steps)+1)*100 );
    sinn_120[i] = (unsigned int)(fabs(sin(2* i * pi / steps+2*pi/3)+1)*100 );
    sinn_240[i] = (unsigned int)(fabs(sin(2* i * pi / steps+4*pi/3)+1)*100 );
  }
Тут получается 3 синусоиды сдвинутые на 120 градусов.

Мне необходимо в ходе программы при изменении значения частоты сигнала, которое приходит со SCADA. Поэтому синус рассчитывается в микроконтроллере.
0
 Аватар для COKPOWEHEU
4082 / 2680 / 432
Регистрация: 09.09.2017
Сообщений: 11,900
11.05.2022, 15:01
Цитата Сообщение от Briergo Посмотреть сообщение
sinn[i] = (unsigned int)(fabs(sin(2* i * pi / steps)+1)*100 );
Зачем вам тут модуль? Опасаетесь, что sin() вернет что-то меньшее -1?
Цитата Сообщение от Briergo Посмотреть сообщение
Мне необходимо в ходе программы при изменении значения частоты сигнала, которое приходит со SCADA. Поэтому синус рассчитывается в микроконтроллере.
Ничего не понял. При изменении частоты сигнала, которое приходит снаружи - что?
Как из этого следует необходимость вычислять синус программно?
---
Как вы думаете, как рисуются наклонные линии на мониторе? Пиксельная сетка ведь всегда одинаковая, а углы наклона линий могут быть любыми. Просто выбирается тот пиксель, который на данном шаге оказался к узлу сетки ближе. Так и у вас: есть таблица синусов для небольшого количества углов. И есть текущий угол. Вот и выбираете из таблицы значение того угла, который оказался ближе всего.
Естественно, все расчеты лучше проводить в целых числах: и углы, и синусы, и все остальное.
0
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62
11.05.2022, 15:37  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Зачем вам тут модуль? Опасаетесь, что sin() вернет что-то меньшее -1?

Ничего не понял. При изменении частоты сигнала, которое приходит снаружи - что?
Как из этого следует необходимость вычислять синус программно?
---
Как вы думаете, как рисуются наклонные линии на мониторе? Пиксельная сетка ведь всегда одинаковая, а углы наклона линий могут быть любыми. Просто выбирается тот пиксель, который на данном шаге оказался к узлу сетки ближе. Так и у вас: есть таблица синусов для небольшого количества углов. И есть текущий угол. Вот и выбираете из таблицы значение того угла, который оказался ближе всего.
Естественно, все расчеты лучше проводить в целых числах: и углы, и синусы, и все остальное.
Изначально задается какая-то частота синуса, например, 50 герц. Рассчитывается таблица синуса.
C
1
2
3
4
5
6
#define CPU_Freq 168000000 
#define PWM_Freq 20000    
#define MOD_Freq 50       
#define precision (CPU_Freq/PWM_Freq/8)
#define STEP (PWM_Freq/MOD_Freq)
#define pi  3.1415926535
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void sinus_init(void)
{
  if(counter<amplitud)
     flag_counter=PLUS;
  else if(counter>amplitud)
     flag_counter=MINUS;
  sinus_calculation();
  sinus_array();
  
}
 
void sinus_calculation(void)
{
  freq_signal_calculation();
  for(int i = 0; i<steps; i++)
  {
    sinn[i] = (unsigned int)(fabs(sin(2* i * pi / steps)+1)*100 );
    sinn_120[i] = (unsigned int)(fabs(sin(2* i * pi / steps+2*pi/3)+1)*100 );
    sinn_240[i] = (unsigned int)(fabs(sin(2* i * pi / steps+4*pi/3)+1)*100 );
  }
}
 
 
void sinus_array(void)
{
   for(int i = 0; i<steps; i++)
   {
     sin_ar[i] = (unsigned int)(sinn[i]*precision*counter/(200*100));
     sin_ar_120[i] = (unsigned int)(sinn_120[i]*precision*counter/(200*100));
     sin_ar_240[i] = (unsigned int)(sinn_240[i]*precision*counter/(200*100));
   }
}
Как видите количество точек зависит от частоты сигнала. Далее рассчитывается таблица синусов. В конечном итоге мне нужен не синус, а ШИМ, который я подам на транзистор. Вот если я захочу изменить частоту синуса, мне потребуется пересчитать таблицу синусов. Может я неправильно мыслю и это неразумно. Не судите строго я только учусь программировать.
0
 Аватар для COKPOWEHEU
4082 / 2680 / 432
Регистрация: 09.09.2017
Сообщений: 11,900
11.05.2022, 16:01
Цитата Сообщение от Briergo Посмотреть сообщение
Вот если я захочу изменить частоту синуса, мне потребуется пересчитать таблицу синусов.
Нет. Вы просто храните заранее просчитанную таблицу синусов для "всех" углов. Допустим, для 256 значений.
C
1
2
3
4
5
6
7
8
9
const int sin_table[256] = {...};
...
float time_s = 0; //текущее время
float freq_Hz = 50; //частота
float angle = time_s / freq_Hz; //угол (сколько процентов от полного цикла)
uint8_t angle_idx = (256 * angle)%256; //угол, нормированный на размер массива
int val1 = sin_table[ angle_idx ]; //1-я фаза
int val2 = sin_table[ (angle_idx + 256*1/3) % 256 ]; //2-я фаза
int val3 = sin_table[ (angle_idx + 256*2/3) % 256 ]; //3-я фаза
Если присмиотреться к коду, понятно, что при слишком низкой частоте одни и те же значения будут повторяться много раз подряд, а при слишком высокой - пропускаться.
Как вы понимаете, float я использовал только для демонстрации. На самом деле там, естественно, должны быть целые числа. Но даже так на одну точку уходит всего одно деление и пара умножений, это гораздо быстрее, чем вычисление синуса.
Выражение x % 256 тоже прекрасно оптимизируется (не удивлюсь, если даже компилятором) в наложение битовой маски. Ради этого размер массива и был выбран круглым.
1
0 / 0 / 0
Регистрация: 18.03.2020
Сообщений: 62
11.05.2022, 16:10  [ТС]
Спасибо большое, за объяснение.
0
42 / 35 / 11
Регистрация: 22.09.2017
Сообщений: 125
14.05.2022, 10:00
Цитата Сообщение от Briergo Посмотреть сообщение
Вот если я захочу изменить частоту синуса, мне потребуется пересчитать таблицу синусов.
Можно менять частоту таймера, тогда таблица синусов может быть одна.
Опять же зависит еще от ФНЧ который стоит после транзисторов.
0
Windows must die
665 / 836 / 102
Регистрация: 23.11.2021
Сообщений: 4,861
Записей в блоге: 15
14.05.2022, 18:18
Таблицу синусов нужно считать лишь от 0 до 90°, остальные значения (и косинусы) элементарно вычисляются.
И, конечно, надо стараться избегать флоатов на тех МК, где их нет. Ведь крайне редко возникает ситуация, когда флоаты остро необходимы. Уж для генерации синусоидального сигнала они не нужны точно.
0
 Аватар для COKPOWEHEU
4082 / 2680 / 432
Регистрация: 09.09.2017
Сообщений: 11,900
14.05.2022, 20:27
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Таблицу синусов нужно считать лишь от 0 до 90°, остальные значения (и косинусы) элементарно вычисляются.
Зависит от задачи. Если свободного флеша куча, можно и всю таблицу загнать.
0
Windows must die
665 / 836 / 102
Регистрация: 23.11.2021
Сообщений: 4,861
Записей в блоге: 15
14.05.2022, 20:36
COKPOWEHEU, лучше при инициализации сразу посчитать нужные значения регистров для таймеров, запихать это в оперативку и при помощи DMA гонять туда-сюда.
0
 Аватар для COKPOWEHEU
4082 / 2680 / 432
Регистрация: 09.09.2017
Сообщений: 11,900
14.05.2022, 23:03
Не понял что имеется в виду. Если частота синусоиды должна меняться, как вычислить значение регистров или таблицы заранее?
Хотя можно, конечно, завести таблицу значений в оперативке и пересчитать туда значения из таблицы синусов под нужную частоту - тогда можно и DMA. В принципе, если 8-битный ШИМ и 8 бит на угол, получается массив всего 256 элементов, не так уж много. Хотя синхронизировать частоты задаче не такая уж очевидная.
С другой стороны, даже при 8-битном ШИМ, получаем минимум 256 тактов между прерываниями, а то и больше. Скорость переключения силовых ключей ведь тоже не бесконечна.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.05.2022, 23:03
Помогаю со студенческими работами здесь

Программа, определяющая длительность периода синусоидального сигнала PIC16?
нужно написать программу, определяющая длительность периода синусоидального сигнала для микроконтроллера PIC16.

Генератор 3х фазного синусоидального сигнала
Поскажите схемку генератора 3х фазного синусоидального сигнала, чтобы можно было регулировать частоту, фазу и амплитуду каждой синусоиды....

DDS-генератор синусоидального сигнала
Приветствую всех! Долго репу чесал и понял, что без &quot;звонка другу&quot; мне не обойтись. Навыков в программировании нет вообще, разве что...

График синусоидального сигнала
Строю график синусоидального сигнала. Не показывает сам график, в чем ошибка не пойму. clc clear a=10; w=10*0.5; t=5+10;...

Цифровая обработка синусоидального сигнала
Здравствуйте, необходимо обработать синусоидальное напряжение, пускай пока что будет бытовое напряжение в 220В. На базе микроконтроллера...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru