Генератор сигналов на avr с дисплеем. Функциональный генератор НЧ сигналов на основе DDS с применением контроллера AVR ATMega16

Максимальная частота - 65534 Гц (и до 8 МГц HS выход с меандром). И тут я подумал, что генератор - отличная задача, где ПЛИС сможет показать себя в лучшем виде. В качестве спортивного интереса я решил повторить проект на ПЛИС, при этом по срокам уложиться в два выходных дня, а параметры получить не строго определенные, а максимально возможные. Что из этого получилось, можно узнать под катом

День нулевой

До того, как наступят выходные, у меня было немного времени подумать над реализацией. Чтобы упростить себе задачу, решил сделать генератор не в виде отдельного устройства с кнопками и LCD экраном, а в виде устройства, которое подключается к ПК через USB. Для этого у меня есть плата USB2RS232 . Плата драйверов не требует (CDC), поэтому, я думаю, что и под Linux будет работать (для кого-то это важно). Так же, не буду скрывать, что с приемом сообщений по RS232 я уже работал. Модули для работы с RS232 буду брать готовые c opencores.com .

Для генерации синусоидального сигнала потребуется ЦАП. Тип ЦАП я выбрал, как и в исходном проекте - R2R на 8 бит. Он позволит работать на высоких частотах, порядка мегагерц. Убежден, что ПЛИС с этим должна справиться

По поводу того, на чем написать программу для передачи данных через COM порт я задумался. С одной стороны, можно написать на Delphi7, опыт написания такой программы уже есть, к тому же размер исполняемого файла будет не большим. Еще попробовал набросать что-то для работы с Serial в виде java скрипта в html страничке, но более менее заработало только через Chrome serial API, но для этого надо устанавливать плагин… в общем тоже отпадает. В качестве новшества для себя попробовал PyQt5, но при распространении такого проекта, нужно тащить кучу библиотек. Попробовав собрать PyQt проект в exe файл, получилось больше 10 мб. То есть, будет ничем не лучше приложения, написанного на c++\Qt5. Стоит еще учесть, что опыта разработки на python у меня нет, а вот на Qt5 - есть. Поэтому выбор пал на Qt5. С пятой версии там появился модуль для работы с serial и я с ним уже работал. А еще приложение на Qt5 может быть перенесено на Linux и Mac (для кого-то это важно), а с 5.2 версии, приложения на QWidgets может быть перенесено даже на смартфон!

Что еще нужно? Естественно плата с ПЛИС. У меня их две (Cyclone iv EP4CE10E22C8N на 10 тыс. ячеек, и Cyclone ii EP2C5 на 5 тыс. ячеек). Я выберу ту, что слева, исключительно по причине более удобного разъема. В плане объема проект не предполагает быть большим, поэтому уместится в любую из двух. По скорости работы они не отличаются. Обе платы имеют «на борту» генераторы 50 МГц, а внутри ПЛИС есть PLL , с помощью которого я смогу увеличить частоту до запланированных 200 МГц.

День первый

В связи с тем, что модуль DDS я уже делал в своем синтезаторном проекте, то я сразу взялся за паяльник и начал паять ЦАП на резисторах. Плату взял макетную. Монтаж делал с применением накрутки . Единственное изменение, которое коснулось технологии - я отказался от кислоты Ф38Н для лужения стоек в пользу индикаторного флюс-геля ТТ . Суть технологии проста: в печатную плату впаиваю стойки, на них со стороны печатного монтажа припаиваю резисторы. Недостающие соединения выполняю накруткой. Еще, стойки удобны тем, что я их могу вставить прямо в плату ПЛИС.

К сожалению, дома в наличии не оказалось резисторов 1 и 2 килоома. Ехать в магазин было некогда. Пришлось поступиться одним из своих правил, и выпаять резисторы из старой не нужной платы. Там применялись резисторы 15К и 30К. Получился вот такой франкенштейн:


После создания проекта нужно задать целевое устройство: Меню Assigments -> Device


В проекте я «нахадркодил» неуправляемый главный модуль DDS на фиксированную частоту.

Модуль генератора на 1000 Гц

module signal_generator(clk50M, signal_out); input wire clk50M; output wire signal_out; wire clk200M; osc osc_200M reg accumulator; assign signal_out = accumulator; //пробуем генерировать 1000 Гц //50 000 000 Hz - тактовая частота внешнего генератора //2^32 = 4 294 967 296 - разрядность DDS - 32 бита //делим 1000Hz / 50 000 000 Hz / 2 * 4294967296 => 42949,67296 always @(posedge clk50M) begin accumulator <= accumulator + 32"d42949; end endmodule


После этого нажал «Start Compilation», чтобы среда разработки задалась вопросом, какие у нас линии ввода вывода есть в главном модуле проекта и к каким физическим PIN"s они подключены. Подключить можно практически к любому. После компиляции назначаем появившиеся линии к реальным PIN микросхемы ПЛИС:

Пункт меню Assigments -> Pin Planner

На линии HS_OUT, key0 и key1 прошу пока не обращать внимание, они появляются в проекте потом, но скрин в самом начале я сделать не успел.

В принципе, достаточно «прописать» только PIN_nn в столбце Location, а остальные параметры (I/O standart, Current Strench и Slew Rate) можно оставить по умолчанию, либо выбрать такие же, что предлагаются по умолчанию (default), чтобы не было warning"ов.

Как узнать какому PIN соответствует номер разъема на плате?

Номера контактов разъема подписаны на плате


А пины ПЛИС, к которым подключены контакты разъема, описаны в документации, которая идет в комплекте с платой ПЛИС.




После того, как пины назначены, компилирую проект еще раз и прошиваю с помощью USB программатора. Если у вас не установлены драйверы для программатора USB Byte blaster, то укажите Windows, что они находятся в папке, куда у вас установлен Quartus. Дальше она сама найдет.

Подключать программатор нужно к разъему JTAG. А пункт меню для программирования «Tools -> Programmer» (либо нажать значек на панели инструментов). Кнопка «Start», радостное «Success» и прошивка уже внутри ПЛИС и уже работает. Только не выключайте ПЛИС, а то она все забудет.

Tools -> Programmer


ЦАП подключен к разъему платы ПЛИС. К выходу ЦАП подключаю осциллограф С1-112А. В результате должна получиться «пила» потому что на выход 8 бит выводится старшая часть слова DDS аккумулятора фазы. А оно всегда увеличивается, пока не переполнится.

Каких-то 1.5 часа и для частоты в 1000 Гц я вижу следующую осциллограмму:

Хочу заметить, что «пила» по середине имеет небольшой перелом. Он связан с тем, что резисторы имеют разброс значений.

Еще один важный момент, который нужно было выяснить - это максимально возможная частота, с которой будет работать DDS генератор. При правильно настроенных параметрах TimeQuest, после компиляции в «Compilation Report» можно увидеть, что скорость работы схемы выше 200 МГц с запасом. А это значит, что частоту генератора 50 МГц я буду умножать с помощью PLL на 4. Увеличивать значение аккумулятора фазы DDS буду с частотой 200 МГц. Итоговый диапазон частот, который можно получить в наших условиях 0 - 100 МГц. Точность установки частоты:

200 000 000 Гц (clk) / 2^32 (DDS) = 0,047 Гц
То есть, это лучше, чем ~0.05 Гц. Точность в доли герца для генератора с таким диапазоном рабочих частот (0...100 МГц) считаю достаточной. Если кому-то потребуется повысить точность, то для этого можно увеличить разрядность DDS (при этом не забыть проверить TimeQuest Timing Analyzer, что скорость работы логической схемы укладывалась в CLK=200 МГц, ведь это сумматор), либо просто снизить тактовую частоту, если такой широкий диапазон частот не требуется.

TimeQuest Timing Analyzer


После того, как я увидел на экране «пилу», семейные дела заставили меня ехать на дачу (выходной же). Там я косил, варил, жарил шашлык и не подозревал о том сюрпризе, что ждал меня вечером. Уже ближе к ночи, перед сном, я решил посмотреть форму сигнала для других частот.

Для частоты 100 КГц

Для частоты 250 КГц

Для частоты 500 КГц

Для частоты 1 МГц

День второй

В связи с тем, что было интересно, как будет работать ЦАП на резисторах 100 и 200 Ом, я сразу взялся за паяльник. На этот раз ЦАП получился более аккуратным, а времени на его монтаж ушло меньше.

Ставим ЦАП на плату ПЛИС и подключаем к осциллографу

Проверяем 1 МГц - ВО! Совсем другое дело!

Пила 10 МГц

Пила 25 МГц


Форма пилы на 10 МГц еще похожа на правильную. Но на 25 МГц она уже совсем «не красивая». Однако, у С1-112а полоса пропускания - 10 МГц, так что в данном случае причина может быть уже в осциллографе.

В принципе, на этом вопрос с ЦАП можно считать закрытым. Теперь снимем осциллограммы высокоскоростного выхода. Для этого, выведем старший бит на отдельный PIN ПЛИС. Данные для этой линии будем брать со старшего бита аккумулятора DDS.

Assign hs_out = accumulator;

Меандр 1 МГц

Меандр 5 МГц

Меандр 25 МГц

Меандр 50 МГц уже практически не виден


Но считаю, что выход ПЛИС стоило бы нагрузить на сопротивление. Возможно, фронты были бы круче.

Синус делается по таблице. Размер таблицы 256 значений по 8 бит. Можно было бы взять и больше, но у меня уже был готовый mif файл. С помощью мастера создаем элемент ROM с данными таблицы синуса из mif-файла.

Создание ROM - Tools -> Mega Wizard Plugin manager


Выбираем 1 портовую ROM и задаем название модулю

Соглашаемся

Тут тоже соглашаемся

С помощью browse находим наш mif файл с таблицей синуса

Тут тоже ничего не меняем

Снимаем галочку с модуля sine_rom_bb.v - он не нужен. Дальше finish. Квартус спросит добавить модуль в проект - соглашаемся. После этого, модуль можно использовать так же, как любой другой модуль в Verilog.


Старшие 8 бит слова аккумулятора DDS будут использоваться в качестве адреса ROM, а выход данных - значение синуса.

Код

//sine rom wire sine_out; sine_rom sine1(.clock(clk200M), .address(accumulator), .q(sine_out));


Осциллограмма синуса на разных частотах выглядит… одинаково.

При желании, можно рассмотреть проблемы ЦАП, связанные с разбросом резисторов:

Чтож, на этом выходные кончились. А ведь еще не написано ПО для управления с ПК. Вынужден констатировать факт, что в запланированные сроки я не уложился.

День третий

Времени совсем мало, поэтому программу пишем на скорую руку (в лучших традициях). Местами, чтобы сократить количество букв и удобство ввода информации с клавиатуры, применяется фильтр событий по имени виджета. Прошу понять и простить.

Интерфейс

Ссылки с аналогами

Далеко не полный список
Функциональный DDS генератор. Создан базе AVR. Частоты 0… 65534 Гц.
Обзор DDS-генератора GK101. Создан с применением ПЛИС Altera MAX240. Частоты до 10 МГц.
Многофункциональный генератор на PIC16F870. Частотный диапазон: 11 Гц - 60 кГц.
генераторы Добавить метки

DDS генератор, или генератор Прямого Цифрового Синтеза в настоящее время уже далеко не новинка. На просторах интернета представлено большое количество схем, преимущественно на микроконтроллерах AVR. В качестве ЦАП-а в основном выступает R-2R матрица, но присутствуют конструкции и на микросхеме AD9850 (к слову, низкой стоимостью они не отличаются). Но к сожалению (или у счастью?), в них не было нужного мне: небольшие размеры и низкая стоимость. Как итог, была разработана данная схема.

В данной статье я хочу представить DDS генератор, выполненный на микроконтроллере ATmega8. Для отображения информации используется графический LCD LPH8731-3C. Данное устройство позволяет получить периодичный сигнал с произвольной формой (разрешение 100 точек) и заданной амплитудой.

Технические характеристики:

  • Напряжение питания: 5В
  • Потребляемый ток: <100мА
  • Мин. выходное напряжение: 0.5В
  • Макс. выходное напряжение: 2,5В
  • Шаг установки напряжения: 0,5В
  • Мин. частота сигнала: 10Гц
  • Макс. частота сигнала: 2кГц (10кГц)
  • Шаг установки частоты: 10Гц (100Гц)
  • Количество предустановленных сигналов: 8
  • Отображение данных: графический ЖКИ
  • Возможность добавления формы сигнала "на ходу" (без перепрошивки): отсутствует
  • Яркость подсветки: регулируется, необходима перепрошивка
  • Макс. количество форм в памяти: не менее 20

Схема устройства представлена ниже:

Основа схемы, как уже упоминалось, микроконтроллер ATmega8-16AU. Индекс "...16" необходим, так как в схеме применен кварцевый резонатор на 16МГц. ЦАП выполнен на R-2R матрице. Данный ход позволяет избежать применения специальных микросхем, но к сожалению, не позволяет добиться реального разрешения ЦАП выше 10 .. 12бит (в любительских условиях). К выходу матрицы через резистивный делитель напряжения (R17, RV1) подключен операционный усилитель, включенный по схеме повторителя и служит для усиления тока.

Управление устройством осуществляется посредством кнопок. На переднюю панель целесообразно выносить только кнопки SB1-SB4. Кнопка SB5 играет роль "функциональной", и позволяет использовать отличные от "основных" действия для кнопок SB1-SB4. Переключатель SA1 включает/выключает "генерацию" и кнопки управления соответственно. В первом его положении включено управление и отключено генерирование сигнала, а в другом ситуация диаметрально противоположна первому. Разъем J2 можно не разводить на плате, так как он предназначен лишь для подачи на плату питания на время программирования микроконтроллера (но придется цепляться напрямую к дорожкам).

Печатная плата устройства выполнена на двухстороннем фольгированном материале и имеет размеры (_ х _). Основная сложность при ее изготовлении - разводка дорожек для посадки микроконтроллера, но если у вас есть опыт изготовления подобных плат и/или возможность использовать фоторезист/ЛУТ, то проблем при изготовлении быть не должно.

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

Прошивка

Прошивка для микроконтроллера была написана в . Для заливки.hex файла использовался программатор и софт . Скриншот с примером выставления fuse-битов представлен ниже. Так как на печатной плате специальный разъем для программирования не предусматривался, то для прошивки микроконтроллера придется временно припаяться к соответствующим дорожкам (пины микроконтроллера "MISO", "MOSI", "SCK", "RESET").

Сборка и компоновка устройства

При помещении устройства в корпус, желательно установить кнопку SB5 на боковой его грани. Выключатель SA1 в моем варианте находился на нижнем торце, как и разъем для подключения нагрузки. Разъем USB установлен в верхней части корпуса потому, что в планах было использование DC-DC преобразователя 3.7 -> 5В. Но так как хотелось универсальности, решил сделать этот блок съемным.

Возможная замена элементов

Микроконтроллер можно использовать только ATmega8-16AU. Операционный усилитель LM358 аналогичным (к примеру, NE532, OP04, OP221, OP290, ...) в корпусе SO-8, и про возможное несоответствие выводов забывать не стоит. Транзистор Q1 можно взять любой маломощный n-p-n, к примеру отечественный КТ315 или КТ3102. Резисторы R1-R16 желательно брать с минимальный допуском (0,5...1%), но пойдут и более распространенные 2...5% (но тут форма сигнала может быть немного хуже). Причем, желательно взять резисторы одного номинала (пусть будет 10кОм), и потом там где требуется 2R ставить 10кОм, а где R - 2х10кОм параллельно. Конденсаторы C1, C2 желательно брать в диапазоне 22...33пФ. Кварцевый резонатор использован низкопрофильный, на частоту 16МГц. Резистор RV1 - многооборотный. Стабилитрон можно ставить только на 3.3В.

LCD дисплей можно использовать только с желтой подложкой и надписью "LPH8731-3C". Он встречается в мобильных телефонах Siemens A60, A65 и др. и имеет разрешение 101x80 пикселей.

Настройка

Правильно собранное устройство в наладке не нуждается, и должно работать сразу после сборки и прошивки контроллера. Если этого не произошло, то проверьте на короткое дорожки на печатной плате, правильность подключения LCD дисплея, целостность проводов от переключателя SA1 а так же исправность стабилитрона и источника питания/кабеля USB.

При успешном первом включении, необходимо с помощью осциллографа и подстроечного резистора RV1 настроить уровень выходного сигнала согласно установкам на дисплее.

Назначение кнопок: SB1 - "Влево" (Вых. напряжение меньше), SB2 - "Вправо" (Вых. напряжение больше), SB3 - "Частота +10" (Частота +100), SB4 - "Частота -10" (Частота -100) <-- SB5 - Отжата (Нажата).

Фото и видео устройства:


На двух фото ниже видно, как можно получить большую частоту, нежели 2кГц. Но приходится качеством сигнала (для прямоугольных не принципиально).



Осциллограммы сигналов, полученных с помощью данного устройства:





Внешний вид собранного устройства:


Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
U1 МК AVR 8-бит

ATmega8A-AU

1 В блокнот
U2 Операционный усилитель

LM358

1 Корпус SO-8 (LM358D)) В блокнот
Q1 Биполярный транзистор

BC547

1 В блокнот
D1 Стабилитрон

BZX55C3V3

1 В блокнот
RV1 Подстроечный резистор 220 кОм 1 В блокнот
R1-R9 Резистор

2.2 кОм

9 0805, 1% В блокнот
R10-R16, R32 Резистор

1.1 кОм

8 0805, 1% В блокнот
R17 Резистор

100 кОм

1 0805 В блокнот
R19-R23 Резистор

5.6 кОм

5 0805 В блокнот
R24-28, R18 Резистор

10 кОм

5 0805 В блокнот
R29, R30 Резистор

220 Ом

2 0805 В блокнот
R31 Резистор

75 Ом

1 0805 В блокнот
R33 Резистор

510 Ом

1 0805 В блокнот
C1, C2 Конденсатор 27 пФ 2 0805

Максимальная частота - 65534 Гц (и до 8 МГц HS выход с меандром). И тут я подумал, что генератор - отличная задача, где ПЛИС сможет показать себя в лучшем виде. В качестве спортивного интереса я решил повторить проект на ПЛИС, при этом по срокам уложиться в два выходных дня, а параметры получить не строго определенные, а максимально возможные. Что из этого получилось, можно узнать под катом

День нулевой

До того, как наступят выходные, у меня было немного времени подумать над реализацией. Чтобы упростить себе задачу, решил сделать генератор не в виде отдельного устройства с кнопками и LCD экраном, а в виде устройства, которое подключается к ПК через USB. Для этого у меня есть плата USB2RS232 . Плата драйверов не требует (CDC), поэтому, я думаю, что и под Linux будет работать (для кого-то это важно). Так же, не буду скрывать, что с приемом сообщений по RS232 я уже работал. Модули для работы с RS232 буду брать готовые c opencores.com .

Для генерации синусоидального сигнала потребуется ЦАП. Тип ЦАП я выбрал, как и в исходном проекте - R2R на 8 бит. Он позволит работать на высоких частотах, порядка мегагерц. Убежден, что ПЛИС с этим должна справиться

По поводу того, на чем написать программу для передачи данных через COM порт я задумался. С одной стороны, можно написать на Delphi7, опыт написания такой программы уже есть, к тому же размер исполняемого файла будет не большим. Еще попробовал набросать что-то для работы с Serial в виде java скрипта в html страничке, но более менее заработало только через Chrome serial API, но для этого надо устанавливать плагин… в общем тоже отпадает. В качестве новшества для себя попробовал PyQt5, но при распространении такого проекта, нужно тащить кучу библиотек. Попробовав собрать PyQt проект в exe файл, получилось больше 10 мб. То есть, будет ничем не лучше приложения, написанного на c++\Qt5. Стоит еще учесть, что опыта разработки на python у меня нет, а вот на Qt5 - есть. Поэтому выбор пал на Qt5. С пятой версии там появился модуль для работы с serial и я с ним уже работал. А еще приложение на Qt5 может быть перенесено на Linux и Mac (для кого-то это важно), а с 5.2 версии, приложения на QWidgets может быть перенесено даже на смартфон!

Что еще нужно? Естественно плата с ПЛИС. У меня их две (Cyclone iv EP4CE10E22C8N на 10 тыс. ячеек, и Cyclone ii EP2C5 на 5 тыс. ячеек). Я выберу ту, что слева, исключительно по причине более удобного разъема. В плане объема проект не предполагает быть большим, поэтому уместится в любую из двух. По скорости работы они не отличаются. Обе платы имеют «на борту» генераторы 50 МГц, а внутри ПЛИС есть PLL , с помощью которого я смогу увеличить частоту до запланированных 200 МГц.

День первый

В связи с тем, что модуль DDS я уже делал в своем синтезаторном проекте, то я сразу взялся за паяльник и начал паять ЦАП на резисторах. Плату взял макетную. Монтаж делал с применением . Единственное изменение, которое коснулось технологии - я отказался от кислоты Ф38Н для лужения стоек в пользу индикаторного флюс-геля ТТ . Суть технологии проста: в печатную плату впаиваю стойки, на них со стороны печатного монтажа припаиваю резисторы. Недостающие соединения выполняю накруткой. Еще, стойки удобны тем, что я их могу вставить прямо в плату ПЛИС.

К сожалению, дома в наличии не оказалось резисторов 1 и 2 килоома. Ехать в магазин было некогда. Пришлось поступиться одним из своих правил, и выпаять резисторы из старой не нужной платы. Там применялись резисторы 15К и 30К. Получился вот такой франкенштейн:


После создания проекта нужно задать целевое устройство: Меню Assigments -> Device


В проекте я «нахадркодил» неуправляемый главный модуль DDS на фиксированную частоту.

Модуль генератора на 1000 Гц

module signal_generator(clk50M, signal_out); input wire clk50M; output wire signal_out; wire clk200M; osc osc_200M reg accumulator; assign signal_out = accumulator; //пробуем генерировать 1000 Гц //50 000 000 Hz - тактовая частота внешнего генератора //2^32 = 4 294 967 296 - разрядность DDS - 32 бита //делим 1000Hz / 50 000 000 Hz / 2 * 4294967296 => 42949,67296 always @(posedge clk50M) begin accumulator <= accumulator + 32"d42949; end endmodule


После этого нажал «Start Compilation», чтобы среда разработки задалась вопросом, какие у нас линии ввода вывода есть в главном модуле проекта и к каким физическим PIN"s они подключены. Подключить можно практически к любому. После компиляции назначаем появившиеся линии к реальным PIN микросхемы ПЛИС:

Пункт меню Assigments -> Pin Planner

На линии HS_OUT, key0 и key1 прошу пока не обращать внимание, они появляются в проекте потом, но скрин в самом начале я сделать не успел.

В принципе, достаточно «прописать» только PIN_nn в столбце Location, а остальные параметры (I/O standart, Current Strench и Slew Rate) можно оставить по умолчанию, либо выбрать такие же, что предлагаются по умолчанию (default), чтобы не было warning"ов.

Как узнать какому PIN соответствует номер разъема на плате?

Номера контактов разъема подписаны на плате


А пины ПЛИС, к которым подключены контакты разъема, описаны в документации, которая идет в комплекте с платой ПЛИС.




После того, как пины назначены, компилирую проект еще раз и прошиваю с помощью USB программатора. Если у вас не установлены драйверы для программатора USB Byte blaster, то укажите Windows, что они находятся в папке, куда у вас установлен Quartus. Дальше она сама найдет.

Подключать программатор нужно к разъему JTAG. А пункт меню для программирования «Tools -> Programmer» (либо нажать значек на панели инструментов). Кнопка «Start», радостное «Success» и прошивка уже внутри ПЛИС и уже работает. Только не выключайте ПЛИС, а то она все забудет.

Tools -> Programmer


ЦАП подключен к разъему платы ПЛИС. К выходу ЦАП подключаю осциллограф С1-112А. В результате должна получиться «пила» потому что на выход 8 бит выводится старшая часть слова DDS аккумулятора фазы. А оно всегда увеличивается, пока не переполнится.

Каких-то 1.5 часа и для частоты в 1000 Гц я вижу следующую осциллограмму:

Хочу заметить, что «пила» по середине имеет небольшой перелом. Он связан с тем, что резисторы имеют разброс значений.

Еще один важный момент, который нужно было выяснить - это максимально возможная частота, с которой будет работать DDS генератор. При правильно настроенных параметрах TimeQuest, после компиляции в «Compilation Report» можно увидеть, что скорость работы схемы выше 200 МГц с запасом. А это значит, что частоту генератора 50 МГц я буду умножать с помощью PLL на 4. Увеличивать значение аккумулятора фазы DDS буду с частотой 200 МГц. Итоговый диапазон частот, который можно получить в наших условиях 0 - 100 МГц. Точность установки частоты:

200 000 000 Гц (clk) / 2^32 (DDS) = 0,047 Гц
То есть, это лучше, чем ~0.05 Гц. Точность в доли герца для генератора с таким диапазоном рабочих частот (0...100 МГц) считаю достаточной. Если кому-то потребуется повысить точность, то для этого можно увеличить разрядность DDS (при этом не забыть проверить TimeQuest Timing Analyzer, что скорость работы логической схемы укладывалась в CLK=200 МГц, ведь это сумматор), либо просто снизить тактовую частоту, если такой широкий диапазон частот не требуется.

TimeQuest Timing Analyzer


После того, как я увидел на экране «пилу», семейные дела заставили меня ехать на дачу (выходной же). Там я косил, варил, жарил шашлык и не подозревал о том сюрпризе, что ждал меня вечером. Уже ближе к ночи, перед сном, я решил посмотреть форму сигнала для других частот.

Для частоты 100 КГц

Для частоты 250 КГц

Для частоты 500 КГц

Для частоты 1 МГц

День второй

В связи с тем, что было интересно, как будет работать ЦАП на резисторах 100 и 200 Ом, я сразу взялся за паяльник. На этот раз ЦАП получился более аккуратным, а времени на его монтаж ушло меньше.

Ставим ЦАП на плату ПЛИС и подключаем к осциллографу

Проверяем 1 МГц - ВО! Совсем другое дело!

Пила 10 МГц

Пила 25 МГц


Форма пилы на 10 МГц еще похожа на правильную. Но на 25 МГц она уже совсем «не красивая». Однако, у С1-112а полоса пропускания - 10 МГц, так что в данном случае причина может быть уже в осциллографе.

В принципе, на этом вопрос с ЦАП можно считать закрытым. Теперь снимем осциллограммы высокоскоростного выхода. Для этого, выведем старший бит на отдельный PIN ПЛИС. Данные для этой линии будем брать со старшего бита аккумулятора DDS.

Assign hs_out = accumulator;

Меандр 1 МГц

Меандр 5 МГц

Меандр 25 МГц

Меандр 50 МГц уже практически не виден


Но считаю, что выход ПЛИС стоило бы нагрузить на сопротивление. Возможно, фронты были бы круче.

Синус делается по таблице. Размер таблицы 256 значений по 8 бит. Можно было бы взять и больше, но у меня уже был готовый mif файл. С помощью мастера создаем элемент ROM с данными таблицы синуса из mif-файла.

Создание ROM - Tools -> Mega Wizard Plugin manager


Выбираем 1 портовую ROM и задаем название модулю

Соглашаемся

Тут тоже соглашаемся

С помощью browse находим наш mif файл с таблицей синуса

Тут тоже ничего не меняем

Снимаем галочку с модуля sine_rom_bb.v - он не нужен. Дальше finish. Квартус спросит добавить модуль в проект - соглашаемся. После этого, модуль можно использовать так же, как любой другой модуль в Verilog.


Старшие 8 бит слова аккумулятора DDS будут использоваться в качестве адреса ROM, а выход данных - значение синуса.

Код

//sine rom wire sine_out; sine_rom sine1(.clock(clk200M), .address(accumulator), .q(sine_out));


Осциллограмма синуса на разных частотах выглядит… одинаково.

При желании, можно рассмотреть проблемы ЦАП, связанные с разбросом резисторов:

Чтож, на этом выходные кончились. А ведь еще не написано ПО для управления с ПК. Вынужден констатировать факт, что в запланированные сроки я не уложился.

День третий

Времени совсем мало, поэтому программу пишем на скорую руку (в лучших традициях). Местами, чтобы сократить количество букв и удобство ввода информации с клавиатуры, применяется фильтр событий по имени виджета. Прошу понять и простить.

Интерфейс

Ссылки с аналогами

Далеко не полный список
Функциональный DDS генератор. Создан базе AVR. Частоты 0… 65534 Гц.
Обзор DDS-генератора GK101. Создан с применением ПЛИС Altera MAX240. Частоты до 10 МГц.
Многофункциональный генератор на PIC16F870. Частотный диапазон: 11 Гц - 60 кГц.
генераторы
  • Qt5
  • Добавить метки

    В последнее время получили широкое распространение методы цифрового синтеза частоты(DDS), причем методы реализации очень многообразны. Способ и метод реализации зависит от требований к генератору.

      У меня к генератору были основные требования:
    • 1. Частота в диапазоне от 0.01Гц – 50000Гц с шагом 0.01Гц
    • 2. Максимальная, по возможности, линейность на протяжении всего диапазона.
    • 3. Работа на низкоомную нагрузку(для проверки динамиков и УЗ магнитострикционных излучателей)
    • 4. Удобство и быстрота перестройки «на горячую».
    • 5. Сканирование заданного диапазона с заданным шагом (удобно для определения частоты резонанса чего угодно)
    • 6. Большое количество форм сигналов, и постоянное напряжение для калибровки.
    • 7. Информативность отображения.
    Поскольку я часто сталкивался с написанием программ на контроллеры AVR и Microchip – я выбирал между ними… Но дешевле и функциональнее оказался AVR. По быстродействию и нужному количеству выводов подошел ATMega16. Теперь о расчетах…
    F max = 16000000Hz(Частота атмеги)
    15 циклов берем на изменение аккумулятора фазы, выборку из LUT и вывод.
    Итого Fclk=16000000Hz/15=1066666,6667Hz
    Для необходимой точности выбрал 32-битный аккумулятор фазы.
    Теперь вычислим минимальный шаг:
    Step(Hz)= 1066666,6667Hz/(2^32)= 0,0002483526865641276041667(Hz)
    Код самого генератора:
    while (1){ #asm ADD R1,R6 ADC R2,R7 ADC R3,R8 ADC R4,R9 #endasm PORTC=LUT_of_Signal;
    При 50000Гц сигнал за период будет образовываться ~21 сменой напряжений на выходе ЦАПа.
    В качестве ЦАП я выбрал обычную R-2R матрицу – она не требует стробов и 8 бит вполне удовлетворяют условиям. Т.е. (|12|+|-12|) / 2^8 = 0,09375~ 0,1V

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

    Чтобы предотвратить ложные срабатывания от валкодера – контроллер несколько раз проверяет направления при шагах и только тогда фиксирует изменения.
    Остальные параметры задаются 4-мя кнопками.

      Генератор имеет возможность воспроизводить следующие формы сигналов:
    • 1. Синусоида
    • 2. Меандр
    • 3. H-wave
    • 4. Лестница симметричная
    • 5. Трапеция
    • 6. Пила
    • 7. Прямоугольник симметричный
    • 8. Лестница асимметричная
    • 9. Прямоугольник асимметричный
    • 10. Постоянный "+"
    • 11. Постоянный "-"
    Видео с работой
    Так же добавил функцию сканирования заданного диапазона частот с регулируемым шагом.
    Шаг устанавливается 0,01Гц-0.1Гц-1Гц-10Гц-100Гц и обратно. Для удобства отображения и простоты написания программы использовал LCD от Nokia 3310(84x48). В качестве самого валкодера использовал биполярный шаговый двигатель от старого винчестера. Все устройство и программу просимулировал в Proteus.
    Аналоговая часть генератора


    Поскольку ЦАП выдает сигнал однополярный а задумка была зделать именно двухполярный генератор то необходимо использовать смещение на усилителе. В качестве источника опорного напряжения я выбрал TL431. Сам усилитель я реализовал на 2-х каскадах. Для усиления нагрузочной способности я применил повторитель напряжения на микросхеме TDA2030A.

    Сигнал на выходе устройства U3 повторяет по форме и амплитуде входной, но имеет большую мощность, т.е. схема может работать на низкоомную нагрузку. Повторитель использован для увеличения выходной мощности низкочастотного генератора (чтобы можно было непосредственно испытывать головки громкоговорителей или акустические системы). Полоса рабочих частот повторителя линейна от постоянного тока до 0,5...1 МГц, что более чем достаточно для генератора НЧ.

    Источник питания - любой(импульсный или линейный), желательно стабилизированный с питаниями +5,+12/-12V.

    О сборке
    При сборке проблем особых не возникло, настройка заключается в подстройке аналоговой части симметричности и амплитуды выходного сигнала. Смещение настраивается резистором R1 и R6.Амплитуда первого каскада R5, второго R8.

    Сегодня на обзоре конструктор генератора DDS (Direct Digital Synthesizers, прямой цифровой синтез - метод получения сигнала напрямую с выхода ЦАП по заранее указанной функции или таблице значений). с китайского магазина. Особо много технической документации нарыть не удалось. Внизу статьи прикреплен файлик с оригинальным описанием.

    Характеристики от производителя:

    • простая схема;
    • ВЧ выход до 8 МГц;
    • регулируемая амплитуда и постоянная составляющая на выходе синтезатора;
    • синтезируемые формы: синус, треугольник, прямая и обратная пила, ЭКГ, шум;
    • меню на дисплее 16х2;
    • простая клавиатура из 5 кнопок;
    • шаг регулировки частоты 1Гц - 10кГц
    • хранение последних настроек энергонезависимо;
    • диапазон частот синтезатор 1Гц - 65535Гц;
    • постоянная составляющая -5В..+5В;
    • амплитуда до 10В.

    Конструктор пришел вот в таком пакете

    Вот что внутри

    Никакой инструкции не наблюдалось, но, как и обещали, интуитивно всё понятно. Как видно, на плате всё сразу подписано номиналами. Плата, кстати, сделана весьма неплохо.

    Можно начинать сборку. Традиционно первыми ставим резисторы. Их номиналы либо проверяем мультиметром, либо выясняем по кольцам. Вот так это выглядит у меня, поставлены резисторы 10к и 20к:

    Ставлю не все сразу, чтобы лес выводов внизу не мешал. Вот так установлены и впаяны все резисторы:

    Теперь поставим переменный резистор. Он необходим для подстройки контрастности экрана. Заодно вставил кварц.

    Теперь установим разъем для дисплейного модуля. Тут надо обратить внимание на 2 момента - разъём при пайке не перегрейте (чтобы не поплавить корпус) и поставить надо как можно более вертикально. У меня получилось вот так.

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

    Разъём питания. Устройству требуется, как видим 3 напряжения: +12, -12, +5 (В). +5В нужен для работы проца и дисплея, +/-12 для выходного усилителя.

    ,

    Теперь два подстроечных резистора. Будьте внимательны: несмотря на одинаковые корпуса резисторы имеют разные номиналы - 50кОм для регулировки амплитуды и 1кОм для регулировки постоянной составляющей.

    Из пайки остались только панельки под микросхемы. Какая для чего - перепутать сложно. Снова не рекомендую перегревать. Обращайте внимание на положение ключа на маркировке и на панельке.

    Ставим в панельке две микросхемы. Внимательно следите, чтобы ключ стоял в соответствии с маркировкой. При установке восьминогой LM358 обязательно убедитесь в правильном положении ключа; неправильное положение на 80% приведет к отказу микросхемы. При установке микроконтроллера следите за тем, чтобы все ноги попадали в панельку, при необходимости осторожно подогните выводы. Также я привинтил стойки к плате в средние отверстия для закрепления дисплея.

    Осталось установить в разъем дисплей и привинтить к стойкам. В принципе устройство собрано. Вот окончательный вид

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

    Настраиваем контрастность

    При правильно настроенной контрастности символы чётко должны быть видны на дисплее

    Начнём тестирование. В первую очередь снимем сигнал с правого разъёма DDS

    Кнопками UP и DOWN выбирается форма сигнала, LEFT и RIGHT меняем частоту, центральная кнопка включает/выключает генерацию.

    Сразу видим, что после 10 кГц синуса уже далеко нет. После 30 кГц падает амплитуда. На частотах ниже 10 кГц синус хороший, частота стабильна, ступенек нет.

    Теперь смотрим прямоугольный сигнал, частоты 1, 5, 10 кГц

    На частотах выше 10 кГц даже проверять не стану - думаю уже все понятно.

    Теперь треугольный сигнал, частоты 1, 5, 10, 30, 65,5 кГц.

     

    Возможно, будет полезно почитать: