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

stm32 генерация синусоиды

19.08.2022, 08:10. Показов 6124. Ответов 77
Метки c#, c++ (Все метки)

Студворк — интернет-сервис помощи студентам
У меня возник вопрос чтобы генерировать синусоиду в STM32.И задался вопросом а по какой формуле лучше вычислять массив. Или его не вычислять. А предоставить вычислять эту функцию контролеру?. Кто из спецов может поделится умными мыслями. Кто может подсказать. Нашёл вот такую формулу SIN A=(sin(2p*x/128+1))*127 и немного переделал SINB=(sin((2p*x/128+2p/3)+1))*127 и SINС=(sin((2p*x/128-2p/3)+1))*127.x-один элемент массива. Может неправильно .Что является периодом?.Вот что меня интересует.И как лучше управлять периодом?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.08.2022, 08:10
Ответы с готовыми решениями:

Генерация ШИМ для синусоиды STM32F100
Здравствуйте, помогите новичку! До этого никогда не работал с МК, а тут начал с STM32F100 с наскоку. Вот по одному из многочисленных...

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

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

77
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 18:08  [ТС]
Студворк — интернет-сервис помощи студентам
C++
1
Stm32f103 c8t
Вот моё тактирование вернее контроллера
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
[CODE]#include"main.h"
#include<stdio.h>
#define SYSCLOCK 72000000U
__IO uint32_t tmpreg;
__IO uint32_t SysTick_CNT = 0;
//volatile uint16_t adc_data=0;
uint16_t  txData[255];
__IO uint8_t fl_adc;
volatile uint16_t adc_data[4]={0};
 volatile   unsigned char sec,min,hour,day,date,month,year;
volatile   unsigned char menu_btn;
volatile unsigned   char  menu_lcd;
uint8_t status;
    uint8_t dt[8];
    uint16_t raw_temper;
    float temper;
    char c;
struct
{
    volatile uint16_t Ua;
    volatile  uint16_t Ub;
    volatile  uint16_t Uc;
    volatile  uint16_t Ia;
    volatile  uint16_t Ib;
    volatile  uint16_t Ic;
}par,*par_p;
char  buf0[20];
char buf1[20];
char buf2[20];
char buf3[20];
char buf4[20];
char buf5[20];
char buf6[20];
char buf7[20];
char buf8[20];
char buf9[50];
char buf10[50];
    volatile  unsigned char flag=0;
    volatile  unsigned char flag1=0;
    volatile unsigned  int   pauza=0;
    volatile unsigned  int   pauza1=0;
    volatile  unsigned char flag2=0;
            volatile  unsigned char flag3=0;
            volatile unsigned  int   pauza2=0;
            volatile unsigned  int   pauza3=0;
            volatile unsigned char a1;
                    volatile unsigned char a2;
                    volatile unsigned char b1;
                    volatile unsigned char b2;
                    volatile unsigned char c1;
                    volatile unsigned char c2;
                    volatile unsigned char d1;
                    volatile unsigned char d2;
                    volatile unsigned  int a;
                    volatile unsigned  int b;
 
                    volatile unsigned   int d;
                     unsigned  int result_a;
                     unsigned  int result_b;
                      unsigned  int result_c;
                      unsigned  int result_d;
uint8_t BAT1 [8]=
{
         0B01110,
          0B01010,
          0B11111,
          0B10001,
          0B10001,
          0B10001,
          0B10001,
          0B11111
};
uint8_t BAT2 [8]=
{
        0B01110,
          0B01010,
          0B11111,
          0B10001,
          0B10001,
          0B10001,
          0B11111,
          0B11111
};
uint8_t BAT3 [8]=
{
        0B01110,
          0B01010,
          0B11111,
          0B10001,
          0B10001,
          0B11111,
          0B11111,
          0B11111
};
uint8_t BAT4 [8]=
{
         0B01110,
          0B01010,
          0B11111,
          0B10001,
          0B11111,
          0B11111,
          0B11111,
          0B11111
};
uint8_t BAT5 [8]=
{
         0B01110,
          0B01010,
          0B11111,
          0B11111,
          0B11111,
          0B11111,
          0B11111,
          0B11111
 
};
struct
{
            volatile unsigned char a1;
            volatile unsigned char a2;
            volatile unsigned char b1;
            volatile unsigned char b2;
            volatile unsigned char c1;
            volatile unsigned char c2;
            volatile unsigned char d1;
            volatile unsigned char d2;
            unsigned short int a;
             unsigned short  int b;
             unsigned short int c;
             unsigned  short int d;
             unsigned  int result_a;
             unsigned  int result_b;
              unsigned  int result_c;
              unsigned  int result_d;
              volatile unsigned char MA[10];
}danie;
struct
{
        volatile   unsigned char menu_btn;
      volatile unsigned char  menu_lcd;
      char buf0[50];
       char buf1[50];
       char buf2[50];
       char buf3[50];
       char buf4[50];
       char buf5[50];
           char buf6[50];
           char buf7[50];
           char buf8[50];
         char buf9[50];
         char buf10[50];
         char buf11[50];
         char buf12[50];
        volatile  unsigned char flag;
        volatile  unsigned char flag1;
        volatile unsigned  int   pauza0;
        volatile unsigned  int   pauza1;
        volatile unsigned  int   pauza2;
        volatile unsigned  int   pauza3;
        volatile  unsigned char flag2;
                volatile  unsigned char flag3;
             volatile  unsigned char flag4;
             volatile  unsigned char flag5;
             volatile  unsigned char flag6;
             volatile  unsigned char flag7;
             volatile  unsigned char flag8;
 
             volatile unsigned char flag_eeprom_error;
 
             volatile unsigned char flag_eeprom;
            volatile unsigned char flag_obriv_a;
            volatile unsigned char flag_obriv_b;
            volatile unsigned char flag_obriv_c;
            volatile unsigned char bit_obriv_a;
            volatile unsigned char bit_obriv_b;
            volatile unsigned char bit_obriv_c;
             volatile unsigned  char flag_port_peregruz;
            volatile unsigned char bit_status_A;
            volatile unsigned char bit_status_B;
            volatile unsigned char bit_status_C;
            volatile unsigned char bit_status_D;
 
}nastroyki,*nastroyki_n;
struct
{
    volatile unsigned int pauza1;
} timer;
struct
{
    volatile unsigned int pauza1_A;
    volatile unsigned int pauza1_B;
    volatile unsigned int pauza1_C;
    volatile unsigned int pauza1_D;
}timers;
 
void DMA1_Channel1_IRQHandler (void)
{
 if(DMA1->ISR & DMA_ISR_TCIF1)
 {
     DMA1->IFCR|= DMA_IFCR_CTCIF1;
 
 }
 if(DMA1->ISR& DMA_ISR_TEIF1)
  {
     DMA1->IFCR|= DMA_IFCR_CTEIF1;
 
  }
}
void DMA1_Channe4_IRQHandler (void)
{
 if(DMA1->ISR& DMA_ISR_TCIF4)
 {
     DMA1->IFCR|= DMA_IFCR_CTCIF4;
 
 
 
 }
 if(DMA1->ISR& DMA_ISR_TEIF4)
  {
     DMA1->IFCR|= DMA_IFCR_CTEIF4;
  }
}
void TIM1_UP_IRQHandler(void)
{
 
 if(TIM1->SR & TIM_SR_UIF)
 {
    TIM1->SR &= ~ TIM_SR_UIF;
    {
 
    }
 
 
 }
 
}
void TIM2_IRQHandler (void)
{
    if(TIM2->SR & TIM_SR_UIF)
    {
        TIM2->SR &= ~ TIM_SR_UIF;
        if((GPIOB->IDR&GPIO_IDR_IDR5)==0)
              {
                      //nastroyki.flag1=1;
 
                        nastroyki_n->flag=1;
                        nastroyki_n->pauza1++;
                        pauza1=0;
                }
 
 
     if((nastroyki_n->flag==1)&&(GPIOB->IDR&GPIO_IDR_IDR5)&&(nastroyki_n->pauza1>10)&&(nastroyki_n->pauza1<100))
     {
       nastroyki_n->flag=0;
       // nastroyki.flag1=0;
       nastroyki_n->pauza1=0;
       //nastroyki.pauza=0;
      nastroyki_n-> menu_lcd++;
      menu_btn++;
 
     }
     if((nastroyki_n->flag==1)&&(GPIOB->IDR&GPIO_IDR_IDR5)&&(nastroyki_n->pauza1>100))
       {
                  nastroyki_n->flag=0;
                 //nastroyki.flag1=0;
                 nastroyki_n->pauza1=0;
                nastroyki_n-> menu_lcd=0;
                     menu_btn=0;
       }
 
 
    }
 
 
}
void TIM3_IRQHandler (void)
{
    if(TIM3->SR & TIM_SR_UIF)
    {
        TIM3->SR &= ~ TIM_SR_UIF;
 
 
    }
}
 
void TIM4_IRQHandler (void)
{
    if(TIM4->SR & TIM_SR_UIF)
    {
        TIM4->SR &= ~ TIM_SR_UIF;
 
    }
}
 
 
 
void SysTick_Handler(void)
{
  if(SysTick_CNT > 0)  SysTick_CNT--;
}
void init_systimer(void)
{
     MODIFY_REG(SysTick->LOAD,SysTick_LOAD_RELOAD_Msk,SYSCLOCK / 1000 - 1);
 
 
  CLEAR_BIT(SysTick->VAL, SysTick_VAL_CURRENT_Msk);
    SET_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
 
}
void delay(__IO uint32_t tck)
{
  while(tck)
  {
    tck--;
  }
}
//----------------------------------------------------------
void delay_ms(__IO uint32_t ms)
{
  MODIFY_REG(SysTick->VAL,SysTick_VAL_CURRENT_Msk,SYSCLOCK / 1000 - 1);
  SysTick_CNT = ms;
  while(SysTick_CNT) {}
}
 void DelayMicro(__IO uint32_t micros)
{
    micros *=(SystemCoreClock / 1000000) / 9;
    while (micros--);
}
 void NMI_Handler(void)
 {
   if((RCC->CIR & RCC_CIR_CSSF) != 0) // HSE fail
   {
     RCC->CIR |= RCC_CIR_CSSC; // Clear CSSF flag
 
   }
 }
 void RCC_init(void)
 {
    FLASH->ACR |=FLASH_ACR_PRFTBE ;
    FLASH->ACR|=FLASH_ACR_LATENCY_2;
 
    RCC->CR  |=RCC_CR_HSEON ;
 
    while(!(RCC->CR&RCC_CR_HSERDY ))
    {
 
    }
     RCC->CR |=RCC_CR_CSSON ;
     RCC->CFGR|=RCC_CFGR_PLLSRC;
     RCC->CFGR|=RCC_CFGR_PLLXTPRE_HSE;
 
      RCC->CFGR|=RCC_CFGR_PLLMULL9;
      RCC->CFGR|=RCC_CFGR_HPRE_DIV1; //_VAL2FLD(RCC_CFGR_HPRE,1);
           RCC->CFGR|=RCC_CFGR_PPRE1_DIV2 ;//_VAL2FLD(RCC_CFGR_PPRE1,2);
           RCC->CFGR|=RCC_CFGR_PPRE2_DIV1; //_VAL2FLD(RCC_CFGR_PPRE2,1);
           RCC->CFGR|= RCC_CFGR_ADCPRE_DIV2;
      RCC->CR|=RCC_CR_PLLON;
      while(!(RCC->CR&RCC_CR_PLLRDY))
      {
 
      }
 
        RCC->CFGR|=RCC_CFGR_SW_PLL;
        while(!(RCC->CFGR&RCC_CFGR_SWS_PLL ))
        {
 
        }
 }
 void WWDT_init(void)
 {
     RCC->APB1ENR =RCC_APB1ENR_WWDGEN;
     WWDG->CFR|=_VAL2FLD(WWDG_CFR_WDGTB,0);
 
     WWDG->CFR|=WWDG_CFR_EWI;
 
 }
 void IWDT_init(void)
 {
              RCC->CSR|= RCC_CSR_LSION;
             //while(!(RCC->CSR &RCC_CSR_LSIRDY ));
              IWDG->KR =0x5555;
              IWDG->PR|= _VAL2FLD(IWDG_PR_PR,0);
         //  IWDG->PR &=~(IWDG_PR_PR_2|IWDG_PR_PR_1|IWDG_PR_PR_0); // 4096
           IWDG->RLR =3000;//0x7FF;
 
           while (!((IWDG->SR & IWDG_SR_PVU) && (IWDG->SR & IWDG_SR_RVU))){} // wait while bist of PVU and RVU will be set.
 
           IWDG->KR =0xCCCC; // Start count down;
 
 }
 
int main(void)
{
 
    //nastroyki_n->menu_lcd=0;
   // Timer=&timer;
    par_p=&par;
  nastroyki_n=&nastroyki;
    IWDT_init();
    RCC_init();
    init_systimer();
 
    APB_init();
    GPIO_init();
    timer_1_init();
     timer_2_init();
     timer_3_init();
     timer_4_init();
    // USART1_Init();
    // USART1_DMA_Init();
     adc1_DMA1_init();
 
    I2C1_Init();
 
     LCD_ini();
    LCD_Clear();
    LCD_CreateChar(BAT1,1);
         LCD_CreateChar(BAT2,2);
         LCD_CreateChar(BAT3,3);
         LCD_CreateChar( BAT4,4);
         LCD_CreateChar(BAT5,5);
    while(1)
    {
 
        switch(nastroyki_n->menu_lcd)
        {
          case 0:
                   IWDG->KR= 0xAAAA;
                     LCD_SetPos(0,0);
                       LCD_SendChar('M');
                       LCD_SendChar('a');
                       LCD_SendChar(0xBC);
                       LCD_SendChar('a');
                       LCD_SendChar(' ');
                       LCD_PrintMyChar(1);
             break;
          case 1:
                 IWDG->KR= 0xAAAA;
                 LCD_SetPos(0,0);
                  LCD_SendChar(0xA8);
                  LCD_SendChar('a');
                  LCD_SendChar(0xBE);
                  LCD_SendChar('a');
                  LCD_SendChar(' ');
                  LCD_PrintMyChar(2);
            break;
          case 2:
                 IWDG->KR= 0xAAAA;
                 LCD_SetPos(0,0);
                 LCD_SendChar('K');
                 LCD_SendChar('p');
                 LCD_SendChar('o');
                 LCD_SendChar(0xBB);
                 LCD_SendChar(0xB8);
                 LCD_SendChar(0xBA);
                 LCD_PrintMyChar(2);
             break;
           case 3:
                  IWDG->KR= 0xAAAA;
                  LCD_SetPos(0,0);
                  LCD_SendChar(0xA4);
                  LCD_SendChar('a');
                  LCD_SendChar(0xC7);
                  LCD_SendChar(0xE5);
                  LCD_SendChar(' ');
                  LCD_PrintMyChar(5);
                //  LCD_SendChar(0x9B);
             break;
           case 4:
                 nastroyki_n-> menu_lcd=0;
             break;
        }
    }
}
[/CODE]
Это черновик не пугайтесь.
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 18:11
Цитата Сообщение от ivan rusev Посмотреть сообщение
Вот моё тактирование вернее контроллера
ну вот ваши делители по APB1 и APB2

Теперь смотрите на какой шине сидит ваш таймер
Миниатюры
stm32 генерация синусоиды  
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 18:15
Цитата Сообщение от ivan rusev Посмотреть сообщение
Вот моё тактирование вернее контроллера
какой таймер вы собираетесь использовать ?
Миниатюры
stm32 генерация синусоиды   stm32 генерация синусоиды  
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 18:17
у вас APB1 = 36 mhz
APB2 = 72 mhz

и именно эти частоты будет делить psc для счета
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 18:19  [ТС]
C
1
2
3
4
5
6
7
8
9
10
11
12
13
[CODE]void timer_2_init(void)
{
 
    RCC->APB1ENR |=RCC_APB1ENR_TIM2EN;
 
    TIM2->PSC =15; // ����������� �������� ��� ������ ����� 1000 ��� � �������
    TIM2->ARR =62499; //65535
 
    TIM2->EGR|= TIM_EGR_UG;
     TIM2->DIER |= TIM_DIER_UIE;
    TIM2->CR1|=  TIM_CR1_CEN;
     NVIC_EnableIRQ(TIM2_IRQn);
}[/CODE]
Вот таймер.Как это сделать?
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 18:28
ага, TIM 2 значит выбрали..

какая частота то нужна ?
частота будет равна: 36 000 000 (частота тактирования по APB1) \ ( psc * arr )

Добавлено через 28 секунд
psc - нужно уменьшить на единицу (там счет от нуля идет)

Добавлено через 2 минуты
то есть для частоты в 1 кгц - нужно например записать
psc= 36-1
arr=1000

Добавлено через 2 минуты
делитель psc как бы определяет частоту с которой таймер будет считать :

36 000 000 \ 36 (в psc записываем 36-1=35) = получается 1 000 000 - это частота счета таймера...
таймер будет считать от 0 до arr
как только досчитает до arr будет перезагрузка значения счетчика...
то есть с частотой 1 мгц таймер будет считать до 1000 (значение arr)..
следовательно перезагрузка счетчика таймера будет происходить: 1 000 000 \ 1000 = 1000 раз в секунду
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 18:47  [ТС]
Например если нужна частота 8 МГЦ.Ну а как сделать икремент вот этих параметров
C
1
2
TIM2->PSC =15;
    TIM2->ARR =62499;
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 18:54
Цитата Сообщение от ivan rusev Посмотреть сообщение
Например если нужна частота 8 МГЦ
гм... 8 мгц ?! выше же вы писали намного более меньшие значения частоты...

для 8 мгц - возьмите лучше TIM1 - у него делитель APB2 = 1 - это частота 72 мгц на входе

psc=0 (1-1=0)
arr=9

72\ (1*9)= 8 мгц...

p.s. надеюсь вы понимаете что прерывания с такой частотой работать не могут при такте в 72 мгц... там на вход выход больше времени будет тратиться чем период прерываний...
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 19:10  [ТС]
Ну несущая частота По avr должна быть 8Мгц.Это если мы создаём масив из 128 точек в ШИМе.А если больше точек массив то наверное частота уменьшится.Несущая 8Мгц а выход 50гц но это с учётом что шим массив вписывается в прывание по другому таймеру.А как оно с DMA будет?На выходе CCR1 ёмкость с резистором(нч филтр).
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 19:18
Цитата Сообщение от ivan rusev Посмотреть сообщение
А как оно с DMA будет?
думаю с dma проблем быть не должно...

у меня даже пример есть, но он на ассемблере и для f401... хотя там отличий от 103 помоему не будет, только на cmsis переписать...
выложить ?

Добавлено через 2 минуты
Цитата Сообщение от ivan rusev Посмотреть сообщение
а выходе CCR1 ёмкость с резистором(нч филтр).
у вас при частоте 8 мгц всего 8 итераций скважности !! (arr=9)

возможно лучше будет снизить частоту и увеличить количество итераций скважности или вообще сделать резистивный DAC на GPIO так же с передачей значения по DMA
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 19:30  [ТС]
Что говорить нужно пробовать.Искуственный DAC?А на таймере?Ну это написал в AVR.А на stm32 нужно всё по новому.
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 19:32
ну берем резистивную матрицу например от PA0 до PA7
с набором резисторов где значение следующего в 2 раза больше предыдущего...
https://radiohlam.ru/dac_r-2r/
или вот по лучше ссылка http://easyelectronics.ru/para... -r-2r.html там и пример есть и массив синуса

и потом таймером шлем запрос на dma, который из SRAM кидает значение амплитуды на GPIO_ODR...
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 19:40  [ТС]
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * atmega128 pwm.c
 *
 * Created: 20.08.2017 13:52:41
 * Author : User
 */ 
#define F_CPU 800000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <math.h>
 
 volatile long int p; 
 struct
 {
     volatile char flag1;
     volatile char flag2;
     volatile char flag3;
     volatile char flag4;
     volatile int bit1;
     
}status;
 volatile  unsigned int K=0;
 
 volatile  unsigned int i; 
 //sinusA=(sin(2px/T)+1)*127
 //sinusB=(sin(2px/T+2p/3)+1)*127
 //sinusB=(sin(2px/T-2p/3)+1)*127
 
 const int sinusA[128]={237,233,230,226,222,218,214,204,199,194,192,188,183,177,171,166,161,154,147,141,135,
     129,123,116,110,104,98,92,86,80,74,69,63,58,53,48,43,38,34,30,26,22,
     19,16,13,10,8,6,4,2,1,0,0,0,0,0,1,2,3,4,6,10,11,
     14,17,20,23,27,31,35,40,44,49,54,59,65,70,76,82,88,94,100,106,112,118,124,131,137,143,
     149,155,161,167,173,179,185,190,195,200,205,210,215,219,223,227,231,234,238,240,243,245,247,249,251,252,253,253,253,253,253,252,251,
     250,249,247,245,342,239};
 
 const int sinusB[128]={127,134,140,146,152,158,164,170,176,182,187,193,198,203,208,213,217,222,226,230,233,
236,240,242,245,247,249,251,252,253,254,254,254,254,254,253,252,251,249,247,245,242,
240,236,233,230,226,222,217,213,208,203,198,193,187,182,176,170,164,158,152,146,140,
134,127,121,115,109,103,97,91,85,79,73,68,62,57,52,47,42,38,33,29,25,22,19,15,13,10,
8,6,4,3,2,1,1,0,1,1,2,3,4,6,8,10,13,15,19,22,25,29,33,38,42,47,52,57,62,68,73,79,85,
91,97,103,109,115,121};
const int sinusC[128]={17,14,11,8,6,4,3,2,1,0,0,0,0,0,1,2,4,6,8,10,13,15,19,22,26,30,
34,38,43,48,53,63,68,74,80,86,92,98,104,110,116,122,129.135,141,147,153,159,165,171,
177,183,188,194,199,204,209,213,218,222,226,230,234,236,239,242,245,247,249,250,251,
252,253,253,253,253,253,252,251,249,247,245,243,240,238,234,231,227,223,219,215,210,
205,200,195,190,185,179,173,167,161,155,149,143,138,131,124,119,112,106,100,94,88,82,
76,70,65.59,54,49,44,40,35,31,27,23,20
};
ISR(TIMER0_COMP_vect)
{
    //  OCR3B=sinusA[K];
    TCNT0=0;
    
    K++;
    
}
ISR(TIMER1_COMPA_vect)
{
    
      OCR3A=sinusA[i];
      OCR3B=sinusB[i];
       OCR3C=sinusC[i];
     
    i++;
    if(i>127)
    {
        i=0;
    }
     
}
void init_ports()
{
 PORTB|=(0<<4)|(0<<5)|(0<<6)|(0<<7);
 DDRB|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
 DDRE|=(0<<2)|(1<<3)|(1<<4)|(1<<5);
 PORTE|=(1<<2)|(0<<3)|(0<<4)|(0<<5);
 
}
void init_timers()
{ 
    
    
 
    //TCCR3B=(1<<WGM31)|(1<<CS30);
   // TCCR1B=0x69;
  //  TCCR3B|=0x09; ;
  
  TIMSK|=(0<<OCIE2)|(0<<TOIE2)|(0<<TICIE1)|(1<<OCIE1A)|(0<<OCIE1B)|(0<<TOIE1)|(1<<OCIE0)|(0<<TOIE0);
  TIFR|=(0<<OCF2)|(0<<TOV2)|(0<<ICF1)|(0<<OCF1A)|(0<<OCF1B)|(0<<TOV1)|(1<<OCF0)|(0<<TOV0);
  TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10);
  TCCR1A|=(0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<COM1C1)|(0<<COM1C0)|(1<<WGM11)|(1<<WGM10);
  TCCR1C|=(0<<FOC1A)|(0<<FOC1B)|(0<<FOC1C);
    TCCR3A|=(1<<COM3A1)|(0<<COM3A0)|(1<<COM3B1)|(0<<COM3B0)|(1<<COM3C1)|(0<<COM3C0)|(0<<WGM31)|(1<<WGM30);
    TCCR3B|= (0<<ICNC3)|(0<<ICES3)|(0<<WGM33)|(1<<WGM32)|(0<<CS32)|(0<<CS31)|(1<<CS30);
    TCCR3C|=(0<<FOC3A)|(0<<FOC3B)|(0<<FOC3C);
    TCCR2|=(0<<FOC2)|(1<<WGM20)|(1<<COM21)|(0<<COM20)|(0<<WGM21)|(0<<CS22)|(0<<CS21)|(1<<CS20);
    TCCR0|=(0<<FOC0)|(1<<WGM00)|(1<<COM01)|(0<<COM00)|(1<<WGM01)|(0<<CS02)|(0<<CS01)|(0<<CS00);
    TCNT0=0;
    TCNT1H=0;
    TCNT1L=0;
    TCNT2=0;
    TCNT3L=0;
    TCNT3H=0;
    OCR0=0;
    OCR2=0;
    // OCR1AH=0x04;
      // OCR1AL=0xE2;
    
    
    OCR1AH=50;
    OCR1AL=50;
    OCR3A=0;
    //OCR3A=1000;
    
    OCR3B=0;
    
    OCR3C=0;
}
 
 
int main(void)
{
    init_ports();
    init_timers();
    asm("sei");
    while (1) 
    {
        
    }
          
}
Я извеняюсь вот наработки черновик по трём фазам но в AVR.
STM32 если получится то хорошо.
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 19:43
Цитата Сообщение от ivan rusev Посмотреть сообщение
по трём фазам но в AVR.
а вам именно 3 фазы нужны ? и именно синус ?
ну в принципе GPIO 16ти битный.. и если 5-ти битного разрешения хватит (32 итерации амплитуды) - то можно одним GPIO и 3 фазы сделать... все зависит от требований по точности синуса....
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 19:46  [ТС]
C
1
2
3
//sinusA=(sin(2px/128)+1)*127
 //sinusB=(sin(2px/128+2p/3)+1)*127
 //sinusB=(sin(2px/128-2p/3)+1)*127
А таймер почему не подходит?
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 19:48
Цитата Сообщение от ivan rusev Посмотреть сообщение
по трём фазам но в AVR.
опять таки я сомневаюсь что в АВР используется частота PWM в 8 мгц....

Добавлено через 1 минуту
Цитата Сообщение от ivan rusev Посмотреть сообщение
А таймер почему не подходит?
ну выше же есть расчет !
при частоте pwm = 8 мгц вы получаете счет от 0 до 8 (значение arr=9)... - это 9 итераций заполнения периода шим....
не 256 а 9 !!!
поэтому я и пишу что нужно уменьшить частоту шим или делать резистивный цап
0
 Аватар для COKPOWEHEU
4147 / 2725 / 433
Регистрация: 09.09.2017
Сообщений: 12,074
21.08.2022, 19:53
Цитата Сообщение от ivan rusev Посмотреть сообщение
Ну несущая частота По avr должна быть 8Мгц
При чем здесь avr?
Цитата Сообщение от ivan rusev Посмотреть сообщение
Я извеняюсь вот наработки черновик по трём фазам но в AVR.
Уже три фазы возникли.
Цитата Сообщение от ivan rusev Посмотреть сообщение
const int sinusA
const int sinusB
const int sinusC
Зачем вам три одинаковых таблицы, когда достаточно одной?
Цитата Сообщение от ivan rusev Посмотреть сообщение
вот наработки черновик
Лучше опишите чего вы хотите добиться. А то решать ваши фантазии мы, конечно, можем. Но делая даже самые выверенные шаги, но в неверном направлении, к цели не придешь.
Попробую поиграть в Вангу и предсказать, что речь идет о трехфазном частотнике.
0
-80 / 1 / 0
Регистрация: 15.12.2019
Сообщений: 346
21.08.2022, 21:26  [ТС]
Три фазы для асинхронного двигателя 36 вольт 200гц но с плавным пуском.То есть частота меняется плавно с течением от 0 до заданного времени минимум 10сек.максимум 60сек.И массивы не одинаковые ода опережает на 120градусов другая остаёт на 120 градусов.
0
62 / 187 / 31
Регистрация: 14.02.2013
Сообщений: 1,715
21.08.2022, 21:38
Цитата Сообщение от ivan rusev Посмотреть сообщение
Три фазы для асинхронного двигателя 36 вольт 200гц но с плавным пуском.То есть частота меняется плавно с течением от 0 до заданного времени минимум 10сек.максимум 60сек.И массивы не одинаковые ода опережает на 120градусов другая остаёт на 120 градусов.
Придётся не только частоту изменять но ещё надо промодулировать каждый полупериод синуса прямоугольными импульсами с ШИМ.
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 940
Записей в блоге: 17
21.08.2022, 21:56
Цитата Сообщение от VladimirU Посмотреть сообщение
о ещё надо промодулировать каждый полупериод синуса прямоугольными импульсами с ШИМ.
может лучше зеркалированный BAM ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.08.2022, 21:56

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

Чем связать STM32 + STM32 в одном корпусе?
Есть 2 платы: (1) - STM32 (Вывод на LCD + запись SD) и (2) - STM32F4 (обработка сигналов + коммуникация с датчиками). Чем связать данные...

Общение с барометром MS5540 на STM32 (Arduino to STM32)
Получил от китайца сей аппарат, пошел тут же гуглить что нибудь готовое, но не тут то было. Информации по нем очень мало, даже на Arduino...

график синусоиды
требуется написать график синосоиды, чтоб при запуске был график синосоиды с осями и чтоб на осе была шкала procedure...

Анимация синусоиды
Нужен совет - как анимировать синусоиду, чтобы в результате была бегущая по экрану бесконечная волна? Может какие-нибудь библиотеки...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru