Перейти к содержанию
    

Как состряпать алгоритм синусоидального ШИМ?

У Атмела есть апнот AVR447 как раз про это дело. Там предлагается использовать phase correct PWM mode и каждому плечу полумоста выделить канал OCхA на верхний ключ и OCхВ на нижний. Один канал прямой, второй инверсный. Ну и значение OCRnВ сделать меньше на  DeadTime. ШИМ выровнена по центру и каналы симметричны, получается, что канал В будет включаться позже, а выключаться раньше.

Но это как то расточительно - шесть каналов ШИМ на три фазы, да и нет столько в МК...

4 minutes ago, jcxz said:

Взять МК со счётчиками, имеющими dead-time и не заниматься ерундой и ногодрыжеством.

А отчего бы тогда вообще не купить китайский частотник "и не заниматься ерундой и ногодрыжеством"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, MPetrovich сказал:

А отчего бы тогда вообще не купить китайский частотник "и не заниматься ерундой и ногодрыжеством"?

Не надо валить с больной головы на здоровую.

Ногодрыгом просто невозможно реализовать нормальное управление мотором. В принципе. Без аппаратной поддержки (счётчиков с соответствующим функционалом).

А на МК имеющем, соответствующую периферию - вполне возможно сделать любое управление мотором. Без готовых частотников.

 

PS: Если нужно нарубить дров - берут топор. Никто в здравом уме не будет брать топор, когда нужно нарисовать рисунок. Он возьмёт карандаш. Вы же взяли топор, чтобы нарисовать рисунок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, MPetrovich сказал:

Но это как то расточительно - шесть каналов ШИМ на три фазы, да и нет столько в МК...

Есть их столько: OC0, OC1A, OC1B, OC1C/OC2, OC3A, OC3B, OC3C.  Даже один на плавное включение светодиода остается 🙂. И все четыре таймера можно запустить одновременно, т.е. синхронно через SFIOR.TSM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 minutes ago, Сергей Борщ said:

Есть их столько: OC0, OC1A, OC1B, OC1C/OC2, OC3A, OC3B, OC3C. 

Точно! Я как то упустил из виду, что 16-ти битные таймеры TIM1 и TIM3 описываются как один в даташите. Так что теперь Выше предложение

Quote

Можете еще попробовать использовать режим не простого ШИМ, а phase and frequency correct PWM.

стало неожиданно актуально)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда до кучи спрошу ещё об одном прерывании - прерывании по переполнению TIM2 используемого мной для динамической индикации, вызываемого с частотой 8000000/256/256=122,07Гц. В нём я устанавливаю признак запуска процедуры индикации, а в основном цикле проверяю этот признак. Если он установлен, то запускается процедура индикации. Она довольно громоздкая для 4-х разрядов и я её вытащил в основной цикл вместе со снятием показаний потенциометра для регулировки оборотов. Само прерывание состоит всего из одного действия, не считая проверки и сброса флага, от которых я думаю отказаться, поскольку флаг сбрасывается автоматом.

ISR(TIMER2_OVF_vect)
{ 
TIFR |= 0x40;//TIFR[6]=TOV2=0x40; TOV2 is cleared by writing a logic one to the flag.
 
   indicator = 1 ;
}

ну и в основном цикле

if(indicator == 1)indication();

по окончании indication(); признак сбрасывается indicator = 0;

Вопрос: это прерывание не тормозит программу?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посчитал частоту ШИМ для PWM Phase Correct, 8-bit, получилось так: F_PWM = F_CLK/2*N*TOP = 8MHz/2*1*256 = 15625Hz (эх, жалко частота в звуковой диапазон попадает :-(  ), что дает период ШИМ равный 1/15625=64мкСек. Т.е. минимально возможный Dead-Time=64/256=0,25мкСек. Я верно рассуждаю?

1 hour ago, Сергей Борщ said:

можно запустить одновременно, т.е. синхронно через SFIOR.TSM.

То есть сначала ставим TSM=1, потом инициализируем таймеры, а потом сбрасываем TSM=0 и таймеры стартуют одновременно. Так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В ATtiny261A / 861A есть готовый трёхфазный 10-разрядный таймер с тактированием от умножителя с ФАПЧ и с генератором пауз. Ещё у производителя есть примеры запуска трёхфазных двигателей как для обычных атмег, так и для ATtiny x61. Есть у неё недостаток - нет нормальных интерфейсов, только сдвиговый регистр.

Ещё готовые трёхфазные таймеры с паузами есть во многих 32-разрядных МК, даже китайских.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, vov4ick сказал:

Ещё готовые трёхфазные таймеры с паузами есть во многих 32-разрядных МК, даже китайских.

Да есть куча МК с таймерам под многофазное управление, dead-time, аппаратными fault-ами и прочими плюшками для управления моторами. Просто бери и пользуйся. Колхоз не нужен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, vov4ick said:

Ещё готовые трёхфазные таймеры с паузами есть во многих 32-разрядных МК, даже китайских.

Если бы я хотел 32-х разрядный контроллер, то я взял бы stm32 и использовал его фишки. И операции с flat, и готовые трехфазные таймеры, и частотку в разы выше, и разветвленную систему прерываний...

Однако, я использую 8-ми разрядный avr и код пишу для него. Если у уважаемых участников есть дельные предложения по 8-ми битным МК, я с большим удовольствием ими воспользуюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, MPetrovich сказал:

Вопрос: это прерывание не тормозит программу?

Конечно тормозит. А зачем оно вообще нужно? Что мешает проверять и сбрасывать флаг переполнения таймера прямо в основном цикле?

5 часов назад, MPetrovich сказал:
TIFR |= 0x40;

Это неправильно. Тут вы сбрасываете заодно и все остальные флаги, которым не повезло оказаться установленными в этот момент. Тут должна быть запись TIFR = 1 << TOV2;, хотя и она тут лишняя - эти флаги сбрасываются в момент входа в соответствующее прерывание.

 

4 часа назад, MPetrovich сказал:

То есть сначала ставим TSM=1, потом инициализируем таймеры, а потом сбрасываем TSM=0 и таймеры стартуют одновременно. Так?

Да, так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

35 minutes ago, Сергей Борщ said:

TIFR |= 0x40 Тут вы сбрасываете заодно и все остальные флаги, которым не повезло оказаться установленными в этот момент

А по-моему я устанавливаю 3-й бит регистра TIFR. Ведь это не прямое присвоение, а "или" с константой и потом присвоение. Все остальные биты не меняются.

 

40 minutes ago, Сергей Борщ said:

TIFR = 1 << TOV2;,

А вот здесь прямое присвоение и остальные биты обнуляются.

 

41 minutes ago, Сергей Борщ said:

эти флаги сбрасываются в момент входа в соответствующее прерывание.

Вот и я так думаю - лишнее действие, потребляющее лишние циклы.

 

42 minutes ago, Сергей Борщ said:

Что мешает проверять и сбрасывать флаг переполнения таймера прямо в основном цикле?

Вот Вы всегда предлагаете действия, которые после того, как Вы предложили, кажутся очевидными. Но я отчего то этого не вижу... Спасибо за очередную подсказку!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

43 минуты назад, MPetrovich сказал:

А по-моему я устанавливаю 3-й бит регистра TIFR.

А Вы почитайте описание TIFR и все сразу станет понятно (в частности, что будет, если TOV1, например, установился до выполнения строчки TIFR |= 1 << TOV0).
 

Цитата

А вот здесь прямое присвоение и остальные биты обнуляются.

TIFR - это не просто переменная, это аппаратный регистр. Он спроектирован таким образом, что запись "0" туда не влияет на уже установленные там "1" в битах. А вот запись "1" в соответствующий бит обнулит его, если там уже стояла "1". Т.е. это регистр, биты которого чувствительны только к записи ненулевых битов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы ещё проверил, во что компилируется TIFR |= ххх, вдруг не атомарная операция, тогда если бит между операциями сбросится (вызовом прерывания), будут скрытые грабли.

2 часа назад, MPetrovich сказал:

Если у уважаемых участников есть дельные предложения по 8-ми битным МК, я с большим удовольствием ими воспользуюсь.

В первом абзаце было.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 часов назад, vov4ick сказал:

тогда если бит между операциями сбросится (вызовом прерывания), будут скрытые грабли.

Не будут. Запись единицы не устанавливает бит конкретно в этом регистре.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 hours ago, Arlleex said:

TIFR - это не просто переменная, это аппаратный регистр. Он спроектирован таким образом, что запись "0" туда не влияет на уже установленные там "1" в битах. А вот запись "1" в соответствующий бит обнулит его, если там уже стояла "1". Т.е. это регистр, биты которого чувствительны только к записи ненулевых битов.

Понятно. Благодарю за разъяснение. Теперь буду правильно использовать операцию сброса флага в этом регистре.

 

9 hours ago, vov4ick said:

В первом абзаце было.

 

14 hours ago, vov4ick said:

В ATtiny261A / 861A есть готовый трёхфазный 10-разрядный таймер

Мне по объёму памяти подойдут ATtiny461A / 861A, в 261А программа не влезет. Однако этих МК у меня в наличии нет, а ATMega128 есть и не одна)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...