Подскажите микросхему - программно управляемый генератор прямоугольных импульсов звукового диапазона.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Собственно, совершенно незнаком с современной элементной базой.

Итак, что хочется:

- генератор прямоугольного сигнала с регулируемой скважностью, период которого управляется с точностью не хуже 2 мкс.

- характерное значение скважности 1/7, меандр и короткий импульс не подходят.

- желательно управление по последовательномиу порту (не обязательно UART).

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

- только DIP - более тонконогие я не запаяю.

- при задании новых параметров сигнала они должны вступать в силу со следующего периода (не прерывая текущий период посередине).

- по вменяемой цене.

Из того, что мне известно, не оченьт подходит к580ви53 (8253). Что не нравится:

- нужен внешний генератор,

- управление в параллельном коде, для подключения к Ардуине нужен дополнительно сдвиговый регистр,

- крупный корпус,

- для формирования нужного сигнала следует использовать 2 канала: один как делитель частоты, другой - как формироатель импульса заданной длительности.

Все-таки с момента создания 8253 прошло уже несколько десятилетий, должно же было за это время появиться что-нибудь более "вкусное".

MagicianT
Offline
Зарегистрирован: 03.10.2015

А чем не подходит генерация на самой ардуино?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

MagicianT пишет:

А чем не подходит генерация на самой ардуино?

При частоте дискретизации 40 кГц погрешность получается 25 мкс вместо желаемых 2. А как показал проект http://arduino.ru/forum/proekty/floppy-hdd-music , увеличивать частоту дискретизации при нескольких генерируемых частотах уже некуда. 25 мкс в игрушке - куда ни шло, а для музыкального инструмента это явно много.

Bront
Offline
Зарегистрирован: 05.04.2016

Наверное что-то типа этого нужно

http://www.ebay.com/itm/141625769493?_trksid=p2055119.m1438.l2649&ssPage...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Спасибо.

Почитал с интересом, но, похоже, это не совсем то, что нужно. Все-таки DDS рассчитан на формирование синусоиды.

Честно говоря, не понял, может ли он генерить прямоугольник с управляемой скважностью. Конечно, последний можно получить из треугольника, но это, опять же, требует дополнительных корпусов. А это существенно, т.к. каждую конструкцию нужно будет изготовить в количестве порядка 10 шт.

По сравнению с 8253, насколько я понимаю, достоинства и недостатки следующие:

- по размеру корпуса 9833 конечно предпочтительнее 8253, но это достоинство с избытком компенсируется следующим недостатком,

- 9833 не выпускается в DIP корпусе - это для меня очень серьезный недостаток,

- для одного генератора нужен целый корпус 9833, тогда как 8253 - только 2/3, т.е. преимущество на стороне 8253,

- и то и другое требует внешнего генератора - ничья,

- у 8253 параллельный интерфейс, а у 9833 - последовательный, это - плюс.

В общем, идея интересная, но, похоже, недостатков больше чем достоинств. Особенно если окажется, что скважностью он управлять не может.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano, в принципе можно сделать и на ардуине или даже на какой нить тиньке, запустив её скажем на 20МГц , но генерить не таймером, а чисто программно, на ассемблере. Что-то типа функции, которая принимает в себя нужное число тактов процессора с поднятой ногой и с опущенной. И сответссно отсчитывает их и дёргает ногой.  Разрешение в этом случае будет  1/20MHz =0,05мкс. а разрядность регулировки скважности для 40кГц -500 шагов.  Перепрограммировать функцию например через прерывание. Но для этого нужно знать ассемблер, на СИ такое не написать.. :)

gena
Offline
Зарегистрирован: 04.11.2012

 Здесь http://www.radiokot.ru/forum/viewtopic.php?t=127111 утверждается, что скважность можно менять.

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

AD9833.pdf

Если хочется больше то AD9959.pdf

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

gena пишет:

 Здесь http://www.radiokot.ru/forum/viewtopic.php?t=127111 утверждается, что скважность можно менять.

Спасибо.

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

Надо разбираться.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

NeiroN пишет:

AD9833.pdf

Если хочется больше то AD9959.pdf

4 канала - это хорошо. Только, насколько я понял, микросхема генерит ТОЛЬКО синус. А для прямоугольного сигнала с регулируемой скважностью предлагается использовать 2 канала + внешний компаратор. Т.е. для формирования 4 сигналов нужно 2 корпуса 9959 и 1 компаратора (если их 4 штуки в корпусе). На 12 сигналов - 9 корпусов. В случае 8253 - 3 сигнала на 2 корпуса, т.е. на 12 сигналов - 8 корпусов. Еще задающий генератор почему-то требуется от 20 до 30 МГц, хотя я предпочел бы 0.5-1.0 МГц. Ну и распаивать такую многоножку я вряд ли решусь.

Но в любом случае спасибо. Чувствую, нужно где-то раздобыть сводную таблицу по параметрам AD9xxx.

gena
Offline
Зарегистрирован: 04.11.2012

 Так AD9959 - считай золотая. А мне нравилась  КР1810ВИ54.  Была в "ZX Spectrum " Yamaha YM2149F.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

andriano, в принципе можно сделать и на ардуине или даже на какой нить тиньке, запустив её скажем на 20МГц , но генерить не таймером, а чисто программно, на ассемблере. Что-то типа функции, которая принимает в себя нужное число тактов процессора с поднятой ногой и с опущенной. И сответссно отсчитывает их и дёргает ногой.  Разрешение в этом случае будет  1/20MHz =0,05мкс. а разрядность регулировки скважности для 40кГц -500 шагов.  Перепрограммировать функцию например через прерывание. Но для этого нужно знать ассемблер, на СИ такое не написать.. :)

Бегло просмотрел систему команд AVR. Простые команды выполняются 1 такт, команда переходе - не менее 2 тактов, т.е. цикл можно задать с дискретностью не лучше 3 тактов. Другое дело, что к циклу всегда можно добавитиь от 0 до 2 NOP'ов, что позволит сделает его с точностью до такта. Слава Богу, насколько я понял, в AVR, как и в старом добром 8080 время выполнения достаточно просто считать по тактам.

Что такое "Перепрограммировать функцию через прерывание" я не понял.

У меня вот тут родилась идея, как при частоте дискретизации те же 40-44 кГц уменьшить погрешность с 23-25 мкс до 2. Если в исходном варианте я настраиваю прерывания на 40 кГц и заношу в счетчик длительнсть положительного или отрицательного полупериода в 25-мкс тактах, а потом в каждом прерывании уменьшаю на 1, пока не достигну 0, тогда дергаю ногу и заношу в счетчик длительность другого полупериода. Можно вместо этого в счетчик заносить число как если бы частота прерываний была 480 кГц, а вычитать при каждом вызове не 1, а 12. И не заносить длительность нового полупериода, а прибавлять ее к уже имеющемуся числу. Будет небольшой джиттер, зато частота быдет выставлена с существенно большей точностью. Правда, надо посчитать, не огребу я так каких-то негармонических составляющих. Все-таки теорема Котельникова-Шеннона подразумевает, что в исходном сигнале удалены частоты выше половины частоты дискретизации, а для таким образом формируемого сигнала это будет не так. Т.е. если половина частоты дискретизации 20 кГц, то, генерируя, например, 6 кГц, не получу ли я вдобавок паразитную частоту 20-6=14 кГц.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano, я сегодня ещё раз прочёл условие -а чем генерация 16 битным таймером не подходит? Ведь идеально же. Точность установки скважности будет равна такту = 0,0625 μS   На частоте  40кГц   будет 400 шагов регулировки скважности, -более чем достаточно. А чем ниже будет частота, тем число шагов ещё выше. Даже примерчик вам что б не голословно было:

void setup() {
pinMode(9,OUTPUT);
TCCR1A=(1<<COM1A1)|(1<<WGM11);
TCCR1B=(1<<WGM12)|(1<<WGM13)|(1<<CS10);   //mode 14
ICR1=399;// 16MHz/40kHz = 400 тактов на полный период для 40кГц
OCR1A=199; // скважность 50% для 40кГц
}

void loop() {}

 

gena
Offline
Зарегистрирован: 04.11.2012

  А если ардуинку ещё и "разогнать" до 24 МГц, то и выходная частота повыше станет.

gena
Offline
Зарегистрирован: 04.11.2012

  Комментарий к посту #8: там опереционный усилитель служит ЦАПом, а 74LVC8T245 - формирователем цифрового выходного сигнала. Благодаря ОУ можно менять амплитуду цифрового выхода, меняя напряжение питания 74LVC8T245.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

andriano, я сегодня ещё раз прочёл условие -а чем генерация 16 битным таймером не подходит? Ведь идеально же. Точность установки скважности будет равна такту = 0,0625 μS   На частоте  40кГц   будет 400 шагов регулировки скважности, -более чем достаточно. А чем ниже будет частота, тем число шагов ещё выше. Даже примерчик вам что б не голословно было:

void setup() {
pinMode(9,OUTPUT);
TCCR1A=(1<<COM1A1)|(1<<WGM11);
TCCR1B=(1<<WGM12)|(1<<WGM13)|(1<<CS10);   //mode 14
ICR1=399;// 16MHz/40kHz = 400 тактов на полный период для 40кГц
OCR1A=199; // скважность 50% для 40кГц
}

void loop() {}

dimax, честно говоря, я Ваш код не понимаю. Можно его перевести с AVR на Arduino?

А поскольку не понимаю, задаю глупые вопросы:

1. Сколько сигналов можно вывести одновременно указанным способом? Нужно порядка 10.

2. В принцпе, loop() пустой, но на всякий случай спрошу: можно ли помимо генерации набора сигналов производить дрполнительные действия: принимать данные по COM-порту, управлять частотой генерируемых сигналов (независимо), а также дополнительными устройствами? Можно привести пример, скажем, генерации 10 различных частот с вибрато (низкочастотной модуляцией 7-9 Гц)?

inspiritus
Offline
Зарегистрирован: 17.12.2012

исторически я сторонник делать аппаратно по-максимуму

генератор с регулируемой скважносью, как я понимаю это ШИМ

может быть Вам ЭТО подойдет ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano, код к сожалению не переводится в ардуино-френдли, а по вопросам: (1) -сколько 16-битных таймеров в МК, столько и выходов. Т.е. для меги328 -один выход. Правда можно 2 выхода таймера задействовать, если одинаковая частота по обоим выходам устраивает. (2) таймер вообще никак не загружает основной контроллер, так что пока таймер молотит -м.к. просто "валяет дурака", и может делать абсолютно любые доступные ему дела. Что-бы промодулировать одну частоту другой -нужен ещё один 16-бит таймер. Соответссно завести его на 7-9 герц, и останавливать с этой частотой первый таймер. Но как мне кажется иметь возможность регулировки скважности и модуляция -это всё таки взаимоисключающие вещи, т.к. в первом случае это натуральный шим, его не применяют для звукоизвлечения, хотя я не вникал в логику тех "поющих дисководов", может там это и совместимо. 

nik182
Offline
Зарегистрирован: 04.05.2015

inspiritus пишет:

исторически я сторонник делать аппаратно по-максимуму

dimax предложил как раз аппаратное по максимуму. И совершенно не затратное. И генерящее до 62 кГц со скважностью 1/ICR1 - (ICR1-1)/ICR1. И как раз для ардуины. Аппаратное - потому что после настройки генерит не затрагивая процессор.

В loop можно только OCR1A=ХХХ; писать в регистр число от 1 до того, что в ICR1-1 и менять скважность. 
Прочитайте про таймеры AVR и всё станет ясно. Например здесь  
inspiritus
Offline
Зарегистрирован: 17.12.2012

Я понимаю, что предложил уважаемый dimax.

Несомненно это аппаратное решение.

Они ( эти решения аппаратные) могут быть интегрированными и внешними.

я предложил внешнее на случай например занятости интегрированного таймера для иных целей.

опять же тс просил более одного канала

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

inspiritus пишет:

может быть Вам ЭТО подойдет ?

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

(1) -сколько 16-битных таймеров в МК, столько и выходов. Т.е. для меги328 -один выход.

Один корпус на канал - по этому параметру 328 проигрывает как 8253, так и 9833.

Цитата:

Правда можно 2 выхода таймера задействовать, если одинаковая частота по обоим выходам устраивает.

Добавляем 155лн1 и имеем 8 выходов с одной частотой.

Цитата:

(2) таймер вообще никак не загружает основной контроллер, так что пока таймер молотит -м.к. просто "валяет дурака", и может делать абсолютно любые доступные ему дела. Что-бы промодулировать одну частоту другой -нужен ещё один 16-бит таймер. Соответссно завести его на 7-9 герц, и останавливать с этой частотой первый таймер.

Останавливать таймер - это зачем? Тут важно, чтобы таймер не сбрасывался при переустановке частоты. А вибрато делается небольшой перестройкой частоты раз эдак 2000 в секунду. Ну чтобы модулирующая синусоида укладывалась а 256 отсчетов.

Цитата:

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

ШИМ строго говоря не нужен. Нужен генератор, позволяющий управлять как частотой так и скважностью импульсов. В идеале один раз устанавливаем свкажность и дальше не трогаем. Или трогаем, если понадобится. Если так нельзя, отдельно устанавливаем длительности отрицательной и положительной полуволн, чтобы обеспечить нужные частоту и скважность.

"Поющие дисководы" - это игрушка. И там неточность строя не играла существенной роли. Тем более, что высокие частоты (для которых погрешность 25мкс сильно заметна) дисководной механике попросту недоступны.

Но генерить штук 8 сигналов программно на одной 328 я все равно попробую. По тому алгоритму, что я излагал выше.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

andriano пишет:

У меня вот тут родилась идея, как при частоте дискретизации те же 40-44 кГц уменьшить погрешность с 23-25 мкс до 2. Если в исходном варианте я настраиваю прерывания на 40 кГц и заношу в счетчик длительнсть положительного или отрицательного полупериода в 25-мкс тактах, а потом в каждом прерывании уменьшаю на 1, пока не достигну 0, тогда дергаю ногу и заношу в счетчик длительность другого полупериода. Можно вместо этого в счетчик заносить число как если бы частота прерываний была 480 кГц, а вычитать при каждом вызове не 1, а 12. И не заносить длительность нового полупериода, а прибавлять ее к уже имеющемуся числу. Будет небольшой джиттер, зато частота быдет выставлена с существенно большей точностью. Правда, надо посчитать, не огребу я так каких-то негармонических составляющих. Все-таки теорема Котельникова-Шеннона подразумевает, что в исходном сигнале удалены частоты выше половины частоты дискретизации, а для таким образом формируемого сигнала это будет не так. Т.е. если половина частоты дискретизации 20 кГц, то, генерируя, например, 6 кГц, не получу ли я вдобавок паразитную частоту 20-6=14 кГц.

Просчитал спектр для этой идеи. Не вариант - появляются негармонические составляющие:

На верхнем рисунке спектр сигнала с периодом кратным периоду частоты дискретизации (64/8), а на втором - некратным (64/7). Видна масса составляющих, не являющихся гармониками основного тона.

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

Кто-нибудь может подсказать способ генерации нескольких сигналов одной Ардуиной на разных ногах с различной частотой?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

andriano, код к сожалению не переводится в ардуино-френдли, а по вопросам: (1) -сколько 16-битных таймеров в МК, столько и выходов. Т.е. для меги328 -один выход.

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

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

Идея такая: нужный коэффициент деления подбирается в виде A*B*C, где:

A - коэффициент предделителя,

B - коэффициент деления счетчика 2 (от 2 до 256 или от 2 до 512 с шагом 2),

С - коэффициент деления, реализуемый программно: с частотой A*B вызывается прерывание, у которого свой счетчик (т.е. переменная), по которому и происходит переключение пина на каждое C-е прерывание (точнее, два переключения, чтобы обеспечить нужную скважность).

Но возникли непонятки. Мне кажется, именно Вы советовали книжку А. В. Евстифеева. Так вот, там на странице 354 есть таблица режимов, из которой следует, что как для Fast PWM, так и для Phase Correct PWM есть режимы (5 и 7), в которых коэффициент деления задается регистром OCR2. Далее эти режимы описаны, но на страницах 358 и 360 приведены формулы для расчета частоты, расчитанные на счет до конца т.е. до FF. Для стандартного режима (на стр. 356) в формуле для частоты фигурирует OCR.

Так как на самом деле? Можно ли в режимах Fast PWM и Phase Correct PWM задавать коэффициент деления отличный от 256 и 512 соответственно?

Цитата:

Что-бы промодулировать одну частоту другой -нужен ещё один 16-бит таймер. Соответссно завести его на 7-9 герц, и останавливать с этой частотой первый таймер. Но как мне кажется иметь возможность регулировки скважности и модуляция -это всё таки взаимоисключающие вещи, т.к. в первом случае это натуральный шим, его не применяют для звукоизвлечения, хотя я не вникал в логику тех "поющих дисководов", может там это и совместимо. 

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

Сделаю - выложу пример.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Попытался.
Попытка ниже (в последней строчке предыдущего поста ошибка: следует читать "таймере 0").
Собственно, к аналоговому входу А1 нужно подключить потенциометр 0-5В, а к 9 пину через делитель примерно 1/10 вход аудио (в принципе, видно и на осцилографе).
И самое главное: управление частотой звука (вибрато) осуществляется по прерыванию. Но прерыванием я пользуюсь стандартным - от 0 таймера по совету ЕвгенийП http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-me...
Т.е. нужно править включаемые файлы.

unsigned long icr; // ICR+1;
unsigned char vibrato = 0;

void Every_1024us(const unsigned long ii) {
  static int counter; // при частоте вызовов 978 Гц частоте 7 Гц соотв. период 140 тиков
  if (counter < 70) {
    ICR1=(icr-1) + (counter - 35)*vibrato/64;
  } else {
    ICR1=(icr-1) + (105 - counter)*vibrato/64;
  }
  OCR1A = ICR1/7;  // скважность 1/7
  counter++;
  if(counter == 140) counter = 0;
}

void setup() {
  Serial.begin(115200);
  pinMode (9,OUTPUT); // выход генератора PB2
  TCCR1A=1<<COM1A1; //подключить выход OC1A первого таймера
  TCCR1B=2|(1<<WGM13);; // //  divider=8;
  icr = 2273; 
  Timer0_Hook = Every_1024us;
}

void loop() {
  delay(500);
  vibrato = analogRead(A0)/4;
  Serial.print(vibrato);
  Serial.print('\t');
  Serial.println(35*vibrato/64);
}


В сущности, того, чего хотел, добился, но возникли маленькие проблемы. А именно - время от времени генерация срывается. На слух это воспринимается как толи короткие паузы, толи щелчки. В общем, в звуке присутствуют дефекты.
При отсутствии вибрато дефектов нет. И при незначительной амплитуде - тоже. Есть предположение, что дефект возникает тогда, когда изменяется старший байт делителя частоты.
В принципе, 8-разрядный процессор записывает двухбайтовое число в регистр побайтно, но, вроде, когда дело касается коэффициента деления, старший байт должен записываться во временный регистр, а в момент записи младшего оба они заносятся в таймер одновременно.
По крайней мере, так должно быть (если я правильно понял документацию).
Посмотрел описание ICR1 в файле iom328p.h:
#define ICR1 _SFR_MEM16(0x86)
Т.е. пишется он не в регистр, а в память (если я правильно понимаю).

Отсюда два вопроса:
1. Нет ли какого другого возможного источника проблемы кроме того, что я указал выше?
2. Как обеспечить одновременное занесение в регистр обоих байтов?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano пишет:

Так как на самом деле? Можно ли в режимах Fast PWM и Phase Correct PWM задавать коэффициент деления отличный от 256 и 512 соответственно?

Нет, в таймере2 такой возможности нет. В нём можно плавно регулировать что-то одно. Либо регулировать частоту(режим СТС ) либо скважность (Fast PWM и Phase Correct PWM).