ШИМ Синусоида
- Войдите на сайт для отправки комментариев
Вс, 06/12/2015 - 16:54
Требуется собрать генератор двух одинаковых ШИМ сигналов, которыми промодулирована частота 60 герц. Есть программные средства для создания двух ШИМ с противоположной полярностью?
мб инвертор на транзисторе, но будет на микросекунды запаздывать.
Инвертор не получится использовать, лучше всего это программно реализовать.
Есть программные средства для создания двух ШИМ с противоположной полярностью?
Есть, биты Compare_Output_mode регистра TCCRxA задают требуемый режим выхода.
Ладно, уже что-то. Спасибо.
А на какой частоте нужен ШИМ? Аналоговый выводы не подойдут? Тогда все просто на один вывод 512+511*sin(2*pi*60*t) на другой 512-511*sin(2*pi*60*t). Или я чего не понял.
А где у дунек "аналоговые выходы"? :)
Подойдет частота выше звуковой, хочу использовать таймер 0 в режиме Phase-correct PWM. Тогда частота должна быть 31,25 кГц. Всё так?
После pinMode мне, видимо, нужно написать:
TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
TCCR0B = _BV(CS00);
В соответствии с:
http://playground.arduino.cc/Main/TimerPWMCheatsheet
Но, что делать дальше, я особого понятия уже не имею. Нашел только это:
https://www.arduino.cc/en/Tutorial/DueSimpleWaveformGenerator
Отсюда можно взять массив для синусоиды. Точнее, нельзя. В нём всего лишь 255 значений, а нужно 510.
А где у дунек "аналоговые выходы"? :)
http://arduino.ru/Reference/AnalogWrite
Это PWM или ШИМ ноги .. они точно также как и остальные устанавливаются или в лог.0 или в лог.1 .. разница только в том, что время стояния 1 (или 0) можно указывать в аппаратном таймере .. вы же написали про "аналоговые выходы" .. то есть я вас понял про DAC конвертер (преобразование числа в аналоговый уровень сигнала аппаратно) .. у ATxmega да, такие есть .. но насколько знаю на них нет "Ардуино" плат или они не распространены.
Чтобы из ШИМ сделать полноценный DAC вообще-то надо постараться. Простой интегрирующий конденсатор полезен только для фиксированной частоты DAC.
Не имеет особого смысла использовать DAC. Нужно лишь составить массив из значений коэффициента заполнения, т.к. модулируемая частота строго фиксирована. Из хитростей требуется только прямая запись в регистры, насколько я понял за последние пару часов. Такой код даже на 10% не нагрузит процессор МК.
Возьмите любой таймер AVR-ки (не знаю в какой модели вы это хотите использовать, подойдет "любая"), настройте один его выход (их от 2 до 4 в зависимости от модели на таймер) на прямую выдачу, а второй на инверсную и управляйте ШИМ таймера хоть по синусоиде, хоть по какому иному закону, хоть таблично, ... в общем как вдумается. В чем проблема?
Nickalaich, вам будет проще найти аналогичный проект. С начальными знаниями о таймерах ничего не получится, тут нужно досканально понимать все нюансы программирования таймеров. Нужно настроить 16-битный таймер на прерывание по переполнению, если вам нужна точность в 512 отсчётов, то выходная частота будет 31250/512=61,03 Гц В прерывании по переполнению нужно программировать скважность таймера из готового буффера данных на 512 байт, или вычисляя математически. Второе вряд ли реально при такой скорости. Первое может и реально, но в любом случае МК ничего другого делать уже не сможет. Так что в любом случае лучше задуматься о чисто аппаратном решении данной задачи.
Первый вариант реален, больше ничего от МК и не требуется. Я выбрал именно такой способ, потому что аналоговый способ генерации ШИМ сигнала именно такой частоты требует гораздо больше деталей и импульсный трансформатор. В заданный корпус может не влезть.
Nickalaich, ну найдите сначала (или сделайте) массив синуса на 512 байт, глядишь и выйдет чего :)
Верно. Только непонятно почему накатать 512 байт в предварительный буфер - "проблема" или сложность. Взять калькулятор, подсчитать заранее и сложить в общую программную память. Оттуда доставать при завершении предыдущего счета в таймер. Да, при 512 значениях можно обойтись буфером в 1/4 периода (128шт) ибо синус симметричен, что позволяет обойтись и 8-и битным таймером...
Вопрос - массив обязательно должен быть в шестнадцатеричной системе счисления?
?!? Этот вопрос на что влияет и из каких соображения появился? :)
А впрочем, я уже нашел таблицу значений :)
Да, ступил. Если надо 512 значений по амплитуде, то 8-и битный тайрем использовать, скорее всего, не получится.
А впрочем, я уже нашел таблицу значений :)
да в сетапе расчитайте нужную таблицу в нужном виде в массив и усё, в лупе пользуйте. Это к стати может быть и не отсчеты синуса а непосредственно длительности импульса ШИМ для соответствующей фазы сигнала. И нужно их не 512 а в 4 раза менше. тригонометрия в помощ!
Собссно я уже из любопытсва накатал код и проверил. Правда таблицы синуса на 512байт подрукой не было, взял на 256 байт. Генерит на выводах 9 и 10 ардуино шим-синус, каналы в противофазе. Скетч:
Результат (через 2 интегрирующие цепи разумееется):
А есть возможность показать нефильтрованные сигналы? Мне нужны два сигнала для того, чтобы давать их драйверу полумоста. Хочу сопоставить моменты включения каждого транзистора, а мой совковый осцил не очень-то такие удобства дает.
Огромное спасибо за код :)
Все-таки непонятно, почему не посчитать таблицы синуса в setup(), как советует Logik.
Это занимает процессорное время.
Это занимает процессорное время.
А если сгенерить 3 ШИМ-синусоиды со сдвигом 120 градусов то уже чисто коммерческий проект выйдет ;)
Да можно и этот проект коммерческим сделать без особых проблем - получается достаточно точный генератор 120 вольт 60 герц из 230 вольт 50 герц. Мне он нужен, чтобы американский синхронный двигатель завести в номинальную мощность.
А есть возможность показать нефильтрованные сигналы?
Да, конечно. Вот два варианта отображения этого же сигнала, разница в установленном времени развёртки:
Прекрасно. В следующие выходные, наверное, протестирую. Придется ещё поискать изолирующий трансформатор. А частота ШИМа - 31,25 кГц?
Nickalaich, да. 16000000/512= 31250, но в данном скетче за один полный цикл Wave Form Generator' а (512 тактов) синус рисуется 2 раза, тк. он на 256 байт.
Хорошо, большое спасибо за разъяснения. С Вашей помощью мне требуется только плату развести, можно сказать.
Калькулятор таблиц значений http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml, если захотите сделать подобное в будущем :)
Nickalaich, оказывается у меня уже был этот сайт в избранном, но с закладкой на калькуляторы :)
По картинкам хочется спросить: а что там за хвосты на крайних значениях? Можете вывести верх и/или низ в более растянутом варианте?
Совсем забыл про одну очень важную деталь. Моменты включения-выключения этих ШИМ ни в коем случае не должны совпадать. Нужен dead time, иначе полевые ключи сгорят. Для ШИМ-контроллера стандартный dead time - 3%. Те ключи, что я собираюсь использовать, достаточно быстродействующие, так что dead time можно сократить до 1%. Значит, OCR1A и OCR1B должны отличаться на 5 тактов, верно?
Arhat109-2, не совсем понял, про какие хвосты речь, на каком рисунке хоть?
Nickalaich, я очень слабо знакомом с спецификой дед-таймов, так что могу высказать только предположение. По-моему средствами atmega328 невозможно сдвинуть фазы ШИМ друг относительно друга. Эта возможность есть в некоторых более свежих МК, в частности в "народной" attiny85.
Если один цикл ШИМ составляет 512 тактов, то дед-тайм в 1% составит 5 тактов. Вполне осуществимо, кажется, хотя этого должно быть предостаточно для срабатывания драйвера и полевика. Тогда обработчик прерывания будет таким? И, наверное, надо таблицу значений подкорректировать.
ISR (TIMER1_OVF_vect) {
static
uint8_t n=0;
OCR1A - 5 = OCR1B = sine_wave[n];
n++;
}
Есть возможность перенести код на STM32F1.
Там где у вас приведены синусоиды. В вверху и внизу (макс и мин) значений наблюдается существенное "уширение" рисунка. Там явно "что-то есть". Вот и хотел посмотреть.
Да почему сложно-то?
Если пользовать 2 ноги одного счетчика в противофазах - то они конечно будут шлепать синхронно .. причем очень синхронно, ибо аппаратно.
Но, есть же режим коррекции фазы и частоты, и в если в нем загружать ШИМ +-1 в пределы срабатывания, то вполне можно получить (не пробовал сам) ситуацию когда одна нога будет гарантированно выключаться "чуть раньше" или "чуть позже". Но это уже надо серъезно вкуривать даташит на 16-и битные счетчики и смотреть кто кого и когда должен "опережать".
Как вариант использовать 2 счетчика сдвигая их на заданную величину. Таким же способом можно организовать и "трехфазные" ШИМ. :)
Nickalaich, может мы о чём-то разном говорим? Посмотрите на второй рисунок в #27 У обоих оцилограмм передний фронт наступает чётко синхронно. Длительность импульса может быть сколь угодно разной, но передний фронт всегда одновременно. Я так понимаю, что разность в наступлении переднего фрона - это и есть дед тайм. К сожалению значение OCR на это никаким образом не влияет. Arhat109-2 верно вспомнил про один хитрый режим, в котором могут разойтись фронты при разных OCR, но это сразу приведёт к искажению формы синуса. До какой степени -не знаю, нужно проверять.
Arhat109-2, там утолщение просто следствие упрощённого преобразования шим-напряжение, если увеличить то там будет видно, как проползает несущая частота.
В режиме Phase-correct PWM оба фронта могут не совпадать. Так что мой костыль, возможно, мог бы и проканать.
При таком мизерном расхождении фронтов ощутимых искажений не будет, я думаю...
Да, пробовать нужно. До самых выходных не будет возможности :/
Нашел полезную инфу:
http://www.hilltop-cottage.info/blogs/adam/avr-timer1-dead-time-generato...
Надо бы закупиться десятком тинек и кварцами.
dimax, ну вот и мне так показалось, что применение конденсатора в качестве интегрирующего звена "не комильфо". правильнее делать полноценный интегратор на ОУ. :)
P.S. Ибо DAC - отсутствует ..
Да почему не комильфо? Г-LC фильтр достаточно проинтегрирует ШИМ. Я очень, очень сомневаюсь, что в промышленных установках кто-то использует ЦАП для управления двигателями. Там и синусоиду не всегда используют. Устройство силовое всё же, и к тому же сигнал на выходе из ардуины должен быть строго импульсным. Это простейший усилитель класса D, по сути.
ШИМ-синус 60Гц 9-битный (512 отсчётов)
Да можно и этот проект коммерческим сделать без особых проблем - получается достаточно точный генератор 120 вольт 60 герц из 230 вольт 50 герц. Мне он нужен, чтобы американский синхронный двигатель завести в номинальную мощность.
Выяснилось, что было бы крайне неразумно строить такой девайс на Arduino/AVR МК, т.к. у STM32, имеющегося в наличии, есть возможность аппаратно генерировать dead-time и поднять частоту ШИМ. В конечном варианте хочу использовать STM32F030, а пока тестирую на F103. Код нужен?
Это занимает процессорное время.
Для Вас лишние 0.06 с один раз при включении - это критично?
Не знаю. Самое критичное - это дедтайм, на AVR он вводится как костыль. Поэтому я переношу код на STM32, там его реализация никаких проблем не составляет на уровне железа и добавляет в код всего 3 строчки.
И зачем вычислять то, что и так уже вычислено? Смысл в этом вообще какой? Почему бы не упростить контроллеру задачу, и не положить в память готовую таблицу?
Добрый вечер Всем
DIMAX очень хороший пример
попобую еще связать с драйвером IR2110 (2 шт в мост)
Nickalaich
где код-то для stm32
хороший пример. только он к сожалению для фиксированной частоты. А мне бы надо регулируемой частоты две синусы в противофазе как у Вас. вот чую в сетапе должен быть блок вычисления массива синуса по данным с потенциометра а как это формализовать не знаю мозги не доходят. новичок я еще в этом деле. частоты нужны небольшие до 20 гц. а опрос потенциометрат вроде как в лупе должон быть.