Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.72/39: Рейтинг темы: голосов - 39, средняя оценка - 4.72
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
1

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

22.06.2016, 09:19. Просмотров 7099. Ответов 30

Здравствуйте, помогите новичку! До этого никогда не работал с МК, а тут начал с 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2016, 09:19
Ответы с готовыми решениями:

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

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

STM32F1 генерация ШИМ на TIM4 с использованием DMA
Добрый день! Пытаюсь запустить генерацию PWM с использованием DMA на таймере...

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

ШИМ для PIC16f887 на ASM
Добрый день! Такая проблема. Есть библиотека для управления ШИМ PIC16f887,...

30
Voland_
1670 / 1015 / 97
Регистрация: 04.01.2010
Сообщений: 3,395
22.06.2016, 09:42 2
че-та в коде вашем непонятно где массив, где его обработка и прерывание по переполнению таймера.
В целью "вращения" синуса вы просто должны дойти до максимального индекса массива и затем пойти обратно, до нуля. Это можно сделать организацией и выбором режима работы. Например, при режиме "ноль" (можете обозвать его каким-нить энумом) счетчик инкриминируется, при режиме "один" - декриминируется. Соответственно, вы получите "пробег", от нуля до максимума и обратно.
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 09:46 3
Vozz, код выделяй тегами
выделил листинг программы и нажал на кнопочку "С" в шапке окна ответа

теперь по теме
Цитата Сообщение от Vozz Посмотреть сообщение
В моем понимании задается некий массив со значениями синуса от 0 до 90 градусов,
вот скажи зачем создавать себе сложности? чтобы успешно их преодолевать?
что мешает заполнить таблицу(массив) значениями до 180 градусов?
Цитата Сообщение от Vozz Посмотреть сообщение
Напрямую в TIMx_CNT ? TIM_Pulse уже не имеет значения и его можно удалять?
прямо в регистр, только не в CNT,это счетчик таймера
а в CCR1(CCR2 CCR3 CCR4) зависит от того какой канал шима используешь, это регистр, так скажем заполнения шима
для твоей задачи нужно 2 таймера
первый это шим
второй задает скорость прохода по массиву, можно использовать простейшие TIM6,TIM7


но лучше обрати внимание на ЦАП, он как раз для этого и предназначен

Добавлено через 1 минуту
Цитата Сообщение от Vozz Посмотреть сообщение
Nozka
есть прекрасное английское имя PIN
2
Витальич
1272 / 1182 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
22.06.2016, 10:18 4
Цитата Сообщение от ValeryS Посмотреть сообщение
что мешает заполнить таблицу(массив) значениями до 180 градусов?
,а зачем? Достаточно до 90 градусов, с 90 до 180 тоже самое, что и от 0 до 90 только наоборот
0
Voland_
1670 / 1015 / 97
Регистрация: 04.01.2010
Сообщений: 3,395
22.06.2016, 10:29 5
Цитата Сообщение от Витальич Посмотреть сообщение
,а зачем?
Валерьич намекнул, что в этом случае вообще не надо никаких переключений. Не знаю, есть ли DMA в F100 на эти каналы, но в F103 можно такую синусоиду сделать через DMA. В этом случае - "включил и забыл" ).
1
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 10:37 6
Цитата Сообщение от Витальич Посмотреть сообщение
,а зачем?
извечный вопрос память/быстродействие, память/сложность

вот смотри массив на 180 градусов, размер 256, беру кратное двойке для быстроты расчетов
C
1
unsigned char arrSin[256];
где то
C
1
2
3
TIM2->CCR1=arrSin[i];
i++;
i%=256;
теперь на 90 градусов
C
1
unsigned char arrSin[128];
теперь считывание значений, как то так
C
1
2
3
4
5
6
7
if(i>127)
 n=-i;
else
 n=i;
i++;
i%=256;
TIM2->CCR1=arrSin[n];
ну или придется вводить еще одну переменную направление
1
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
22.06.2016, 10:44  [ТС] 7
Цитата Сообщение от ValeryS Посмотреть сообщение
но лучше обрати внимание на ЦАП, он как раз для этого и предназначен
Обратил. Пользоваться ЦАПом на порядок легче оказывается! Спасибо. Во вложении фото полученного сигнала. Возможно ли увеличить разрешение сигнала? Скажем до 256-ти точек?

Теперь хочу усложнить задачу. Нужно получить трехфазную синусоиду. Но как я понимаю ЦАП только один в STM32F100?
0
Миниатюры
Генерация ШИМ для синусоиды  STM32F100  
Витальич
1272 / 1182 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
22.06.2016, 10:46 8
в таймерах STM32 по три канала ШИМ в каждом
1
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 10:46 9
Цитата Сообщение от ValeryS Посмотреть сообщение
if(i>127)
ошибочка однако выход за пределы массива
C
1
if(i>126)
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 10:50 10
Цитата Сообщение от Витальич Посмотреть сообщение
в таймерах STM32 по три канала ШИМ в каждом
по 4 но есть и по 2 и по 1, это в крутых камнях где таймеров до проха, и некоторые таймеры не 4 канала, по крайней мере не все на ноги выведены

Добавлено через 2 минуты
Цитата Сообщение от Vozz Посмотреть сообщение
Но как я понимаю ЦАП только один в STM32F100?
Цап один, а каналов у него два, можно два сигнала вывести
Цитата Сообщение от Vozz Посмотреть сообщение
Нужно получить трехфазную синусоиду.
а вот для этого есть крутые таймеры TIM1, TIM8 специально заточены для управления трехфазным движком
0
Voland_
1670 / 1015 / 97
Регистрация: 04.01.2010
Сообщений: 3,395
22.06.2016, 10:50 11
Цитата Сообщение от ValeryS Посмотреть сообщение
i%=256;
не кузявое выражение. По крайней мере AVR очень плохо раобтает с остатком деления, разворачивает целую простыню действий. В кортексах, возможно, по-проще, но все равно лучше обойтись битовыми операциями.
0
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
22.06.2016, 10:52  [ТС] 12
Цитата Сообщение от Витальич Посмотреть сообщение
в таймерах STM32 по три канала ШИМ в каждом
Вы имеете ввиду, что возможно с помощью General-Purpose таймера и DAC сгенерить трехфазную синусоиду и загнать на полевики?
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 10:54 13
Цитата Сообщение от Voland_ Посмотреть сообщение
не кузявое выражение. По крайней мере AVR очень плохо раобтает с остатком деления,
ты не забыл что размер кратен степени двойки?
адекватный компилятор превратит это в
C
1
i&=0xFF;
но можно пойти еще дальше и объявить
C
1
unsigned char i;
тогда из-за размерности переменной, само будет делится на 256
0
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
22.06.2016, 10:55  [ТС] 14
Цитата Сообщение от ValeryS Посмотреть сообщение
Цап один, а каналов у него два, можно два сигнала вывести
То есть трехфазный синус с помощью ЦАП не получить ((( . Максимум 2 фазы
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 10:59 15

Не по теме:

Цитата Сообщение от Voland_ Посмотреть сообщение
Валерьич
:D два ника объединил:)



Добавлено через 2 минуты
Цитата Сообщение от Vozz Посмотреть сообщение
То есть трехфазный синус с помощью ЦАП не получить
нет
но кроме синусоды у ЦАПа есть другие вкусности, в частности аппаратно генерит "белый шум" и треугольники
0
Voland_
1670 / 1015 / 97
Регистрация: 04.01.2010
Сообщений: 3,395
22.06.2016, 10:59 16
Цитата Сообщение от ValeryS Посмотреть сообщение
адекватный компилятор превратит это в
есть прувы? Для AVR я такого не замечал. Мало того, не замечал и в GCC на другой платформе.
Цитата Сообщение от ValeryS Посмотреть сообщение
два ника объединил
сорри )
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 11:04 17

Не по теме:

Цитата Сообщение от Voland_ Посмотреть сообщение
сорри )
да ладно, на обиделся я:handshake:


Цитата Сообщение от Voland_ Посмотреть сообщение
есть прувы?
сейчас нет, этож надо компилятор доставать, что-то писать
вот скоро буду прогу писать на 8535, тогда и проверю, если не забуду
но у меня CVAVR, не знаю какой у него компилятор
0
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
22.06.2016, 11:06  [ТС] 18
А есть у кого нибудь примерчик генерации трехфазного синуса на STM32 на адвансед таймере? :P

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
но кроме синусоды у ЦАПа есть другие вкусности, в частности аппаратно генерит "белый шум" и треугольники
Ыыы мне как релейщику приятнее было бы проверять терминалы защит синусоидой
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,942
22.06.2016, 11:10 19
Цитата Сообщение от Vozz Посмотреть сообщение
А есть у кого нибудь примерчик генерации трехфазного синуса на STM32 на адвансед таймере?
лично у меня нет никогда этим не занимался
пошукай в интернете, я где то видел примеры
ищи по ключевым словам TIM1
0
Vozz
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 67
25.06.2016, 09:36  [ТС] 20
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
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
const int arr[]= {0,20,100,200,300,400,500,600,700,800,900,1000};
 
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= 1000;  //Значение регистра автоперезагрузки. Когда массив дойдет до 1000, счетчик должен
                    //считать в обратном направлении
  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_CMS_1 | TIM_CR1_CMS_0 | TIM_CR1_CEN; // Определили режим PWM - center alligned mode
                                                             //CMS="11"
  
  
  
   
  while (1)    //Крутимся в цикле, пока не произойдет прерывание
{ 
 
  uint8_t t1;
  for (t1=0;t1<=11;t1++) {TIM2->CCR2=arr[t1];//Загоняем массив в регистр сравнения второго канала (как раз нога PA1).
                        //считаем до 1000.
 } 
 
  if (t1>=11) {t1=0;}
  
}
 
}
Попытался загнать массив на счетчик TIM2, чтобы получить на ноге PA1 импульсы разной ширины. Код компилируется нормально, только вот на ноге PA1 одни шумы ) ) Подскажите, что делаю не так
0
25.06.2016, 09:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.06.2016, 09:36

Захват шим с rc-приемника для квадрокоптера
Хочу написать радиоперехватчик под stm32f103 для коптера. Нужно принять 4 шим...

ADC в STM32F100
настраиваю АЦП вот так, нужен только один канал: ADC_InitTypeDef...

Сломал STM32F100
Добрый день, помогите, пожалуйста, разобраться в возникшей проблеме....


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru