DDS синтезатор AD9833


Эпиграф
Понадобился мне, в мойх поделках, генератор сигналов различной формы, а именно: синус, меандр, треугольник ну и плюс постоянное напряжение (но это уже другой вопрос), да не простой а чтобы занимал мало места на плате а главное программно управляемый. После недолгого гугления наткнулся на семейство DDS синтезаторов от Analog Devices, которые все это в себе совмещают (кроме постоянного напряжения). Три из четырех очень неплохо (подумал я) и прикупил парочку.
Принципы работы DDS синтезаторов частоты
DDS — принцип не новый, а значит теории по этому вопросу в инете и не только — навалом. Лично мне хватило пары статей, чтобы «войти в курс дела». Одну из них, со скромным названием «All About Direct Digital Synthesis», можно почитать на сайте Analog Devices. Для тех кто не дружит с английским языком, есть перевод данной статьи.
Почему AD9833?
У этого DDS синтезатора есть ряд преимуществ, по сравнению со своими собратьями: низкая стоимость, малое потребление, последовательный интерфейс обмена данными (всего три проводка), простые команды и вычисления, минимальный обвес AD9833, относительно высокая точность выходного сигнала (10-битный ЦАП, 28-битный фазовый аккумулятор, который позволяет получить выходной сигнал с точностью до 0.1 Гц, при максимальном тактирующем сигнале в 25.0 МГц), отличное соотношение Сигнал/Шум без применения какой либо фильтрации ~ 60dB. Также AD9833 обладает несколькими режимами энергосбережения, что тоже не маловажно.
Описание схемы

Рис.1 Цоколевка AD9833
Как видно из цоколевки, разработчики буквально поделили AD9833 на две части: первая часть — управляющая, в которую входят линии ввода команд/данных, тактирующий и выходной сигналы, и вторая часть отвечающая за питание ИС. Поскольку я впервые имел дело с AD9833, то решил сделать отдельный подопытный модуль, плюс такой модуль обладает большой мобильностью и при желании его можно использовать в нескольких проектах, а также легко локализовать и исправить неполадки (разделяй и властвуй). На рис.2 показана схема сего модуля, в которой все управляющие линии, выходной сигнал и питание собраны в коннекторе CONN1 (этакий интерфейс), через который он будет общаться с управляющей частью.

Рис.2 Схема тестового модуля
Основные требования к модулю
Как было упомянуто раньше, AD9833 очень неприхотливая ИС и для того чтобы получить готовый выходной сигнал ей нужны буквально пара конденсаторов, тактовый генератор и операционный усилитель, поскольку необработанный выходной сигнал составляет ~0.65V (peak-to-peak), плюс небольшой оффсет ~40mV, в режимах с использованием ЦАП'a.
Тактовый генератор — в качестве источника тактового сигнала следует выбрать резонатор со встроенным генератором (Crystal Clock Oscillator), обычный кварц здесь не подойдет.
CAP/2.5V — при напряжении питания больше 2.7V, к этому пину надо подключить конденсатор в 100 нФ (на рис.2 показано перемычкой), в противном случае (напряжение питания меньше 2.7V), этот пин следует подключать напрямую к источнику питания (ставить перемычка между CAP/2.5V и VCC).
Операционный усилитель — при выборе ОУ следует исходить из предусмотренной, максимальной частоты выходного сигнала, генерируемого AD9833. Это означает что амплитудо-частотная характеристика ОУ должна соответствовать (превышать) этой самой максимальной частоте, иначе вместо усиления сигнала получим подавление. Кстати у меня такого ОУ не оказалось, пришлось заказывать парочку высокочастотных. Но к моему счастью, потребности разрабатываемого прибора ограничиваются несколькими килогерцами, так что и низкочастотные ОУ пойдут в дело.
Пример: чтобы обработать выходной сигнал с максимально-возможной частотой, которую способен воспроизвести AD9833, а это MCLKмакс/2 = 12,5 МГц (половина частоты опорного тактирующего сигнала, по закону Найквиста), диапазон рабочих частот ОУ должен быть как минимум 13МГц, а лучше и все 20МГц — кто знает что за ОУ попадется.
Примечания к созданию фильтра
Как я уже говорил, соотношение Сигнал/Шум у AD9833 приличное и без всякой фильтрации, а поскольку генератор будет работать на очень большом диапазоне частот, то избавиться от оставшихся «хвостов» не получится, если только не использовать программируемый цифровой фильтр, но те что мне встречались работали с частотами до 50..100 КГц (для меня в самый раз, но в остальных случаях не пойдут), так что, по сути, конденсатор C5 является единственным фильтром! Но несмотря на это я все-же использовал фильтр Баттерворта 4-го порядка на 100 КГц, для фильтрации высокочастотного шума исходящего от тактового генератора и управляющей логики (микроконтроллера). Кстати я тут рассусоливаю про фильтрующий конденсатор а сам забыл его вставить в свой подопытный модуль.
Заземление — в общем заземление должно соответствовать всем требованием заземления в системах со смешанными сигналами: заземляющая площадь должна быть как можно больше, цифровая и аналоговая земля должны соединятся только в одной точке. Подробней об этом можно почитать в статье: Заземление в системах со смешанными сигналами.

Рис.3 Подопытный модуль — вид сверху

Рис.4 Подопытный модуль — вид снизу
Программная реализация
В качестве управляющего мк я использовал ATMega16. AD9833 может изменять значение частотных регистров двумя способами: путем последовательной записи двух 14-битных слов (проще говоря записи 28-битного слова), либо записывать по отдельности старших/младших 14-бит (так называемый coarse/fine tuning). Данная библиотека работает только в режиме 28-битного слова, то есть происходит полное обновление значения частотного регистра (все 28-бит).
#define ENABLE(x,y) ((x) |= (1<<(y)))
#define DISABLE(x,y) ((x) &=~ (1<<(y)))
#define TOGGLE(x,y) ((x) ^= (1<<(y)))
#define CHECKBIT(x,y) ((x) & (1<<(y)))
#define BIT(x) (1 << (x))
//-------------------------------
#define SPIBUS PORTB
#define DDRSPI DDRB
#define SDATA 5
#define SCLK 7
#define FSYNC 4
//-------------------------------
#define WRITE_TO_FREQ1_REG 0x8000
#define WRITE_TO_FREQ0_REG 0x4000
#define WRITE_TO_PHASE1_REG 0xE000
#define WRITE_TO_PHASE0_REG 0xC000
//-------------------------------
#define B28 13 /* 28-BIT/14-BIT WORD, D13 */
#define HLB 12 /* HIGH/LOW BYTE, D12 */
//-------------------------------
#define USE_FREQ 11 /* FSELECT, D11 */
#define USE_PHASE 10 /* PSELECT, D10 */
//-------------------------------
#define RESET 8 /* D8 */
#define STOP_MCLK 7 /* SLEEP1, D7 */
#define STOP_DAC 6 /* SLEEP12, D6 */
#define DISCONNECT_DAC 5 /* OPBITEN, D5 */
#define DAC_MSB 3 /* DIV2, D3 */
#define BYPASS_SINROM 1 /* MODE, D1 */
//-------------------------------
#define SINUS 0
#define TRIANGLE 1
#define SQUARE 2
//-------------------------------
#define USE_FREQ0_REG 0
#define USE_FREQ1_REG 1
#define USE_PHASE0_REG 0
#define USE_PHASE1_REG 1
//-------------------------------
#define POWER_OFF 0
#define POWER_ON 1
#define PHASE_RESOLUTION 1 //10
#define VSUPPLY 5000//3300
static unsigned int CONTROL_REGISTER; // 16-битная переменная
//-------------------------------
/* AD9833 SEND WORD */
//-------------------------------
void AD9833_word(unsigned data);
//-------------------------------
/* WRITE AD9833 REGISTERs
Эта функция используется для записи
значения в упраляющий и фазовые регистры AD9833 */
//-------------------------------
void AD9833_write(unsigned data);
//-------------------------------
/* AD9833 SET PHASE
Устанавливаем фазу в в один из двух фазовых регистров
Фаза должна быть в градусах: от 0 .. до 360 с точностью в 1 градус
Чтобы установить фазу с точностью до 0.1 градус следует поменять
значение макроса PHASE_RESOLUTION с 1 на 10
после чего устанавливать фазу*10, то есть
если хотим установить 22.5 градусов следует записать:
AD9833_setPhase(WRITE_TO_PHASE0_REG, 225); */
//-------------------------------
void AD9833_setPhase(unsigned REG, unsigned long Phase);
//-------------------------------
/* AD9833 SET FREQUENCE
Формула по расчету выходной частоты: FREG = (FOUT*2^28)/MCLK,
где FOUT - желаемая частота
Частота используемого мной тактового генератора равна MCLK = 12.0 МГц,
В следующей функции, коэффициент 2237/100 получился из деления 2^28/12000000 = 22.37
К примеру если ваш тактовый генератор будет MCLK = 25.0 МГц
то коэффициент в формуле следует заменить на 2^28/25000000 = 1073/100 */
//-------------------------------
void AD9833_setFreq(unsigned REG, unsigned long Freq);
//-------------------------------
/* AD9833, CHANGE USED FREQUENCY REGISTER
В AD9833 имеются 2 частотных регистра.
Пока в одном регистре записана текущая частота,
можно загнать во второй регистр следующую частоту
и в нужный момент переключится на нее. Следующая функция
как раз и используется для переключения между этими двумя
регистрами при помощи соответстующих макросов */
//-------------------------------
void AD9833_usedFreqReg(unsigned char REG);
//-------------------------------
/* AD9833, CHANGE USED PHASE REGISTER
Функция переключения фазовых регистров,
аналогична функции переключения между частотными регистрами */
//-------------------------------
void AD9833_usedPhaseReg(unsigned char REG);
//-------------------------------
/* AD9833 Mode Select
Функция для изменения формы
выходного сигнала: синус (SINUS), треугольник (TRIANGLE), меандр (SQUARE) */
//-------------------------------
void AD9833_mode(unsigned char mode);
BONUS!!!
Как я уже говорил, в моей поделке мне необходим также и ЦАП. Чтобы не цеплять внешний, решил использовать внутрений 10-битный ЦАП AD9833. Следующая функция позволяет использовать AD9833 в качестве простого ЦАП'a. В зависимости от напряжения питания (VSUPPLY) AD9833 можно получать постоянное напряжение от 0 до VSUPPLY. Напряжение питания следует указать в макросе VSUPPLY — в милливольтах. В этой функции используется фазовый регистр № 0.
Описание функции: если кратко то сбрасываем AD9833, тем самым обнуляем все внутренние регистры, устанавливаем частоту в 0.0 Гц и треугольную форму сигнала, чтобы уровень напряжения был в прямой зависимость от значения фазы, а дальше при помощи фазового регистра прибавляем нужную фазу. Также ниже есть график небольшого эксперимента с использованием различных форм сигнала.
//-------------------------------
/* AD9833, USED AS SIMPLE DAC */
//-------------------------------
void AD9833_DAC(unsigned long millivolts); /* millivolts - желаемое напряжение в милливольтах */

Рис.5 Вывод постоянного напряжения с использованием
синусоидальной и треугольной форм сигналов. В одном случае смещение фазы
приводит к смещению по синусоидальной траектории, в другом — по прямой
Эксперимент состоял в определении зависимости и соответсвии подоваемого мной цифрового значения (шаг 500 — который должен был соответствовать 500мВ), и получения на выходе соответствующего значения напряжения. Из графика виден оффсет при использовании внутреннего ЦАП'a: ~0.38mV * K, где К — коэффициент усиления ОУ. Также из графика видно, что я этот самый коэффициент усиления не докрутил до значения при котором можно получить на выходе AD9833 напряжение VSUPPLY. Если подытожить эксперимент, то на выходе получил изменение напряжение с равным шагом (~0.4V) а также прямая зависимость VOUT от цифры. Так что при последующей реализации сего модуля надо будет предусмотреть компенсацию оффсета, соответствующий коэффициент усиления и не забыть про фильтрующий конденсатор :).
//-------------------------------
/* AD9833 - MCLK and DAC power supply
Функция включения/выключения AD9833 */
//-------------------------------
void AD9833_power(unsigned char mode);
//-------------------------------
/* SPI initialization: Master Mode */
//-------------------------------
void spi_init(void);
Ну и на последок функция инициализации. Первым делом следует сбросить все внутренние регистры, затем установить желаемые значения в фазовые и частотные регистры, так как их значение при сбросе не изменяется и по началу там находится мусор. После всех этих операции AD9833 стартует с так называемого midscale значения. Это значение соответствует половине VSUPPLY. Это означает что по умолчанию, AD9833 стартует с 2.5В (VSUPPLY/2), при 90о — VOUT равно 5В и так далее по синусоидальной/треугольной траектории. Я же привык чтобы синус стартовал с минимального значения, плюс в случае инициализации AD9833 с частотой 0.0 Гц, не желательно чтобы на выходе AD9833 торчало 2.5V (VSUPPLY/2). Для этого, в используемый фазовый регистр (по умолчанию это регистр № 0) загонаю 270о градусов, для старта с минимального значения. Во второй «от нечего делать» загнал 180о градусов. Ну и в конце выбираем форму выходного сигнала.
//-------------------------------
/* AD9833 initialization */
//-------------------------------
void AD9833_init(unsigned char mode, unsigned long Freq);

Рис.6 Траектории со смещением в 270о и без смещения
Тестируем код
//-------------------------------
// Проект для ATMega16 или любой другой
//-------------------------------
#include "AD9833.h"
// обработчик внешнего прерывания int0
void int0_isr(void)
{// по нажатию кнопки изменяем форму сигнала
static unsigned char mode;
AD9833_setFreq(WRITE_TO_FREQ0_REG, 1); // Hz
AD9833_mode(mode);
mode++;
if(mode>2) mode=0;
}
// обработчик внешнего прерывания int1
void int1_isr(void)
{// функция использованная в вышеописанном эксперименте
static unsigned millivolts;
AD9833_DAC(millivolts);
millivolts+=500; // step = 500mV
if(millivolts>5000) millivolts=0;
}
//-------------------------------
/* INITIALIZATION OF PERIPHERAL DEVICES */
//-------------------------------
void system_setup(void)
{
asm("cli"); // запретить все прерывания
PORTB = 0x00;
DDRB = 0x00;
AD9833_init(TRIANGLE, 0); /* SET MODE AND FREQUENCY IN Hz */
MCUCR = 0x0F; /* Rising edge */
GICR = 0xC0; // enable int0 and int1 interrupts
TIMSK = 0x00;
asm("sei"); // разрешить все прерывания
}
//-------------------------------
void main(void)
{
system_setup();
while(1)
{
}
}
//-------------------------------
/* THE END */
//-------------------------------
Зубцы на форме выходного сигнала отчасти «работа» осциллографа, ну и конечно сказывается отсутствие фильтрующего конденсатора.
На сайте Analog Devices можно поиграться с AD9834 Interactive Design Tool, хотя AD9833 и AD9834 чуть отличаются.
Скачать статьи по AD9833
Скачать библиотеку по управлению DDS синтезатором AD9833
- +2
- 30 октября 2011, 12:12
- grand1987
А можно узнать максимальную частоту, на которой не появляется глюков(у вас на видео показано порядка 1 Гц)?.. просто с ДДСом я возился, вышло не айс :(
… 1 Гц я поставил для наглядности переключения между формами сигнала… с точностью на том диапазоне что я игрался (до 100КГц) все в порядке (сотые герца)… да и дальше должно работать нормально… вот приедут заказанные высокочастотные ОУ погоняю и на мегагерцах… главный вопрос это форма сигнала на больших частотах, по расчетом на 12.5 МГц, должно быть 20 точек на волну (период), что при наличии сглаживающего конденсатора должно быть похоже на синус :)
Поправьте ссылку на скачивание файлов.
P.S. для тех кто очень хочет скачать, можно это сделать тут
P.S. для тех кто очень хочет скачать, можно это сделать тут
по прочтении статьи решил попробовать DDS
у меня нашлась AD9834 + ATMEGA128 решил использовать их
надо сказать что завелось почти сразу…
переделки коснулись инициализации SPI, прерываний, ну и пришлось переписывать расчет частоты, оригинальный для 9834 не подходит,
сильно врет (у меня MCLK=50 MHz) и выше 1.9 мгц не работает.
у меня нашлась AD9834 + ATMEGA128 решил использовать их
надо сказать что завелось почти сразу…
переделки коснулись инициализации SPI, прерываний, ну и пришлось переписывать расчет частоты, оригинальный для 9834 не подходит,
сильно врет (у меня MCLK=50 MHz) и выше 1.9 мгц не работает.
вот мой вариант
{/* WRITE 28-BIT FREQVENCE */
Fdset = 268435456.0 / MCLK;
rFREQ = (unsigned long)(Fdset*Freq); // F* 2^28/MCLK = Fhz * 268435456/50000000
DISABLE(SPIBUS,FSYNC);
AD9834_word((unsigned)(rFREQ & 0x3FFF) | REG); /* 14 LSBs */
AD9834_word(((rFREQ >> 14) & 0x3FFF) | REG ); /* 14 MSBs */
ENABLE(SPIBUS,FSYNC);
FT2232D — преобразователь интерфейсов USB<->RS232, USB<->SPI, USB<->JTAG, USB<->I2C
Используется уже во многих JTAG-отладчиках, а также в программаторах для внутрисхемного программирования микроконтроллеров AVR.
Об этой микросхеме и программаторах на её основе DI HALT написал целый обзор: easyelectronics.ru/ft2232d-i-avr-proshivka-i-otladka-po-jtag.html
Используется уже во многих JTAG-отладчиках, а также в программаторах для внутрисхемного программирования микроконтроллеров AVR.
Об этой микросхеме и программаторах на её основе DI HALT написал целый обзор: easyelectronics.ru/ft2232d-i-avr-proshivka-i-otladka-po-jtag.html
… в качестве фильтра используйте тот который вам больше подходит, я его не ставил потому что одни предпочитают RC-фильтры, другие Баттерворт/Чебышев/Эллиптический… и т.д., также я использовал фильтр на 100КГц, а кому-то нужен на 1/2/10 МГц… и т.д., так что номиналы тоже могут быть разными. Также различаются и топологии фильтров, или вас интересует именно фильтр Баттерворта 4-го порядка на 100КГц?
Меня интересует схема подключения Atmega + AD9833.
И интересует как лучше реализовать подключение кнопок для регулирования выходного напряжения от 0.1В до 10В и частоты сигнала от 1кГц и до 1Мгц. И судя по всему надо еще дисплей прикрутить чтобы это все видеть. Буду рад любому совету. Так как только начинаю с этим разбираться.
И интересует как лучше реализовать подключение кнопок для регулирования выходного напряжения от 0.1В до 10В и частоты сигнала от 1кГц и до 1Мгц. И судя по всему надо еще дисплей прикрутить чтобы это все видеть. Буду рад любому совету. Так как только начинаю с этим разбираться.
… здесь можно посмотреть более детальную блок-схему
как лучше реализовать подключение кнопок для регулирования выходного напряжения от 0.1В до 10Ввы хотите программно пегулировать амплитудой сигнала?
и частоты сигнала от 1кГц и до 1Мгц… функцию установки частоты я привел выше в коде, а о работе с дисплеем можно почитать в статье DI HALT'a или здесь
Да в принципе без разницы как рулить амплитудой. Я так понимаю, что можно только программно. Аппаратно вроде в AD9833 это не предусмотрено, но я могу ошибаться. Просто мне программу надо на ассемблере писать( (ничего не поделаешь такая задача). И пока я слабо представляю как организовать прерывания для кнопок.
… у AD9833 амплитуда фиксированная и ее ни программно ни аппаратно менять нельзя, единственный вариант это управлять коэффициентом усиления выходного усилителя
Ага, ну что ж нормальный вариант. Вроде разобрался в отрицательной обратной связи надо подстроечный резистор поставить, только что-то не могу сообразить насколько чтобы была перестройка по 0.1В. И еще вопрос J1 это что? Я понял, что это коннектор с 3 ножками. И еще на вход AD9833 CAP/2.7V я так понял надо напряжение подавать. А у вас на схеме это не обозначено.
только что-то не могу сообразить насколько чтобы была перестройка по 0.1В… все зависит от того насколько плавно будите крутить переменник. Берите многооборотный подстроечный резистор.
J1 это что?все зависит от напряжения которым вы будете питать AD9833, и тут есть два варианта:
1. Напряжение питания > 2.7V — тогда CAP/2.5V подключаете через конденсатор на землю
2. Напряжение питания < 2.7V — тогда CAP/2.5V подключаете напрямую к питанию AD9833
Нужно мне сделать звуковой генератор на ad98. Генерировать он будет 100-200 КГц. Понравилась именно эта схема, т.к. переносной модуль — пригодится в других проектах.
Но вот совершенно непонятно как подключать контроллер. Может без порта обойдемся?
И еще… Знаний схемотехнике недостаточно… К выходу можно сразу динамик подключить? Или сначала усилитель?
И что с питанием делать?
Но вот совершенно непонятно как подключать контроллер. Может без порта обойдемся?
И еще… Знаний схемотехнике недостаточно… К выходу можно сразу динамик подключить? Или сначала усилитель?
И что с питанием делать?
К выходу можно сразу динамик подключить? Или сначала усилитель?… смотря какой динамик, но скорей всего без дополнительного усилителя не обойтись
И что с питанием делать?… все зависит от усилителя, на we.easy есть статьи как по усилителям так и по блокам питания
А еще вопрос про резонатор. Какой выбрать? Ни разу с ними не работал. В описаниях у каждого определенный диапазон частот. Он как-то настравивается что ли?
… если вам нравится форма сигнала представленная на видео, то можете и не ставить кондер C5, но маленький кондер на входе думаю не помешает ни при разводке платы ни для качества сигнала. Номинал кондера зависит от максимальной частоты выходного сигнала. Посмотрите графики в даташите, они получены с использование C5 = 20pF, опять-же, если вас устраивает уровни шума и т.д. ставьте этот номинал, если нет подберите более подходящий для вас, но думаю номиналы где то в этом районе.
Ладно, еще один косяк. Один тактовый генератор дороже в три раза чем остальной прибор? 1500 руб(в местном магазине) или 900 при интернет-заказе?
Ээээ… Других вариантов нет?
Ээээ… Других вариантов нет?
Подскажите пож. почему при выборе меандра напряжение становиться 5 вольт?
а пила и синус как положено 6.5
а пила и синус как положено 6.5
… когда выбран меандр, то выходной сигнал генерится компаратором, который следит за MSB-битом ЦАПа (смотрите Рис.1 в даташите). В случае синуса и треугольника, то выходной сигнал генерится непосредственно ЦАПом (выхокочастотным).
А как считаете: хочу управлять акустооптическим фильтром, нужна частота до 250 МГц, DDC нужный нашёл, но вот как реализовать фильтрацию и усиление на таких частотах?
… усилитель придется собирать самому из высокочастотных транзисторов, ну а для фильтра рекомендую програмулю
Ещё вопросы.
1. Насколько точно 0 ЦАПа соответствует половине питающего напряжения?
2. Где достать эту микросхему? Нашёл на Промэлектронике за 260 руб. AD9837 не нашёл вообще. AD9850 за 1500 руб, как-то, не та задача.
1. Насколько точно 0 ЦАПа соответствует половине питающего напряжения?
2. Где достать эту микросхему? Нашёл на Промэлектронике за 260 руб. AD9837 не нашёл вообще. AD9850 за 1500 руб, как-то, не та задача.
1. Насколько точно 0 ЦАПа соответствует половине питающего напряжения?… насколько точно вы убирете оффсет ЦАПа, подадите напряжение питания и выберете коэффициент усиления.
2. Где достать эту микросхему? Нашёл на Промэлектронике за 260 руб. AD9837 не нашёл вообще. AD9850 за 1500 руб, как-то, не та задача.Я брал на ebay. Сейчас посмотрел, там есть AD9850 по $5
Комментарии (84)
RSS свернуть / развернуть