Страница 1 из 3

ШИМ atmega8

Добавлено: Ср авг 02, 2017 06:08:19
7seg
Столкнулся с проблемой выбора типа ШИМ, программный или аппаратный.
Будет использоваться 3 канала шим сдвинутых на 120 градусов по фазе.Каждый канал будет из себя представлять генератор импульсного сигнала с регулируемой частотой от 5-100 герц промодулированный частотой 2 килогерца.

Re: ШИМ atmega8

Добавлено: Ср авг 02, 2017 07:04:17
akl
Думаю, для mega8 можно скомбинировать. На таймере 2 генерировать 250мкс, что составляет полупериод частоты 2кГц, а в прерывании по сравнению программно формировать заданные параметры.

Re: ШИМ atmega8

Добавлено: Ср авг 02, 2017 18:03:58
roman.com
akl писал(а):в прерывании по сравнению программно формировать заданные параметры.
Нечто подобное пробовали.. идеальной точности не будет. Наблюдается джиттер до 1 микросекунды... Помоему лучше прикрутить типа внешний коммутатор..

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 09:13:27
7seg
Чтоб не создавать новую тему решил спросить здесь, как сделать промодулированный меандр?
Пока что настроил три аппаратных шим и решил по простецкий через сделать три промодулированных шим через задержку и кейсы.
но столкнулся с проблемой что PB1 PB2 PB3 не реагируют на изменения которые я хочу внести из while();

Код: Выделить всё

#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>


int main(void)
{
	PORTB=0x00;
	DDRB=0x0E;        // 0b00001110
	//Для таймера TC1 нам потребуются два регистра: TCCR1A и TCCR1B. 
	TCCR1A=0xA1;
	TCCR1B=0b0001010;
	//Для таймера TC2 мы будем использовать регистр TCCR2
	TCCR2=0b1101010;
	// Скважность  задавать регистрами OCR1A,OCR1B, OCR2:
	OCR1A=128;    
	OCR1B=128;   
	OCR2=128;     
	int  ni=0;
	while(1)
	{
		_delay_ms(10);
		ni++;
		switch (ni)
		{
			case 1: 
			PORTB &= ~(1 << PB1);
			PORTB |= (1 <<  PB2);
			PORTB |= (1 <<  PB3);
			break;
			case 2:
			PORTB &= ~(1 <<  PB2);
			PORTB |= (1 <<PB1);
			PORTB |= (1 <<  PB3);
			break;
			case 3:
			PORTB &= ~(1 <<  PB3);
			PORTB |= (1 << PB1);
			PORTB |= (1 <<  PB2);
			break;
		}
		if (ni==4){ni=0;}
	}
	return 0;
}
 
Как я понял надо либо отключать аппаратный шим на время когда PB=0 ? или все таки это не правильный подход к решению моей задачи ?
Добавлено after 32 minutes 33 seconds:
Примерно получить хочу следующие:
Изображение

Добавлено after 3 hours 6 minutes 55 seconds:
Вроде бы получилось, но не знаю на сколько это правильно )

Код: Выделить всё

#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>



int main(void)
{
	PORTB=0x00;
	DDRB=0x0E;        // 0b00001110
	//Для таймера TC1 нам потребуются два регистра: TCCR1A и TCCR1B. 
	//TCCR1A=0xA1;
	TCCR1B=0b0001010;
	//Для таймера TC2 мы будем использовать регистр TCCR2
	//TCCR2=0b1101010;
	// Скважность  задавать регистрами OCR1A,OCR1B, OCR2:
	OCR1A=128;    
	OCR1B=128;   
	OCR2=128;     
	int  ni=0;
	while(1)
	{
		_delay_ms(20);
		ni++;
		switch (ni)
		{
			case 1: 
			//Отключить шим на PB1 OC1A
			TCCR1A = 0b00100001;
			TCCR2=0b1101010;
			PORTB &= ~(1 << PB1);
			break;
			case 2:
			//Отключить шим на PB2 OC1B
			TCCR2=0b1101010;
			TCCR1A = 0b10000001;
			PORTB &= ~(1 <<  PB2);
			break;
			case 3:
			TCCR1A=0xA1;
			TCCR1B=0b0001010;
			TCCR2=0x00;
			PORTB &= ~(1 <<  PB3);
			break;
		}
		if (ni==3){ni=0;}
	}
	return 0;
}

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 09:54:50
ARV
В зависимости от режима ШИМ запись в OCRx нуля (или значения TOP) на соответствующем выходе формируется 0 (или 1). По-моему, так проще "модулировать"...

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 10:27:37
7seg
ARV, спасибо за идею попробую сегодня ее реализовать.
Пока что получается такая картина.
С МК выходит 3 фазы на PC:
Изображение
Из PC ( я их использую сразу из за двух причин гальваническая развязка+ получения сигнала в противофазе) Сигнал пойдет на IR2130.
Изображение
Правильно ли я сформировал сигнал ?
HIN1,2,3 Логические входы для задания в противофазе выходов драйверов верхнего уровня (HO1,2,3)
LIN1,2,3 Логические входы для задания в противофазе выходов драйверов нижнего уровня (LO1,2,3)

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 10:44:49
ARV
Если вы собрались делать 3-фазный инвертор, то вместо ваших опторазвязок надо ставить драйверы с генерацией "мертвого времени". без этого вы будете жечь ваши транзисторы в трехфазном мосту.

кроме того, не ясен смысл прямоугольной модуляции, обычно все стремятся к синусу...

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 11:14:47
7seg
[uquote="ARV",url="/forum/viewtopic.php?p=3155835#p3155835"]надо ставить драйверы с генерацией "мертвого времени".[/uquote]
А можно пример такого драйвера ?
На вход IR2130 можно подавать синус ?
Пока что спаяна только низковольтная часть и пишется программа.
Образно схема выглядит вот так:
СпойлерИзображение
Добавлено after 2 minutes 3 seconds:
Выход только перекинул с МК на ПОРТ Б пока что.

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 11:45:33
ARV
7seg писал(а):На вход IR2130 можно подавать синус
можно, там встроен генератор мертвого времени. для этого драйвера не нужна опторазвязка. но пока что у вас синусом и не пахнет, а в режиме прерывистого сигнала этот драйвер может и не работать, т.к. для зарядки бутстрепного конденсатора обязательно необходимо периодическое отпирание "нижних" транзисторов моста.

поищите в сети схемы инверторов, они есть, даже на atmega8, если не ошибаюсь... я встречал на at90s8515, кажется... не важно - схема-то силовой части неизменна.

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 11:59:20
7seg
Вот не много не понятно что именно должно быть на входах
ИЗ описания IR2130:
HIN1,2,3 Логические входы для задания в противофазе выходов драйверов верхнего уровня (HO1,2,3)
LIN1,2,3 Логические входы для задания в противофазе выходов драйверов нижнего уровня (LO1,2,3)

Если вход логический значит это 0 или 5. или не обязательно ?

И правильно ли мое утверждение как я понял что "Логические входы для задания в противофазе выходов драйверов верхнего уровня"
"Это сигнал из МК а LIN1,2,3 это его инверсия ?

Re: ШИМ atmega8

Добавлено: Чт авг 03, 2017 12:40:53
ARV
7seg писал(а):Если вход логический значит это 0 или 5. или не обязательно ?
логический вход - это 0 или VCC. если VCC=5, то и лог.1 будет 5В. Смотрите даташит - VCC может быть до 25 вольт.

HIN управляют верхними ключами, когда HIN=0, то на выходе HO будет высокий уровень, если нет запретов.
LIN управляет нижними ключами аналогично.

активный уровень для обоих входов - низкий. для простоты надо бы вам поискать драйвер с противофазными входами, чтобы просто соединить их вместе и подавать один и тот же сигнал... посмотрите в сторону IR21362 (правда, мертвое время у нее поменьше)

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 06:40:00
7seg
К сожалению с драйверами проблема пока взял 1 на заказ, ждать еще 1 уж очень долго от 2 до 3 недель.
Как запасной вариант еще идет Модуль IRAM. но это еще неделя полторы.(

Добавлено after 2 hours 42 minutes 2 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3155835#p3155835"]не ясен смысл прямоугольной модуляции, обычно все стремятся к синусу...[/uquote]
Конечно извиняюсь за тупость,
Спойлерпросто недавно начал заниматься проектировкой схем, знания которые есть ограничивается поделками для дома из журнала радио лохматых 80ых годов , а программирование несколькими проектами по геймдеву на с++ ) Сейчас конечно уже после нескольких сделанных проектов начинаю въезжать в тему.)
Из МК можно получить только импульсный сигнал , Как я понял. Если получать из него синусоиду то как я понимаю нужна РЦ цепочка. Просмотрев пару схем на этом форуме и прочитав несколько статей увидел следующей принцип управление АД:
МК формирует 6 ШИМ. 3 сдвинутых на 120 градусов с промодулированной включенной частью частотой 1-4 kHZ +3 Инверсных, Немного поразмышляв пришел к решению(возможно и неверному) зачем грузить МК еще на 3 инверсных ШИМ,когда можно взять 3. ШИМ и сделать инверсию через связку Оптронов(Которая представляет из себя эмиттерный повторитель + инвертор) dt не учел.
Дальше пустить на вход LIN,1,2,3 проинвертированный сигнал , а на HIN1,2,3 Прямой ( т.к по ДШ входы у IR2130 инверсные).
Т.к я понимаю что для АД предпочтительней синусоида по питанию, и не увидев негде в просмотренных мною схемах ПЧ ни каких фильтров решил что синус будет уже формироваться на обмотках АД и чем выше частота модуляции тем ему проще.

Хотелось бы у более опытных людей узнать, насколько моя теория управления АД является истинной ? А если все что я приневал за истину является бредом помочь советом в чем моя ошибка. Думаю ваши ответы помогут не только мне но и остальным новичкам которые обратятся с похожими вопросами к "Великому всезнающему GOOGLE".

Добавлено after 1 hour 1 minute 15 seconds:
Обнаружил еще один пробел в знаниях управления АД .Принцип постоянства отношения напряжение/частота (правило Костенко).
Прочитал,осталось теперь все переварить)

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 06:58:34
ARV
МК формирует 3 сдвинутых по фазе промодулированых ШИМ сигнала. Несущая частота ШИМ выбирается побольше, т.к. чем выше частота, тем проще она фильтруется. но при этом чем выше частота, тем больше динамические потери в транзисторах моста. Поэтому несущую частоту ШИМ выбираеют исходя из мощности привода: для мощных она может быть и менее 1 кГц, для маломощных может достигать 100 кГц. Обычно для маломощных применяют примерно на уровне 18-25 кГц - по причине того, что ухо человека этого уже не слышит, а потери еще терпимые.

ШИМ-сигнал превращается в "синусоиду" после прохождения через интегрирующую цепь, которой обычно является обмотка двигателя: ток в индуктивности будет сглажен. Иногда применяют отдельные синус-фильтры, но это уже скорее редкость.

ШИМ должен быть промодулирован синусоидальным сигналом, чтобы потом получилась синусоида тока в обмотках движка. при этом 0 напряжения на обмотке соответствует не 0 напряжения на выходе ШИМ-сигнала, а ШИМ с заполнением 50%: в таком сигнале нижнее плечо инвертора окрыто ровно столько же, сколько и верхнее, и после интегрирования тока получается 0 действующего тока. Напряжение при этом совсем не похоже на ноль...
Изображение
вот на этой картинке можете посмотреть: в моменты, где синусоида переходит через 0 на ШИМ-сигнале как раз меандр.

В случае с ШИМ из AVR получится что-то типа такого: в OCRх записано число 127 (для 8-битного ШИМ) и все три фазы генерят меандр - это соответствует 0 на выходе инвертора. потом с нужной частотой значения в регистрах OCRx меняются значениями, отличными от 127 (обычно по таблице синуса), и это приводит к тому, что на выходах получаются модулированные синусом ШИМ-последовательности.

как-то так.

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 07:13:18
7seg
Благодарю за развернутый ответ, похоже вы спасли комплект силовой части от умертвления ))

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 07:20:55
ARV
В своё время я увлекался этой темой, и даже сделал нечто работоспособное на MCS51 - можете полюбоваться http://arv.radioliga.com/content/view/64/44/ :)
Дела давно минувших дней...

это я к тому, что описанный мною вариант - наиболее применяемый, но далеко не единственный. есть и другие варианты, вроде моего по ссылке, и из вашего подхода мог бы выйти результат...

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 07:43:34
7seg
Интересная картинка чем то похожа на тот способ который я реализовал, если не ошибаюсь.
Изображение

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 07:56:59
ARV
7seg писал(а):Интересная картинка
что-то туманно-похожее есть :) но у меня совсем не ШИМ, а нечто более несуразное :)

Re: ШИМ atmega8

Добавлено: Пт авг 04, 2017 08:30:22
7seg
Случайно попались сорцы, по уверждению автора © подобие контроллера АС мотора - mc3phac подобие MC3PHAC.
Может кому пригодиться.
Код:
Спойлер

Код: Выделить всё

/*****************************************************

CodeWizardAVR V1.25.9 Professional  - скачать на www.avr123.nm.ru

Project : m48_ac_chip
Version : 001
Date    : 21.01.2009
Author  : AVR123                        
Company : avr123.nm.ru                         

Попытка сделать подобие контроллера АС мотора - mc3phac   www.freescale.com
на ATmega48 но с обратной связью по параметрам мотора и силовой части.

Пока сделано:

Программа выдает 3-х фазную синусоиду с подмесом четвери 3-й гармоники.

Главное - амплитуда синусоиды регулируется множителем amp_sin от 0 до 255
Частота синуса тоже регулируется.

Просто запустите проект PROTEUS и посмотрите.  

========

Chip type           : ATmega48
Clock frequency     : 8 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 128    
  
USART   8N1 38400    8 Data, 1 Stop, No Parity   Включен передатчик

========

Выходы ШИМ для драйверов верхних ключей 3-х фазного моста

Фаза "А"     PD6   регистр OCR0A
Фаза "B"     PD5   регистр OCR0B
Фаза "C"     PB3   регистр OCR2A   

   ВНИМАНИЕ !   По симуляции в PROTEUS получается такой порядок фаз
                "A" - PD6     "B" - PB3      "C" - PD5

ШИМ для нижних ключей создабтся из этих сигналов с 
помощью инверирования 74hc14 (отеч. 1553ТЛ2)

Величина ШИМ в процентах:    100 * (число в регистре)/255 

Используется таблица 0.5 периода синуса из 128 значений с добавкой 
четверти 3-й гармоники. Шаг между фазами - 43

===============

Тамер1 в режиме 4 - считает от нуля и при досчете до 2 байтного числа 
в OCR1A возникает прерывание interrupt [TIM1_COMPA]  и счет начинается 
снова с нуля.

В этом прерывании: 

1) сигнальный вывод PB0 меняет свое значение. 

2) Происходит продвижение по таблице синуса изменением индекса
index_sin на количеств шагов из переменной inc_ind  и обновляются
значения ШИМ для всех 3-х фаз.

Т.е. от частоты этих прерываний завист скорость движения по таблице 
синуса и значит частота генерируемого 3-х фазного напряжения.
  
===============    
ПЕРЕСЧИТАТЬ !!!

Пусть максимальная частота генарции будет 300 Гц - значит в 1 сек нужно 
300*256=76800 шагов по синусу. Если шагать по 8 то будет 9600 шагов в сек.

Включим Таймер1 с делителем 8, тогда при при OCR1A = 103; прерыввание
будет возникать 9615,385 раз в секунду.  


Минимальная частота синуса. При  OCR1AH = 0xFF;  OCR1AL = 0xFE; период
прерываний 79132 мкС  это 12,64 шага по таблице в секунду, делим на 256
получается - 0,049 Гц.

===============

Сделать проверку шагания вперед и назад.

========
 

Краткий курс - самоучитель микроконтроллеры AVR ATmega 
     ATtiny для начинающих - www.AVR123.nm.ru

Самые первые шаги. 
http://www.roboforum.ru/viewtopic.php?f=2&t=1070&p=11560#p11560

"Си для МК" кратко описан всего на двух страницах курса
avr123.nm.ru/05.htm  
avr123.nm.ru/05a.htm       

писать и компилировать программу советую в компиляторе 
CVAVR  - как с ним работать и где взять написано на стр.
avr123.nm.ru на сером фоне  и в задачах  avr123.nm.ru/06.htm 

CVAVR  - тоже имеет отличные примеры и хелп.      

; ************************************************************


Отлаживать программу удобно в маленьком симуляторе VMLAB 
(взять бесплатно на www.amctools.com) рассказано там:
avr123.nm.ru/z2.htm
avr123.nm.ru/z3.htm
avr123.nm.ru/z9.htm

дополнительная информация есть в хелпе и в примерах VMLAB

; ************************************************************

Еще посмотрите "супер-пупер" способ отладки устройств 
на МК - он описан там:  avr123.nm.ru/z4.htm

///////////////////////////////////////////////////////////////

// Мощнейший симулятор электроники и МК - PROTEUS  !!! 
// Советую скачать  - http://www.oProteus.narod.ru
     
///////////////////////////////////////////////////////////////

  CVAVR 1.25.9    есть на  avr123.nm.ru    
 
  PROTEUS 7.4 sp4 PRO с лекарством скачать   
  http://www.roboforum.ru/viewtopic.php?f=2&t=2398 
  
*****************************************************/

#define ADC_VREF_TYPE 0x00 // теперь препроцессор везде в тексте программы заменит "ADC_VREF_TYPE" на "0x00"  

// Declare your global variables here
volatile char ctr; 

// volatile unsigned char temp = 0; // служебная переменная


volatile unsigned int index_sin = 0; // Индекс в таблице синуса 

volatile unsigned char index_a_sin = 0; // Индекс фазы A в таблице синуса 
volatile unsigned char index_b_sin = 85; // Индекс фазы B в таблице синуса 
volatile unsigned char index_c_sin = 43; // Индекс фазы C в таблице синуса

volatile unsigned int temp_16; // служебная переменная 2 байта
volatile unsigned char temp_8; // служебная переменная 1 байт

volatile unsigned char temp_a; // временное хранение значения фазы A
volatile unsigned char temp_b; // временное хранение значения фазы B
volatile unsigned char temp_c; // временное хранение значения фазы C

volatile unsigned char pol_a = 1; // полярность фазы A  "1" - больше 126
volatile unsigned char pol_b = 1; // полярность фазы B  "0" - меньше 128 
volatile unsigned char pol_c = 0; // полярность фазы C 

volatile unsigned char index_bc_calc = 1; // "1" - вычислять индексы для фаз В и С 

volatile unsigned char  inc_ind = 1;  // Шаг индекса в таблице синуса 

volatile unsigned int freq_int = 103; // задает период прерываний, не менее 103.

volatile unsigned char amp_sin = 0; // амплитуда синуса. 255 это максимум.    

// volatile unsigned char error_table = 0; // признак ошибки индекса таблицы

// #define OCR1A (*(unsigned int *) 0x88) // 16 bit access
// старший байт не записывается в  OCR1A

unsigned int u=0; //Глобальная переменная с содержимым преобразования АЦП

#include <mega48.h>
#include <delay.h>
#include <stdio.h> 
  
 
#include <sin256.h>
/*    flash unsigned char sinus[256]={ };

Табличное представоение половины периода 3-х фазной синусоиды 
с добавкой одной четвертой части 3-й гармоники

Значения ШИМ от 0 до 255
 
*/
 


// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Сюда попадаем при  TCNT1=OCR1A  

PORTB^=1; // тестовый сигнал на PB0  //debug

// здесь нужно записать в регистры ШИМ следующие значения формирования синуса.  

ADCSRB = index_a_sin; //debug
        
//======== 
//  Вычисления для Фазы     А         
//index_a_sin += inc_ind;

//======== 
// Перекл. полярн. Фазы А и вычисление индекса
if (index_a_sin > 127){ 
           index_a_sin -= 128;
     
     index_bc_calc = 0; // не вычислять индексы для фаз В и С    
     
  if (pol_a){ // Переключение полярности Фаз
                   pol_a = 0; pol_b = 0; pol_c = 1;
     index_b_sin = index_a_sin + 85;
     index_c_sin = index_a_sin + 43; 
            }
    else{
                   pol_a = 1; pol_b = 1; pol_c = 0;
     index_b_sin = index_a_sin + 85;
     index_c_sin = index_a_sin + 43;
        } 
                      }        
                      

//======== 
// Проверка индексов для Фаз  B и C и полярности
if (index_bc_calc) {  

//========
//   Вычисл. индекса Фазы B и полярности
if (index_b_sin > 127){ 
           index_b_sin -= 128;  
     
  if (pol_b){ // Переключение полярности Фазы B
               pol_b = 0; 
            }
    else{
                pol_b = 1; 
        } 
                      }


//========
//   Вычисл. индекса Фазы С и полярности
if (index_c_sin > 127){ 
           index_c_sin -= 128;  
     
  if (pol_c){ // Переключение полярности Фазы B
               pol_c = 0; 
            }
    else{
                pol_c = 1; 
        } 
                      }
}
//========

//   ТУТ индексы всех фах известны и полярности тоже.
                   
//========
// Вычисление амплитуды Фазы А 
ADCSRB = sinus[index_a_sin];  //debug

// Умножаем значение из таблицы на коэф. amp_sin и берем старший байт.
temp_8 = (((unsigned int)amp_sin * (unsigned int)sinus[index_a_sin])) >> 8;
// это вычисление занимает 32 такта AVR

     ADCSRB = temp_8; //debug
     
if (pol_a){ // если положительная полуволна Фазы 
              temp_a = temp_8 + 127; // PWM PD6 Faza_A
          }
    else{   // если отрицательная полуволна Фазы 
              temp_a = 127 - temp_8;
        } 
             
//========
// Вычисление амплитуды Фазы B 
ADCSRB = sinus[index_b_sin];  //debug

// Умножаем значение из таблицы на коэф. amp_sin и берем старший байт.
temp_8 = (((unsigned int)amp_sin * (unsigned int)sinus[index_b_sin])) >> 8;
// это вычисление занимает 32 такта AVR

     ADCSRB = temp_8; //debug
     
if (pol_b){ // если положительная полуволна Фазы 
              temp_b = temp_8 + 127; // PWM PD6 Faza_A
          }
    else{   // если отрицательная полуволна Фазы 
              temp_b = 127 - temp_8;
        } 
            
//====================
// Вычисление амплитуды Фазы C 
ADCSRB = sinus[index_c_sin];  //debug

// Умножаем значение из таблицы на коэф. amp_sin и берем старший байт.
temp_8 = (((unsigned int)amp_sin * (unsigned int)sinus[index_c_sin])) >> 8;
// это вычисление занимает 32 такта AVR

     ADCSRB = temp_8; //debug
     
if (pol_c){ // если положительная полуволна Фазы 
              temp_c = temp_8 + 127; // PWM PD6 Faza_A
          }
    else{   // если отрицательная полуволна Фазы 
              temp_c = 127 - temp_8;
        } 
                                 
//=====================
//    Запись значений ШИМ в регистры ШИМ 
OCR0A = temp_a;  // PWM PD6 Faza_A   
OCR0B = temp_b;  // PWM PD5 Faza_B  
OCR2A = temp_c;  // PWM PB3 Faza_C 

//=====================
//            Инкремент индексов 
index_a_sin += inc_ind;  // следующий индекс PWM PD6 Faza_A   
index_b_sin += inc_ind;  // следующий индекс PWM PD5 Faza_B  
index_c_sin += inc_ind;  // следующий индекс PWM PB3 Faza_C

index_bc_calc = 1; // ычислять индексы для фаз В и С

temp_8 = 0; //debug

}
//=====================         
                                
/* Мы будем прерываться по завершении АЦ преобразования и выводить результат.
 Нужно написать функцию обработчик этого 
 прерывания - пишем: */

interrupt [ADC_INT] void adc_isr(void) {
u=ADCW;          // Получим значение АЦП
ADCSRA|=0x40;    // Запустить повторное измерение
}    
           
           
         
// ========
// Эти прерывания пока не используются

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here 
//ctr++;

}

// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
// Place your code here
//ctr++;

}

// Timer 0 output compare B interrupt service routine
interrupt [TIM0_COMPB] void timer0_compb_isr(void)
{
// Place your code here
//ctr++;

}

// Эти прерывания пока не используются 
// ========




void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize- 
CLKPR=0x80;  
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
          
DDRB.0 = 1; // выход диагностический
        
// ======= 
// Настройка таймер_0  - 2 сигнала ШИМ для фазы "А" и "В"
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000 kHz  Кварц
// Mode: Phase correct PWM top=FFh   ШИМ 15 686 Hz
// OC0A output: Non-Inverted PWM
// OC0B output: Non-Inverted PWM
TCCR0A=0xA1;
TCCR0B=0x01;
TCNT0=0x00;

// Настройка таймер_2  - сигнал ШИМ для фазы "С"
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 8000 kHz  Кварц
// Mode: Phase correct PWM top=FFh   ШИМ 15 686 Hz
// OC2A output: Non-Inverted PWM
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x81;
TCCR2B=0x01;
TCNT2=0x00;

//  Установка величны ШИМ в 50 % для всех фаз 

OCR0A=127; // PWM PD6 Faza_A   100 * OCR0A/255  (в %)
OCR0B=127; // PWM PD5 Faza_B   100 * OCR0B/255  (в %)
OCR2A=127; // PWM PB3 Faza_C   100 * OCR2A/255  (в %)

// Включить выходы ШИМ
DDRD|=(1<<5)|(1<<6); // PD5 PD6  выходы ШИМ Таймер0
DDRB|=(1<<3);        // PB3      выход  ШИМ Таймер2

// все PWM сигналы в фазе и центры их совпадают
//           по осциллографу PROTEUS  
    
    
           
// =======     
//TIMER1 initialize - prescale:8
// WGM: 4) CTC, TOP=OCRnA
// desired value: 9600Hz
// actual value: 9615,385Hz  при OCR1A = 103;

 TCCR1B = 0x00; //stop 
 
 //TCNT1H = 0xFF; //setup
 //TCNT1L = 0x99;
 
 // эта запись занимает 8 тактов процесора по PROTEUS
 OCR1AH = (unsigned char)(freq_int >> 8);
 OCR1AL = (unsigned char)freq_int;
 
 //OCR1BH = 0x00;
 //OCR1BL = 0x67;
 
 //ICR1H  = 0x00;
 //ICR1L  = 0x67;   
 
 TCCR1A = 0x00;
 TCCR1B = 0x0A; //start Timer
   
       
// ======= 
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x07;

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x02;

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;
   

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 38400      кварц  8 MHz
UCSR0A=0x00;
UCSR0B=0x08;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x0C;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;

// Global enable interrupts
#asm("sei")

 amp_sin = 250; //debug   

ADCSRA=0x8E;
ADMUX=0;            // Порт ADC0 (MUX0-3=0)
ADCSRA|=0x40;       // Запустить измерение АЦП 

while (1)
      {
      // Place your code here 
                                  
 //   amp_sin = 250; //debug   
         
// плавное изменение амплитуды синусоиды

         OCR1AH = (unsigned char)((u+103) >> 8);
         OCR1AL = (unsigned char)(u+103);
         amp_sin = ~ (u>>2);
         delay_ms(300);

// while (freq_int < 700){  
// 
// delay_ms(300);   
// 
// freq_int = freq_int + 10;
// OCR1AH = (unsigned char)(freq_int >> 8);
// OCR1AL = (unsigned char)freq_int;
// 
// };
// 
// 
// while (freq_int>114){ 
// 
// delay_ms(300);   
// 
// freq_int = freq_int - 10;
// OCR1AH = (unsigned char)(freq_int >> 8);
// OCR1AL = (unsigned char)freq_int;
// 
//  };
 
 
 
      };
}

Код: Выделить всё

/*    www.avr123.nm.ru   2009-01

Табличное представоение половины волны синусоиды с добавкой одной четвертой части 3-й гармоники синуса

Таблица содержит 128 значений от 0 до 115 и провал от гармоники до 97
 
*/
 
flash unsigned char sinus[128]=
{
0,
6,
11,
17,
22,
27,
33,
38,
43,
48,
53,
58,
62,
67,
71,
75,
79,
83,
86,
90,
93,
96,
99,
101,
103,
105,
107,
109,
110,
112,
113,
113,
114,
114,
115,
115,
115,
115,
114,
114,
114,
113,
112,
111,
111,
110,
109,
108,
107,
106,
105,
104,
103,
102,
101,
100,
100,
99,
98,
98,
98,
97,
97,
97,
97,
97,
97,
97,
98,
98,
98,
99,
100,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
111,
112,
113,
114,
114,
114,
115,
115,
115,
115,
114,
114,
113,
113,
112,
110,
109,
107,
105,
103,
101,
99,
96,
93,
90,
86,
83,
79,
75,
71,
67,
62,
58,
53,
48,
43,
38,
33,
27,
22,
17,
11,
6
};


Re: ШИМ atmega8

Добавлено: Вт авг 08, 2017 04:43:10
7seg
Пока разбирался с теорией, возник вопрос зачем делают "подмес" 3-4 гармоники ?
Как будет себя вести АД с "подмесом" и без ?

Добавлено after 1 hour 20 minutes 14 seconds:
Может кто объяснить как правильно рассчитать таблицу синусов ? к примеру с дискретность в 128 значений ?
Также интересует почему в найденный мною примерах рассчитывают таблицу для периода или полу периода ? Если можно рассчитать для четверти, а потом просто брать значения в нужном порядке, и как я понимаю этим можно увеличить общую дискретность синуса(Что лучше скажется на формировании правильного синуса).

Re: ШИМ atmega8

Добавлено: Вт авг 08, 2017 08:06:18
Ivanoff-iv
да хоть в экселе.
упрощают алгоритм, можно сделать и для четверти, если развернёшь правильно, правда, я делал повышающий преобразователь, и с четвертями вышло не очень - изза остаточной намагниченности сигнал получился несимметричный (слишком плавный, медленный подъём и резкий спад) — пришлось делать полволны и подправлять.