Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.57/104: Рейтинг темы: голосов - 104, средняя оценка - 4.57
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96

Генерация ШИМ для синусоиды STM32F100

22.06.2016, 09:19. Показов 20516. Ответов 32

Студворк — интернет-сервис помощи студентам
Здравствуйте, помогите новичку! До этого никогда не работал с МК, а тут начал с STM32F100 с наскоку.

Вот по одному из многочисленных уроков в инэте написал код и залил в МК.

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"
 
 
void Init_Timer (void) {
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  
  GPIO_InitTypeDef Nozka;
  Nozka.GPIO_Pin=GPIO_Pin_1;
  Nozka.GPIO_Mode=GPIO_Mode_AF_PP;
  Nozka.GPIO_Speed=GPIO_Speed_50MHz;
  
  GPIO_Init(GPIOA,&Nozka);
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  
  TIM_TimeBaseInitTypeDef  TIM2_scr;
  
  TIM2_scr.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM2_scr.TIM_CounterMode=TIM_CounterMode_Up;
  TIM2_scr.TIM_Prescaler=24000-1;
  TIM2_scr.TIM_Period=10000;
  
  
  
  TIM_TimeBaseInit(TIM2,&TIM2_scr);
  
  TIM_OCInitTypeDef TIM2_OC;
  
  TIM2_OC.TIM_OCMode=TIM_OCMode_PWM1;
  TIM2_OC.TIM_OCPolarity=TIM_OCPolarity_High;
  TIM2_OC.TIM_Pulse=1000;
  TIM2_OC.TIM_OutputState=TIM_OutputState_Enable;
  TIM_OC2Init(TIM2,&TIM2_OC);
 
  TIM_Cmd(TIM2,ENABLE);
  
  
  }
 
int main (void) 
 
{
  Init_Timer();
  while(1){};
  
}
Все работает на ура. Вот только решил пойти дальше, а именно получить положительную полуволну синуса и уткнулся лбом в стену.
В моем понимании задается некий массив со значениями синуса от 0 до 90 градусов, естественно пересчитанными в импульсы увеличивающейся длины. Все это загоняется на полевик IRL3705N.
В CCRx можно записать "0". Счетчик (CNT) массив кушает до 90 градусов синуса, затем значения в CNT и ARR становятся одинаковыми. Счетчик сбрасывается в "0". Как его заставить считать в обратном порядке этот же самый массив? И куда записывать массив? Напрямую в TIMx_CNT ? TIM_Pulse уже не имеет значения и его можно удалять? В TIMx_ARR пихать максимальное значение при синусе 90 градусов?
Пробовал такое сделать но не выходит.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.06.2016, 09:19
Ответы с готовыми решениями:

Объясните суть ШИМ на STM32F100
Здравствуйте. Я навичек в электронике и программировании, но как то сразу потянуло на ШИМ на STM32F100 ... Не смейтесь над моим кодом - я...

stm32 генерация синусоиды
У меня возник вопрос чтобы генерировать синусоиду в STM32.И задался вопросом а по какой формуле лучше вычислять массив. Или его не...

Генерация ШИМ
Плата STM-P103 Частота SYSCLK выставлена на 56МГц Никак не могу разобраться, в чем ошибка. На выход PC6 подключен заведомо рабочий...

32
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
25.06.2016, 10:14
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Vozz Посмотреть сообщение
while (1) * *//Крутимся в цикле, пока не произойдет прерывание
нет крутимся в бесконечном цикле
Цитата Сообщение от Vozz Посмотреть сообщение
for (t1=0;t1<=11;t1++) {TIM2->CCR2=arr[t1];
вот здесь ты постоянно загоняешь новые значения в CCR2,не дожидаясь чтобы что то отработало
таймер у тебя отрабатывает с частотой 1 кГц(тики приходят) а загоняешь значения с частотой несколько МГц
таймер просто не успевает обработать
поставь для начала задержку в вечный цикл
типа такой
C
1
for(int i<0;i<10000;i++);
а потом уже будем думать как правильно правильно использовать еще один таймер
Цитата Сообщение от Vozz Посмотреть сообщение
if (t1>=11) {t1=0;}
привязался к конкретному размеру, если добавишь или убавишь один элемент, будет нехорошо
вот так надежней
C
1
if(t1>=(sizeof(arr)/sizeof(arr[0]))) t1=0;
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
25.06.2016, 17:15  [ТС]
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
const int arr[]= {0,0,10,20,30};
 
uint8_t t1;
 
int main()
{
  //Подааем тактирование на порт А
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  //Подааем тактирование на Таймер 2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
 
  GPIO_InitTypeDef PORT;
  // Настроим ногу PA1 на выход
  PORT.GPIO_Pin = (GPIO_Pin_1);
  //Используем альтернативный режим
  PORT.GPIO_Mode = GPIO_Mode_AF_PP;
  PORT.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &PORT);
  
  //Настраиваем таймер 
  
  TIM2->PSC=24000-1; //Получили 1 кГц через предделитель. На CNT приходит 1 кГц
  TIM2->ARR= 30;  //Значение регистра автоперезагрузки. Когда массив дойдет до 1000, счетчик должен
                    //считать в обратном направлении
  TIM2->CCMR1 &=~ (TIM_CCMR1_OC2M_0 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
  TIM2->CCMR1 |= TIM_CCMR1_OC2M_0 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE; //PWM1. Когда счетчик считает 
                                       //вверх, ножка PA1 должна быть в активном состоянии
 
 
  TIM2->CCER |= (TIM_CCER_CC2E); //Разрешили ШИМ для ноги PA1 
    
  
  TIM2->CR1 &=~ (TIM_CR1_DIR);
 
  TIM2->CR1 |= TIM_CR1_CMS_1  | TIM_CR1_CEN; // Определили режим PWM - center alligned mode
                                                             //CMS="11"
  
  
  
  
   
  while (1)    //Крутимся в цикле, пока не произойдет прерывание
{ 
 
  for (t1=0;t1<=5;t1++) {TIM2->CCR2=arr[t1];//Загоняем массив в регистр сравнения второго канала (как раз нога PA1).
                        //считаем до 1000.
 } 
 
  
  if (t1>=4) {t1=0;}
  TIM2->EGR |= TIM_EGR_UG;
  
  
}
 
}
С проблемой справился. - оказалось не был выставлен бит DIR. Теперь другая проблема - в соответствии с массивом должно происходит постепенное удлинение импульсов от 0 до 30, но вначале цикла всегда почему то генерируется два импульса длиной по 30. Почему это происходит ???!!!
На комментарии не обращайте внимания )))
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
25.06.2016, 19:21
Цитата Сообщение от Vozz Посмотреть сообщение
(t1=0;t1<=5;t1++)
выход за пределы массива
при такой записи обращение идет к элементу arr[5],которого нет, а что там в памяти лежит кто знает
C
1
for(t1=0;t1<5;t1++)
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
26.06.2016, 09:57  [ТС]
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
 
 
const int arr[3]= {10,20,30}; //Для примера задали массив из трех чисел, чтобы увидеть импульсы на осциллографе
 
uint8_t t1;
 
int main()
{
  //Подааем тактирование на порт А
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  //Подааем тактирование на Таймер 2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
 
  GPIO_InitTypeDef PORT;
  // Настроим ногу PA1 на выход
  PORT.GPIO_Pin = (GPIO_Pin_1);
  //Используем альтернативный режим
  PORT.GPIO_Mode = GPIO_Mode_AF_PP;
  PORT.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &PORT);
  
  //Настраиваем таймер 
  
  TIM2->PSC=24000-1; //Получили 1 кГц через предделитель. На CNT приходит 1 кГц
  TIM2->ARR= 30;  //Значение регистра автоперезагрузки. Когда дойдет до 30. должен сброситься и цикл начнется заново
 
  TIM2->CCMR1 |= TIM_CCMR1_OC2M_0 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE; //PWM1. Когда счетчик считает 
                                       //вверх, ножка PA1 должна быть в активном состоянии
 
 
  TIM2->CCER |= (TIM_CCER_CC2E); //Разрешили ШИМ для ноги PA1 
    
  
 TIM2->CR1 &=~ (TIM_CR1_DIR); //Направление счета - вверх
 
 
 TIM2->CR1 |= TIM_CR1_CMS_0 | TIM_CR1_CEN; // Определили режим PWM - center alligned mode 2
                                                             //CMS="10"
 
 
  while (1)    //Крутимся в бесконечном цикле !!!
{ 
 
  for(int i=0;i<10000;i++)
 
    for (t1=0;t1<=3;t1++) {TIM2->CCR2=arr[t1];}//Загоняем массив в регистр сравнения второго канала (как раз нога PA1).
                        //считаем до от 0 до 30. Потом все должно начаться заново
     
 
 if(t1>=(sizeof(arr)/sizeof(arr[0]))) t1=0;
 
  }
 
}
Обещаю остановиться на этой версии ))) . Комментарии подправил, Задержку 10000 не удается ввести из за того. что нельзя выставить i<0;
Что в этом случае должна делать задержка и почему именно 10 000 ? Что то не пойму. В такое число уменьшится частота значений, подаваемых в CCR2 ?
Глянул на структурную схему таймера и понял вас. CNT тикает с частотой 1кГц а в CCR2 я пихаю все 24 МГц. Какая то каша творится - осциллограф мой сходит с ума!
Возможно ли использовать в моей задаче системный таймер SysTick для прохода по массиву? Есть ссылка на пример использования - пытался разобраться, но для меня это пока потемки )))
http://we.easyelectronics.ru/S... 030f4.html
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
26.06.2016, 10:14
Цитата Сообщение от Vozz Посмотреть сообщение
for(int i=0;i<10000;i++)
смотри внимательней у меня
Цитата Сообщение от ValeryS Посмотреть сообщение
for(int i<0;i<10000;i++);
в конце точка с запятой
то бишь пустой цикл на 10000 итераций
Цитата Сообщение от Vozz Посмотреть сообщение
Что в этом случае должна делать задержка и почему именно 10 000
почему 10000? а от балды взял
что делает задержка, на этой строчке программа крутится десять тысяч раз и в результате обновление регистра таймера происходит в 10000 раз медленней
ну и еще пожелание: почему бы не использовать для таймера те же библиотеки, как и для инициализации ножки
заголовочный файл для таймеров "stm32f10x_tim.h", разумеется в проект нужно подключить "stm32f10x_tim.c"
Цитата Сообщение от Vozz Посмотреть сообщение
for (t1=0;t1<=3;t1++)
та же ошибка что и в посте 22, выход за пределы массива
я на неё указывал
у тебя массив из трех элементов arr[0] arr[1] arr[2], а t1 принимает 4 значения 0 1 2 3
Цитата Сообщение от Vozz Посмотреть сообщение
Возможно ли использовать в моей задаче системный таймер SysTick для прохода по массиву?
возможно, и даже необходимо, но на следующем этапе
пока разберись с таймером

Добавлено через 1 минуту
Цитата Сообщение от Vozz Посмотреть сообщение
Обещаю остановиться на этой версии )))
На нерабочей
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
26.06.2016, 10:30  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
for(int i<0;i<10000;i++);
Что то EWB ругается не хочет такое записывать. А вот знак равенства воспринимает вполне адекватно !

Цитата Сообщение от ValeryS Посмотреть сообщение
На нерабочей
Пока что да
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
26.06.2016, 10:56
Цитата Сообщение от Vozz Посмотреть сообщение
Что то EWB ругается не хочет такое записывать.
вполне возможно, это значит он работает по стандарту с90, значит все переменные нужно описывать вначале блока
нужно написать так
C
1
2
3
4
5
6
7
int main()
{
int i;
...............................
.............................
for(i=0;i<10000;i++);
.................................
но лучше порыться в настройках компилятора и настроить на стандарт c99

Добавлено через 2 минуты
пардон, заметил
Цитата Сообщение от ValeryS Посмотреть сообщение
for(int i<0;i<10000;i++);
вот так нужно писать

C
1
for(int i=0;i<10000;i++);
мой косяк
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
26.06.2016, 11:23  [ТС]
Эхх что то не то происходит.
Вот показания осциллографа с i<7 - слева, i<10000 посередине и i<1 справа.
Примерно на i<10 появляется просто череда импульсов по 50 мс длительностью
Миниатюры
Генерация ШИМ для синусоиды  STM32F100   Генерация ШИМ для синусоиды  STM32F100   Генерация ШИМ для синусоиды  STM32F100  

0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
26.06.2016, 11:27  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
ну и еще пожелание: почему бы не использовать для таймера те же библиотеки, как и для инициализации ножки
Думаю разобраться во всем этом на уровне регистров а потом уже и к библиотекам перейду
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
26.06.2016, 11:49
Цитата Сообщение от Vozz Посмотреть сообщение
с i<7 - слева, i<10000 посередине и i<1 справа.
скорость подбери экспериментально, задействуй еще один вывод и навешай на него светодиод, чтобы визуально скорость смотреть
на средней фотке по моему ты просто не дожидаешься изменения скважности
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
29.11.2018, 16:03  [ТС]
Эх, давно вопрос поднял, но проблема решена (хоть и коряво). Кому еще нужен код для формирования синуса? Там же и внешние потенциометры для регулирования амплитуды и фазы (для всех 3-х фаз)
0
0 / 0 / 0
Регистрация: 25.01.2019
Сообщений: 1
25.01.2019, 16:23
Vozz, Можно мне на почту кинуть код? Буду крайне благодарен! {del}
 Комментарий модератора 
правила п 4.6
Обсуждение вопросов - только в теме на форуме. Приглашения к обсуждению еще где-либо (в том числе и с помощью системы личных сообщений) запрещены, за исключением коммерческих разделов.
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
25.01.2019, 16:38  [ТС]
Да, конечно

Добавлено через 9 минут
Как реально зальете, скажите симптомы ) Вроде припоминаю, что была разница по уровням напряжений на комплементарных выводах TIM1 ...
Внешние потенциометры для регулирования напряжения я убрал, была идея управлять через программу-хост на компе
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.01.2019, 16:38

Генерация ШИМ 30кГц на STM32
Доброго времени! Делаю часы на газоразрядных индикаторах, которые питаются от 180в. Сделал плату, которая получает на вход ШИМ 30кГц и...

Генерация синусоиды с ЦАПа через DMA (ADuCM360)
Есть код программы DAC_DMA. Надо чуть чуть переделать что бы генерировать синусоиду и через DMA(прямой доступ к памяти) выводить на ЦАП. Я...

Генерация синусоиды
Вообщем возникла проблема, помогите решить. Идея Генерировать синусоиду с частотой дискретизации 48кГц. Есть таймер (WinForm), с...

Аппаратная генерация ШИМ-сигнала таймером в режиме phase-correct для управления сервоприводом (arduino uno)
Нужно, используя таймер в режиме phase-correct, аппаратно сгенерировать сигнал для управления сервоприводом. При этом, управляя...

Генерация ШИМ в режиме Fast PWM
Доброго! Пытаюсь реализовать программу управления яркостью светодиода через UART. Вот код: .include &quot;tn2313def.inc&quot; .equ...


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru