Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/40: Рейтинг темы: голосов - 40, средняя оценка - 4.55
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
1

Трехфазный ШИМ

05.01.2017, 20:14. Показов 7331. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет! В общем, пытаюсь вывести на ноги контроллера Атмега2560 трехфазный ШИМ. Сам ШИМ - двухполярный. Проход задается с помощью массива.
Фаза А получилась довольно легко, но когда взялся за две другие фазы В и С, то просто встрял
Вся проблема в том, что обе полуволны фазы А попадают в границы массива (127 значений). положительную полуволну фазы В и отрицательную полуволну фазы С также удалось получить (в коде не указано). Но вот отрицательная полуволна фазы В и положительная - фазы С не вмещаются в границы массива. Уже день голову ломаю - никак не могу догадаться как решить эту проблему.

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
[CPP]/*
 * SINUSS.c
 *
 * Created: 04.12.2016 10:44:26
 *  Author: Администратор
 */ 
 
#define F_CPU  8000000
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>
#include <math.h>
 
 
 
                                                       /*Формируем массив для фазы А*/
                                                       
int sinA1[127]={0,26,38,50,62,74,86,98,110,120,132,142,152,162,172,180,190,198,206,212,
    218,226,230,236,240,244,248,250,252,254,254,254,254,254,252,252,250,248,244,240,236,
    230,226,218,212,206,198,190,180,172,162,152,142,132,120,110,98,86,74,62,50,38,
    26,0,26,38,50,62,74,86,98,110,120,132,142,152,162,172,180,190,198,206,212,
    218,226,230,236,240,244,248,250,252,254,254,254,254,254,252,252,250,248,244,240,236,
    230,226,218,212,206,198,190,180,172,162,152,142,132,120,110,98,86,74,62,50,38,
    26,0};
    
 
 
 
int i;
                                                       
 
 
             
float fa=1;   //Амплитуда фазы А
float fb=1; //Амплитуда фазы В
float fc=1; //Амплитуда фазы C
 
 
                                                              /*Функция прерывания*/
 
 
ISR (TIMER2_COMPB_vect)  {
 
 
/*Фаза А*/
 
 if (i<63) {OCR3A=0x00; OCR1A = sinA1[i];} if(i>=63) {OCR1A = 0x00; OCR3A = sinA1[i];}
 if(i>127) i=0;
  
  /*Фаза B*/
 
 
  
 i++;
    }
 
int main (void)
{
    
                                                              /*Настраиваем выходы счетчиков для ШИМ*/
    
    
    PORTG=0x00; //Установили на всех выводах порта G лог "0"
    DDRG=0xFF; // Настроили  все ноги порта G как выходы   (Это ноги таймера "0")
    
    PORTB=0x00; //Установили на всех выводах порта B лог "0"
    DDRB=0xFF; // Настроили  все ноги порта B как выходы  (Это ноги таймера "1")
    
    PORTH=0x00; //Установили на всех выводах порта H лог "0"
    DDRH=0xFF; // Настроили  все ноги порта H как выходы  (Это ноги таймера "2 и 4")
    
    PORTE=0x00; //Установили на всех выводах порта E лог "0"
    DDRE=0xFF; // Настроили  все ноги порта E как выходы  (Это ноги таймера "3")
    
    PORTL=0x00; //Установили на всех выводах порта L лог "0"
    DDRL=0xFF; // Настроили  все ноги порта L как выходы  (Это ноги таймера "5")
    
    
    
                                                 /*Настраиваем канал OC0 для прохода по массиву. Нужно задать режим без предделителя, СТС*/
                                
                                
    
    TCCR2A = (1<<WGM21) | (1<<COM2A0) | (1<<COM2A1); 
    TCCR2B = (1<<COM2B0) | (1<<COM2B1) | (1<<CS21); // Настроили T2 СТС с PSC = 8
    TCNT2 = 0x00;
    OCR2A = 0x9D; // В регистр сравнения запихали число 157. На 157--м тике таймера TCNT2 сработает прерывание по СТС
    OCR2B = 0x00;
    ASSR=0x00; // Тактируемся от внутреннего источника частоты 
    
    
    
    /*Настраиваем T1. Пускай генерирует положительные полуволны для напряжения - Фаза А полож полуволна. Нам нужен режим FAST PWM, не инверт ШИМ, без предделителя*/
    
    
    TCCR1A = (1<<WGM00) | (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0); // Режим без предделителя, FAST PWM
    TCCR1B = (1<<WGM12) | (1<<CS11); // 
    TCCR1C = 0x00;
    TCNT1=0x00; // счетный регистр = 0
    
    
    /*Настраиваем T3. Пускай генерирует отрицательные полуволны для напряжения - Фаза В отриц полуволна. Нам нужен режим FAST PWM, не инверт ШИМ, без предделителя*/
    
    TCCR3A = (1<<WGM30) | (1<<COM3A1) | (0<<COM3A0) | (1<<COM3B1) | (0<<COM3B0); // Режим без предделителя, FAST PWM
    TCCR3B = (1<<WGM32) | (1<<CS31); //
    TCCR3C = 0x00;
    TCNT3=0x00; // счетный регистр = 0
    
    
    
    OCR1AH=0x00;OCR1AL=0x00;  OCR1BH=0x00; OCR1BL=0x00; OCR1CH = 0x00; OCR1CL = 0x00;
    OCR3AH=0x00;OCR3AL=0x00;  OCR3BH=0x00; OCR3BL=0x00; OCR3CH = 0x00; OCR3CL = 0x00;
    
    
    TIMSK2 = (1<<OCIE2B); // Прерывание сработает при совпадении OC2B и счетного регистра. OCIE2B = 1
    sei(); // Разрешаем прерывание. Тут программа сигает вверх на ISR
    
    while (1)
    {
        
       // Бесконечный цикл. Если выполняется прерывание, то программа в цикл не заходит
        
    }
    
    ;}
[/CPP]
Уже как только не извращался - вводил дополнительные переменные, увеличивал размерность массива Какая то головоломка блин
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.01.2017, 20:14
Ответы с готовыми решениями:

Трёхфазный синус
Привет всем! Нужда заставила заняться программированием. Можно ли с помощью одного 16-и битного Т1...

Использование ШИМ
Приветствую всех, не смейтесь над начинающим, но у меня возникла проблема и может даже не с...

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

Частота ШИМ
Есть вот такой фрагмент кода отвечающий за ШИМ в программе управления BLDC. { TCCR0A |= (1 &lt;&lt;...

13
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
05.01.2017, 20:49 2
http://www.gaw.ru/html.cgi/txt... AVR444.htm
https://habrahabr.ru/post/128407/
1
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
05.01.2017, 21:16 3
Лучший ответ Сообщение было отмечено Vozz как решение

Решение

ну можно так
C
1
2
3
4
5
6
7
8
unsigned char table[256]={.......}
unsigned char phA=0;// фаза А 0 градусов
unsigned char phB=96;// фаза B 120 градусов
unsigned char phC=192;// фаза C 240 градусов
 
 OCR1A = table[phA++];
 OCR2A = table[phB++];
 OCR3A = table[phC++];
это не готовый код, а наброски к методу
1
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
05.01.2017, 22:21 4
ValeryS, 96 и 192 - это 135 и 270 градусей .

Хотя, я поддержу этот вариант, только если пренебречь парой градусов точности. Либо использовать медианной уточнение значений.
1
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
06.01.2017, 09:12  [ТС] 5
Спасибо! Как то отвлекся и решение пришло в голову
Опробую ваши методы тоже!

Если кому то пригодится, то вот как получилось решить проблему:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*Фаза А*/
 
 if (i<63) {OCR3A=0x00; OCR1A = sinA1[i];} if(i>=63) {OCR1A = 0x00; OCR3A = sinA1[i];} if(i>127) {OCR3A = 0x00; OCR1A = sinA1[i];} if(i>191) {OCR1A=0x00; OCR3A = sinA1[i];}
 if(i>255) i=0;
  
  /*Фаза B*/
 
  if (j>46) {OCR3B=0x00; OCR1B = sinA1[j-46];} if(j>109) {OCR1B = 0x00; OCR3B = sinA1[j-109];} if(j>172) {j=46;}
 
/*Фаза C*/
 
  if (k>17) {OCR1C=0x00; OCR3C = sinA1[k-17];} if(k>80) {OCR3C = 0x00; OCR1C = sinA1[k-80];} if(k>144) {k=17;}
 
  
 i++;j++; k++;
Думаю добавить еще один вектор. Он будет опорным для остальных трех

Добавлено через 8 часов 37 минут
Короче говоря ... ну этот массив куда подальше. Можно каким то образом рассчитать этот самый массив с помощью формулы уже в программе ?
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
06.01.2017, 10:42  [ТС] 6
C
1
2
3
4
5
6
int x; float p = 3.14; int z=254;
 
int sin_table[x] = (sin(2*p*x/z))*254;
x++;
                            
OCR1A = sin_table[x];
Вот такой код написал прямо внутри прерывания. Выдает одну ошибку: "Error 1 variable-sized object may not be initialized C:\At\3-f invertor AT2560A\3-f invertor AT2560A.c 61 1 3-f invertor AT2560A
"
судя по смыслу текста ошибки, массив с изменяемой размерностью не может быть проинициализирован ...
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
06.01.2017, 10:45 7
Цитата Сообщение от Voland_ Посмотреть сообщение
96 и 192 - это 135 и 270 градусей .
все может быть
можно таблицу составить из 360(720.....) значений, градусы будут точными, но придется индекс делать int и остаток от деления на 360 а это потеря производительности

Добавлено через 2 минуты
Цитата Сообщение от Vozz Посмотреть сообщение
, массив с изменяемой размерностью не может быть проинициализирован ...
не может быть создан в последнем стандарте Си вроде бы разрешили, но я не пользовался, за подробностями на ветку Си

Добавлено через 1 минуту
Цитата Сообщение от Vozz Посмотреть сообщение
int x; float p = 3.14; int z=254;
int sin_table[x]
А x то чему равен???
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
06.01.2017, 10:49  [ТС] 8
Задал начальное значение int x=0; Не помогло
Когда указываю в кв скобках вместо x число 256, то ошибка становится такой "invalid initializer"
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
06.01.2017, 11:02 9
инициализация массива проходит на стадии компиляции
соответственно расчетные значения применены быть не могут
только константы

Добавлено через 2 минуты
Цитата Сообщение от Vozz Посмотреть сообщение
Задал начальное значение int x=0;
а теперь смотри
C
1
2
int x=0;
int sin_table[x] = (sin(2*p*x/z))*254;
объявлен массив нулевого размера
да и что ты ему присваиваешь?
константы для инициализации должны находится в фигурных скобках
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
06.01.2017, 11:30  [ТС] 10
Я его выносил за прерывание. Перенес внутрь прерывания, прописал в фигурных скобках - ничего не изменилось!
Когда заменяю круглые скобки на фигурные вот здесь
C
1
{sin(2*p*x/z)*254}
, то код компилируется, но разумеется неправильно .

Ведь кто то рассчитывает массивы таким способом!
0
1 / 1 / 0
Регистрация: 22.06.2016
Сообщений: 96
08.01.2017, 21:41  [ТС] 11
Огромное спасибо ValeryS! Наконец то получилось собрать в протеусе схемку. Сигналы с МК усиливаются через IR2130 а затем уже на IGBT
IRG4BC40W. Для прохода по массиву использовал счетчик T2 а для записи в OCRnA, OCRnB, OCRnC - вот такую вот конструкцию:

Код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ISR (TIMER2_COMPA_vect)  {
 
 
/*Фаза А*/
 
OCR1A = sin_ABC[phA1++]; OCR3A = sin_ABC[phA2++];
  
  /*Фаза B*/
 
OCR1B = sin_ABC[phB1++];OCR3B = sin_ABC[phB2++];
 
/*Фаза C*/
 
OCR1C = sin_ABC[phC1++];OCR3C = sin_ABC[phC2++];
 
   }
Массив вне основного тела программы

С выхода транзисторов отличный синус, но практика еще покажет .
0
0 / 0 / 0
Регистрация: 27.05.2018
Сообщений: 2
27.05.2018, 22:17 12
В какой программе компилировали код с, хочу тоже запустить трехфазный двигатель
0
1176 / 653 / 111
Регистрация: 15.05.2012
Сообщений: 4,016
28.05.2018, 14:32 13
C
1
2
3
4
5
6
/*
 * SINUSS.c
 *
 * Created: 04.12.2016 10:44:26
 *  Author: Администратор
 */
Стало быть СCS протеуса.

Добавлено через 23 минуты
Обманулся - Atmel Studio.
0
0 / 0 / 0
Регистрация: 27.05.2018
Сообщений: 2
28.05.2018, 20:24 14
Не хочет компилироваться в атмел студио

Добавлено через 12 секунд
Выдает ошибку
0
28.05.2018, 20:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2018, 20:24
Помогаю со студенческими работами здесь

ШИМ на Atmega 16
Хочу запустить шим на таймере 2, но что-то не получается... Компилятор Avr studyo 4 Вот код:...

Atmega8 и ШИМ
Вобщем такой вопрос. Есть Atmega8. Хочу сделать програмный ШИМ на всех ножках кроме PD2, PD3, PB6...

ШИМ на ATTiny261А
Помогите, пожалуйста, запустить ШИМ на ATTiny261A. Мне нужен обычный Fast-PWM на выходах ОС1А и...

ШИМ на Atmega8535
Доброго времени суток. MK Atmega8535. Необходимо калибровать яркость светодиода, подключенного к...

Atmega8 - ШИМ
Здраствуйте! Использую МК Atmega8. Частота 1МГц. 1) как генерировать ШИМ на таймере 0...

L293 и ШИМ
Здравствуйте форумчяне. Столкнулся с такой проблемой. l293 включена в мост как на рисунке....

Шим на Atmega8.
Суть в следующем! в архиве схема и прошивка , где качал не помню не могу найти источник , но при...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru