DDS генератор на AD9833
Автор: grott
Опубликовано 04.11.2016
Создано при помощи КотоРед.
Функциональный генератор в хозяйстве радиолюбителя прибор ниже рангом осциллографа и мультиметра, но так же необходим. Простой генератор на мосте Вина у меня прослужил не малое время, но захотелось более продвинутое устройство. После поиска реализованных проектов выбор пал на генератор, в основе которого применён синтезатор частот AD9833. Подкупала простота с отличными характеристиками и малой ценой. Анализ уже готовых решений не удовлетворил, как всегда народ свои устройства не доделывает до конца и бросает, потеряв к нему интерес. Значит делаем генератор своими силами. Сделал, чем и делюсь с нашим сообществом.
Что может этот генератор:
-два независимых выхода аналоговый и логический;
-генерация синуса и треугольника на аналоговом выходе;
-диапазон частоты на аналоговом выходе 1 Гц — 5 МГц;
-генерация импульсов с раздельной регулировкой длительности высокого и низкого уровней на цифровом выходе;
-диапазон длительности импульсов на цифровом выходе 1 мкс — 10 сек;
-режим качания частоты с установкой пороговых частот от 1 Гц до 5 МГц;
-незавимая регулировка амплитуды для обеих выходов, 0 — 2 В для аналогового и 1.0 — 5 В для цифрового;
-автосохранение всех текущих настроек при выключении;
-выходное сопротивление на обеих выходах 50 Ом.
Цифровой выход реализован на буфере с двумя питаниями, т.е преобразователь уровня, всем известный 74LVC8T245. Регулируемый источник питания сделан на LDO (ОУ МСР6001 и IRLML6402) и управляется ШИМом с Меги. Дисплей, так называемый Nokia 3310. Управление одним энкодером. Текущие настройки сохраняются при выключении. Генератор питается от стабилизированного БП 5В.Всем рулит ATMega328P. Благодаря ардуинщикам, она стала мега популярной и дешёвой. Мега разогнана до 25 МГц и питается 3 Вольтами, что оказывается для неё вполне себе штатным режимом (работала вплоть до 1.8 В). Такой режим позволил отказаться от генератора для тактирования AD9833, такт подаём непоредственно с выхода CLKO Меги. Также можно не задумываться о согласовании уровней для 3-х вольтовой периферии.
AD9833 может синтезировать синусоиду, треугольник с амплитудой 0.6 В и меандр — с 3 В (напряжение питания). Нормализуем к выходному значению с помощью двух ОУ на AD8052, в добавок на втором ОУ реализован аттенюатор с цифровым потенциометром MCP4011. Чтобы минимизировать шумы, фильтр Баттерворта сделан пасивным. Синтезируемый меандр до 5 Мгц ключом 74НС4066 отводим на логический выход.
Возможно потребуется настройка. Настраиваем общий коэф. усиления ОУ, чтобы на выходе стало 2 В в размахе. Резисторы в обратной связи R16 и R14, только нужно следить, чтобы коэф. усиления каждого ОУ не превысил 3. Резистором R5 выравниваем меандр с синусом по амплитуде.
Прошиваем файлы .hex и .eep, потом фьюзы EXTENDED — 0xFE, HIGH — 0xDF, LOW — 0xB7.
Один из инструментов, без которого я бы пропал в своей домашней лаборатории, является функциональный генератор. Он довольно дорогой, поэтому я не купил его. Я подумал, что можно попытаться сделать его самостоятельно. Нашел довольно распространенную DDS (Direct Digital Synthesis, прямой цифровой синтез) микросхему AD9833. Теперь надо добавить только USB-совместимый AVR микроконтроллер и возможно немного аналоговых элементов.
Эта плата не обеспечивает регулировку амплитуды или смещения сигнала. Выход устанавливается 0-4В. Я планирую сделать ещё одну полностью аналоговую плату для регулировки амплитуды и смещения.
Элементы
Неотъемлемой частью этой конструкции является DDS микросхема AD9833 от Analog Devices. Микросхема имеет входной тактовый сигнал 25 МГц, внутреннюю фазовую автоподстройку частоты, таблица поиска синусов и АЦП. Контролируя её по интерфейсу SPI, вы можете получить на выходе синусоидальный, пилообразный и прямоугольный сигнал с частотным диапазоном от 0,01 Гц до 3 МГц. Частота может быть выше, до
7 МГц, но на такой высокой частоте синусоидальный сигнал выглядит ужасно.
Для управления этой микросхемой, я использовал дешевый USB-совместимый AVR микроконтроллер Atmel AT90USB162. Он будет обеспечивать виртуальный последовательный интерфейс по USB и интерпретировать команды переданные по этому интерфейсу для изменения выходного сигнала DDS надлежащим образом.
OPA357 используется для усиления выходного сигнала DDS. Номинальное напряжение на выходе AD9833 0.6Vpp, со средним значение 0.3В. OPA357 была выбрана потому, что она поддерживает необходимые высокие частоты и её можно получить в качестве бесплатного образца от компании Texas Instruments.
Схема
Схема и печатная платы были разработаны в KiCad, довольно приличном EDA (EDA, автоматизация проектирования электронных приборов) с открытым исходным кодом. Здесь приведены некоторые части схемы. Если вас интересует более подробная схема, её можно скачать ниже в формате PDF.
Устройство может питаться или от USB, или от отдельного источника +5В. Два диода Шоттки установлены, чтобы напряжения нашли друг на друга, если они поступаю из обоих входов.
Схема построена на DDS AD9833. Блокировочные конденсаторы и их номиналы взяты из даташита. Источник тактового сигнала может быть выбран при помощи JP1. Может использоваться встроенный генератор и внешний источник тактового сигнала через BNC разъем. Выход из DDS сначала проходит через ФНЧ и затем усиливается. На выходе есть резистор 50 Ом, чтобы обеспечить выходное сопротивление 50 Ом. По всему пути прохождения сигнала есть контрольные точки, что обеспечивает удобство тестирования.
Печатная плата
Разводка довольно проста. Вот скриншот платы в 3D-виде KiCad:
Вы можете видеть BNC разъем для подачи внешнего тактового сигнала на этом скриншоте, но у меня не было необходимости его припаивать.
Я разработал плату для использования генератора для поверхностного монтажа, но у меня не было генератора нужной частоты. У меня был подходящий генератор в DIP корпусе, поэтому я припаял его к плате так:
Немного некрасиво, но работает не хуже.
У меня также была небольшая ошибка в оригинальной разводке. VUSB контакт AVR должен быть подключен к источнику питания, а не к USB VUSB. В таком случае, если я питаю устройство от внешнего источника, USB периферия все равно получает питание и может инициализироваться. Перерезать дорожку и припаять перемычку достаточно, что бы исправить это. К статье прилагается исправленная версия платы.
Протокол
Плата подключена к компьютеру через виртуальный последовательный порт по USB. Должен быть стандартный способ обмена информацией, поэтому я написал простой стандарт перед тем, как я начал писать код. Я решил использовать ASCII для включения человека при написании команд во время тестирования и для облегчения отладки и читабельности кода.
sf1 [freq] #в Гц
sf2 [freq] #в Гц
sp1 [phase] #в градусах
sp2 [phase] #в градусах
sfo [1/2/m(modulation)] #frequency output
spo [1/2/m(modulation)] #phase output
so [o(off-выключен)/s(sine-синусоида)/t(triangle-треугольник)/q(square-прямоугольный сигнал)] #режим выхода
sm [freq] #частота модуляции
Все команды должны заканчиваться возвратом каретки-новой строкой.
Так например, для установки выходной частоты от 1 до 100 Гц, вы должны отправить "sf1 100
".
Программа для AVR
Функциональность USB была предоставлена отличной LUFA USB библиотекой для микроконтроллеров AVR. Я повторил код, который я написал, прежде чем обмениваться информацией по SPI и относительно функциональную библиотеку для AD9833. Потом я написал код, преобразовывающий команды, посылаемые через последовательный интерфейс в обращение к функции библиотеки AD9833.
Я получил проблему, используя Doxygen для комментирования своего кода и создания документации. Подробнее об этом можно узнать, перейдя по ссылке.
Программное обеспечение для ПК
Программное обеспечение написано на Python3. Я начал изучать его пару месяцев назад и до сих пор использую его для создания простых интерфейсов. Я использовал графическую основу tkinter для создания графического интерфейса пользователя и pyserial для последовательного соединения. Код пользовательского интерфейса не очень хорош, я ещё не совсем разобрался с Python. Это прекрасный язык, но я предпочитаю работать с микроконтроллерами и писать код на С.
Пользовательский интерфейс оказался весьма хорошим и хорошо работающим. Есть некоторые вещи, которые я хотел-бы сделать по-другому. Например, выбор модуляции выходного сигнала должен иметь собственные кнопки. Если бы я хотел добавить кнопку сдвига амплитуды, то её было бы просто некуда поставить. Возможно, я попытаюсь разместить её где то.
Работа очень проста: приложение просто посылает соответствующие команды на виртуальный последовательный порт USB, когда любое значение изменяется в пользовательском интерфейсе.
Результат
Я снял короткое видео, демонстрирующее работу функционального генератора. Кажется, он работает довольно хорошо!
Проект на github, документация для AVR-кода
воскресенье, 24 июня 2018 г.
Генератор сигналов на AD9833
AD9833 — это программируемый генератор сигналов с низким энергопотреблением. Позволяет генерировать сигналы с частотой до 12.5МГц синусоидальной, треугольной и прямоугольной формы. Программирование осуществляется с использованием трехпроводного интерфейса SPI и не составляет труда. Ниже приведены основные характеристики микросхемы:
- Цифровое программирование частоты и фазы.
- Потребляемая мощность 12.65 мВт при напряжении 3 В.
- Диапазон выходных частот от 0 МГц до 12.5 МГц.
- Разрешение 28 бит (0.1 Гц при частоте опорного сигнала 25 МГц).
- Синусоидальные, треугольные и прямоугольные выходные колебания.
- Напряжение питания от 2.3 В до 5.5 В.
- Трехпроводной интерфейс SPI.
- Расширенный температурный диапазон: от –40°C до +105°C.
- Опция пониженного энергопотребления.
Более подробную информацию вы можете найти в даташите. В характеристиках также заявлено, что микросхема не требует внешних компонентов, но здесь производитель лукавит: обвязка и источник опорной частоты все же нужны. На Али продаются модули AD9833 с необходимой обвязкой и кварцевым генератором на 25 МГц, как раз с таким модулем я и собираюсь экспериментировать. Данный модуль имеет следующие выводы:
- VCC – плюс питания для цифровых и аналоговых цепей генератора.
- DGND – цифровая земля.
- SDATA – вход данных интерфейса SPI. Передача осуществляется 16-битными словами.
- SCLK – вход тактового сигнала SPI. Используется второй режим работы: (CPOL = 1, CPHA = 0).
- FSYNC – выбор микросхемы. Перед началом передачи данных должен быть установлен в 0, по завершении в 1.
- AGND – аналоговая земля.
- OUT – выход генератора.
Попробуем подключить этот модуль к Ардуино и научиться им управлять. Для начала ознакомимся с его функциональной схемой:
AD9833 состоит из следующих основных частей: два регистра выбора частоты, аккумулятор фазы, два регистра выбора фазы и сумматор смещения фазы (вместе эти компоненты составляют генератор с цифровым управлением — NCO), SIN ROM для преобразования информации о фазе в амплитуду и 10-разрядный цифро-аналоговый преобразователь.
Из схемы видно, что данные с интерфейса SPI передаются в управляющий регистр, регистры выбора фазы и частоты. Именно они определяют сигнал на выходе генератора. И программирование генератора сводится к изменению содержимого указанных регистров.
Управляющий регистр
Это 16-разрядный регистр, управляющий работой генератора. Подробное описание его битов приведено ниже в таблице. Схема из даташита также наглядно демонстрирует их назначение:
Бит | Название | Назначение |
---|---|---|
15, 14 | DB15, DB14 | Чтобы AD9833 понял, что принятое по SPI 16-битное слово содержит новое значение для управляющего регистра, два старших бита в слове должны быть установлены в 0. |
13 | B28 | Регистры частоты AD9833 имеют разрядность 28 бит, поэтому для изменения их содержимого требуется передача двух 16-битных слов. Однако в некоторых случаях требуется изменить только старшую или младшую часть регистра частоты. Здесь и используется данный признак: B28 = 1 говорит о том, что необходимо обновить регистр частоты целиком и его новое значение будет передано двумя последовательными записями. Первая запись содержит 14 младших бит, вторая 14 старших бит. Первые два бита в обеих записях определяют регистр частоты, в который будет записано передаваемое значение и должны быть одинаковыми. Обновление регистра частоты происходит после получения полного слова, поэтому запись промежуточного значения в регистр исключена. B28 = 0 позволяет обновить отдельно старшую или младшую часть регистра. Какая именно часть будет изменена определяется управляющим битом HLB. |
12 | HLB | Бит HLB определяет, какая из частей регистра частоты (младшая или старшая) будет перезаписана. Используется при B28 = 0. При B28 = 1 значение этого бита игнорируется. HLB = 1 позволяет обновить старшие 14 бит регистра частоты; HLB = 0 позволяет обновить младшие 14 бит регистра частоты. |
11 | FSELECT | Бит FSELECT определяет, какой из регистров используется в аккумуляторе фазы – FREQ0 или FREQ1. |
10 | PSELECT | Бит PSELECT определяет, данные какого из регистров PHASE0 или PHASE1 добавляются к выходу аккумулятора фазы. |
9 | Зарезервирован | Данный бит зарезервирован и должен быть установлен в 0. |
8 | RESET | RESET = 1 сбрасывает внутренние регистры генератора в 0. Сброс не затрагивает регистры управления, частоты и фазы. |
7 | SLEEP1 | При SLEEP1 = 1 запрещается внутреннее тактирование, приостанавливается работа NCO и выход генератора остается в своем текущем состоянии. При SLEEP1 = 0 тактирование разрешено. |
6 | SLEEP12 | При SLEEP12 = 1 отключается внутренний ЦАП. Это может быть полезно для генерации прямоугольных импульсов, при которой не требуется выполнение цифро-аналоговых преобразований. При SLEEP12 = 0 внутренний ЦАП активен. |
5 | OPBITEN | Данный бит вместе с битом MODE управляют выходом генератора. При OPBITEN = 1 внутренний ЦАП отключается от выхода VOUT и для генерации выходного сигнала используется значение старшего значащего бита с входа ЦАП, что позволяет получить на выходе генератора прямоугольные импульсы. |
4 | Зарезервирован | Данный бит зарезервирован и должен быть установлен в 0. |
3 | DIV2 | Используется в паре со значением OPBITEN = 1. При DIV2 = 1 значение старшего значащего бита данных с входа ЦАП подается напрямую на выход VOUT. DIV2 = 0 позволяет задействовать делитель частоты и уменьшить частоту выходного сигнала вдвое. При OPBITEN = 0 значение данного бита игнорируется. |
2 | Зарезервирован | Данный бит зарезервирован и должен быть установлен в 0. |
1 | MODE | Данный бит вместе с битом OPBITEN управляют выходом генератора. При OPBITEN = 1 бит MODE должен быть установлен в 0. Значение MODE = 0 позволяет получить на выходе генератора синусоидальный сигнал. При MODE = 1 на выходе будет треугольный сигнал. |
Зарезервирован | Данный бит зарезервирован и должен быть установлен в 0. |
OPBITEN | MODE | DIV2 | Сигнал на выходе VOUT |
---|---|---|---|
X | Синусоидальный | ||
1 | X | Треугольный | |
1 | Прямоугольный с частотой F/2 | ||
1 | 1 | Прямоугольный с частотой F | |
1 | 1 | X | Зарезервировано |
Регистры частоты и фазы
Для того чтобы загрузить значение FREQREG в регистр частоты необходимо старшие биты передаваемого по SPI значения установить в 01 для загрузки в FREQ0 или 10 для загрузки в FREQ1. Напомню, что общение с AD9833 осуществляется по SPI 16-битными словами.
Фаза выходного сигнала определяется следующим образом:
(2π / 2 12 ) * PHASEREG
соответственно, значение для регистра фазы вычисляется по формуле:
PHASEREG = PHASE*2 12 / 2π
В приведенных формулах PHASEREG – это значение активного регистра фазы. Выбор активного регистра осуществляется установкой управляющего бита PSELECT: при PSELECT = 0 активным является PHASE0; при PSELECT = 1 активен регистр PHASE1.
При записи нового значения в регистр фазы старшие биты должны быть установлены в 11, а выбор регистра, в который должно быть записано значение, осуществляется установкой бита 13: при нулевом его значении будет обновлен регистр PHASE0; при установке указанного бита в 1 будет обновлен регистр PHASE1. 12й бит не используется, а биты с 0 по 11 содержат значение для регистра фазы.
Разрядность регистра частоты в 28 бит при опорной частоте 25МГц обеспечивает шаг 0.1Гц для установки частоты сигнала на выходе. А 12-битный регистр фазы обеспечивает разрешение 2π/4096.
Тестовая программа для AD9833 на Ардуино
С подключением все просто: общение с модулем происходит по интерфейсу SPI, для которого на Ардуино отведены следующие пины:
D10 — SS (Slave Select — выбор ведомого), к нему подключаем вывод FSYNC модуля.
D11 — MOSI (Master Out Slave In — выход ведущего, вход ведомого), к нему подключаем вывод SDATA.
D13 — SCK (Serial Clock — Тактовый сигнал), к нему подключаем вывод SCLK.
В данном скетче выполняются следующие действия:
- При первом вызове функции WriteAD9833 производится установка управляющего регистра: бит RESET устанавливается в 1 для выполнения сброса; бит DB28 устанавливается в 1 для перезаписи всего содержимого регистра частоты; биты FSELECT и PSELECT содержат 0, поэтому для генерации выходного сигнала будут использоваться регистры FREQ0 и PHASE0.
- Следующие два вызова передают значение 4295 в регистр частоты FREQ0. Данное значение умещается в 14 младших разрядах, поэтому в старшие разряды регистра записываем нули.
- Сдвиг по фазе не требуется — запишем в регистр PHASE0 значение 0
- Последним вызовом WriteAD9833 в процедуре setup снимаем бит RESET, разрешая тем самым работу генератора. Результирующий сигнал поступает на вывод VOUT.
- Следующие вызовы WriteAD9833 в функции loop обновляют содержимое управляющего регистра, перебирая комбинации битов MODE, OPBITEN и DIV2 для генерации сигнала синусоидальной, треугольной и прямоугольной форм.
Вот как выглядит выходной сигнал генератора в виртуальном осциллографе:
Синусоидальный сигнал (биты MODE и OPBITEN сброшены в 0) |
Треугольный сигнал (MODE = 1, OPBITEN = 0) |
Прямоугольный сигнал (OPBITEN = 1, MODE = 0, DIV2 = 1) |
Прямоугольный сигнал (OPBITEN = 1, MODE = 0, DIV2 = 0) |
Обратите внимание: при генерации синусоидальных и треугольных импульсов, когда сигнал снимается с выхода ЦАП, его амплитуда изменяется в диапазоне 38мВ. 0,65В. При генерации импульсов прямоугольной формы мы имеем дело с обычным цифровым сигналом с соответствующими уровнями напряжения. Так в последних двух осциллограммах логической единице соответствует напряжение
Генератор на AD9833 с дисплеем и энкодером
Ранее я писал о том, как можно сделать меню на Ардуино с энкодером вращения. И сейчас я взял такое меню за основу скетча, добавив в него функционал для работы с AD9833. Скачать скетч можно по ссылке.
При включении питания AD9833 настраивается на генерацию синусоидального сигнала частотой 100Гц, соответствующая информация отображается на дисплее. Вращая ручку энкодера можно изменять его частоту, а при нажатии вызывается меню. В меню доступны следующие опции:
- Установка частоты (можно задать произвольное значение от 1 до 12,5МГц).
- Установка фазы (0 — 360°).
- Выбор формы сигнала.
- Выбор значения, на которое изменяется частота при вращении ручки энкодера.
Остается только поместить все компоненты в подходящий корпус и получится законченное устройство. Результат работы в следующем ролике: