Генератор adf4351 arduino
Здравствуйте.
В соседней теме про мостовой КСВ-метр понадобился источник сигнала. Модули телеметрии и nrf24 не особо подходят, потому что имеют скважность.
Это попытка сделать генератор синуса на adf4351.
Жду такой модуль banggood.com/35M-4_4GHz-PLL-RF-Signal-Source-Frequ…
Пока только могу проверять интерфейс, придумывать коробочку и печатку под нее.
Не знаю, коробку пластиковую или металл. А если металл, то на корпус крепить только SMA, а землю разъема питания изолировать, наверное? Чтобы не было земляных петель.
На модуле adf4351 стоит AMS 3.3V - она будет использоваться также для питания Ардуино. Входное питание будет 5В через фильтры на эту AMS 3v3.
6 регистров управления, генерируемые в коде Ардуино совпадают с регистрами в программе.exe от AD eval board soft.
Теоретически, можно вывести rx tx Ардуино и сделать задание частоты\шага с компьютера. Т.е. написать дополнительный софт для ПК, чтобы управлять генератором не только кнопками\энкодером, но и через оболочку. Например, сделать панорамный измеритель КСВ.
====================================================================
Панкратов Сергей тоже работает над генератором для NWT4000.
По этой ссылке серьезный подход и результат :
forum.vhfdx.ru/eteo-teato/adf4350/msg315403/#msg31…
Задумался над питанием.
Попробую по картинке #1.
На генераторе раздельные аналоговое и цифровое питание, соединяются дросселем 100uH.
С гребенки на плате генератора уходит 3.3В цифрового питания - отправлю его на Ардуино.
На шину SPI поставлю дроссели Murata BLM18GG471.
По питанию от платы генератора к Ардуино: Murata BLM18GG471 и NFM21CC223R, несколько смд-конденсаторов. Земля между генератором и Ардуино напрямую. 3.3В и землю пропущу через ферритовое кольцо (синфазный дроссель).
Земляной провод и шлейф SPI будут в одном плотном жгуте, чтобы между линиями SPI и земляным проводом не было петель (рамки).
Может, +3.3В, землю и SPI вместе пропустить через ферритовое кольцо?
На Ютубе человек говорит, что большой электролит 100мкФ у AMS 3.3 помог ему.
Пока сделал интерфейс. Самой платы adf еще нет…
в идеале иметь возможность подключить два генератора к одному интерфейсу + два канала ацп и интерфейс к компу с протоколом WinNWT …
поддержка по возможности adf4350/adf4351/adf4356/max2871 …
в результате получим контроллер намного более функциональный - от простого генератора и КСВметра до интерфейса спектроанализатора …
ВЧ часть каждый сможет купить/сделать по вкусу/необходимости … есть много готовых вариантов генераторов и детекторов … так-же можно использовать стабилизированные задающие генераторы … можно сделать умножители и смесители на нужные диапазоны …
генератора к одному интерфейсу + два канала ацп и интерфейс к компу с протоколом WinNWT …
поддержка по возможности adf4350/adf4351/max2871 …
в результате получим контроллер намного более функциональный - от простого генератора и КСВметра до интерфейса спектроанализатора …
ВЧ часть каждый сможет купить/сделать по вкусу/необходимости … есть много готовых вариантов генераторов и детекторов … так-же можно использовать стабилизированные задающие генераторы … можно сделать умножители и смесители на нужные диапазоны …
На все нам нужные диапазоны, в том числе и с умножителями и с фильтрами ( без фильтров не будет точности измерений , ксв менее 1.6-1.8 не оценить ) давненько делал. И выкладывал код для работы с WinNWT.
Тут набор на нужные диапазоны-
Тут вид на компе при работе с WinNWT
Тут варианты для 5.8 ггц.
А тут на базе универсальной платы Продвинутого 2 генератор 137-4400 мгц с управлением частотой, мощностью-
в идеале иметь возможность подключить два генератора к одному интерфейсу + два канала ацп и интерфейс к компу с протоколом WinNWT …
поддержка по возможности adf4350/adf4351/adf4356/max2871
Ого! 2 генератора = отладка SPI, чтобы дергать LE на каждом.
max2871 - только слышал про них, купить довольно сложно\дорого.
Зато adf4351 на каждом шагу и доступно.
В текущей версии доступны A6, A7 и несколько цифровых, а также rx-tx.
Можно сделать так:
Напряжение с детектора (Н.О.) или перекоса резистивного моста масштабировать на операционнике и подать на А6.
Или на ЦАП и потом i2c.
Выставляем частоту, шаг. Крутим энкодер.
По TX бегут изменяющиеся freq;voltage;
Далее пишем простую программу, которая нормирует и строит график.
Но вначале запустить бы генератор,который ползет из Китая.
Ого! 2 генератора = отладка SPI, чтобы дергать LE на каждом.
А что там отлаживать?
ССылка ж на мой код есть, банальное дерганье ногами, у меня все программное-
//#define P_LE 6 PD6
//#define P_DATA 8 PB0
//#define P_SCK 9 PB1PORTD &= ~0b01000000;// 0 на LE
for (int n=0; n<4; n++)
{ // с старшего байта до младшего
byte data= Reg [num_reg] [n]; // берем байт
for (char u=0; u<8; u++)
{ //перебираем с старшего бита по младший
if(data &(0b10000000>>u)) PORTB |= 0b00000001; // ставим 1
else PORTB &= ~0b00000001; // или 0 в PB0
//обозначим clock
PORTB |= 0b00000010;// 1 дергаем PB1
PORTB &= ~0b00000010;}// 0
}
PORTD |= 0b01000000;// 1 in LE
Да и вообще какой смысл что то заново изобретать- весь код рабочий, схемы рабочие, плата так же.
Трудятся уже множество устройств…
Мне когда то пришлось изобретать, изучать протоколы- в инете не было примеров кодов.
А сейчас какой смысл?
Да и вообще какой смысл что то заново изобретать- весь код рабочий, схемы рабочие, плата так же.
У меня все параметры доступны для настройки по даташиту. Это замедляет цикл, но позволяет “в лоб” дорабатывать код.
void ADF4351_prepareConfig() {
// PLL-Reg-R0 = 32bit
// Registerselect 3bit
// int F_Frac = 4; // 12bit
// int N_Int = 92; // 16bit
// reserved // 1bit
// PLL-Reg-R1 = 32bit
// Registerselect 3bit
//int M_Mod = 5; // 12bit
int P_Phase = 1; // 12bit bei 2x12bit hintereinander pow()-bug !!
uint8_t Prescal = 0; // 1bit geht nicht ???
uint8_t PhaseAdj = 0; // 1bit geht auch nicht ???
// reserved // 3bit
// PLL-Reg-R2 = 32bit
// Registerselect 3bit
uint8_t U1_CountRes = 0; // 1bit
uint8_t U2_Cp3state = 0; // 1bit
uint8_t U3_PwrDown = 0; // 1bit
uint8_t U4_PDpola = 1; // 1bit
uint8_t U5_LPD = 0; // 1bit
uint8_t U6_LPF = 1; // 1bit 1=Integer, 0=Frac not spported yet
uint8_t CP_ChgPump = 7; // 4bit
uint8_t D1_DoublBuf = 0; // 1bit
// int R_Counter = 1; // 10bit
// int RD1_Rdiv2 = 0; // 1bit
// int RD2refdoubl = 0; // 1bit
uint8_t M_Muxout = 0; // 3bit
uint8_t LoNoisSpur = ADF4351_lowNoiseOrSpurVariants[ADF4351_lowNoiseOrSpur_current]; //0 2bit
// reserved // 1bit
// PLL-Reg-R3 = 32bit
// Registerselect 3bit
int D_Clk_div = 150; // 12bit
uint8_t C_Clk_mode = 0; // 2bit
// reserved // 1bit
uint8_t F1_Csr = 0; // 1bit
// reserved // 2bit
uint8_t F2_ChgChan = 0; // 1bit
uint8_t F3_ADB = 0; // 1bit
uint8_t F4_BandSel = 0; // 1bit
// reserved // 8bit
// PLL-Reg-R4 = 32bit
// Registerselect 3bit
uint8_t D_out_PWR = ADF4351_outputPowerVariants[ADF4351_outputPower_current] ; // 2bit
uint8_t D_RF_ena = 1; // 1bit
uint8_t D_auxOutPwr = 0; // 2bit
uint8_t D_auxOutEna = 0; // 1bit
uint8_t D_auxOutSel = 0; // 1bit
uint8_t D_MTLD = 0; // 1bit
uint8_t D_VcoPwrDown = 0; // 1bit 1=VCO off
// int B_BandSelClk = 200; // 8bit
uint8_t D_RfDivSel = 3; // 3bit 3=70cm 4=2m
uint8_t D_FeedBck = 1; // 1bit
// reserved // 8bit
// PLL-Reg-R5 = 32bit
// Registerselect // 3bit
// reserved // 16bit
// reserved 11 // 2bit
// reserved // 1bit
uint8_t D_LdPinMod = 1; // 2bit muss 1 sein
// reserved // 8bit
// Referenz Freg Calc
// long ADF4351_referenceFreq = 250000; // Refrenquarz = 25000000hz
int R_Counter = 1; // 10bit
uint8_t RD1_Rdiv2 = 0; // 1bit
uint8_t RD2refdoubl = 0; // 1bit
int B_BandSelClk = 200; // 8bit
// int F4_BandSel = 0; // 1bit
// int F4_BandSel = 10.0 * B_BandSelClk / PFDFreq;
uint32_t RFout = ADF4351_frequency; // VCO-Frequenz
// calc bandselect und RF-div
uint8_t outdiv = 0;
if (RFout >= 220000000) {
outdiv = 1;
D_RfDivSel = B0;
}
if (RFout < 220000000) {
outdiv = 2;
D_RfDivSel = B001;
}
if (RFout < 110000000) {
outdiv = 4;
D_RfDivSel = B010;
}
if (RFout < 55000000) {
outdiv = 8;
D_RfDivSel = B011;
}
if (RFout < 27500000) {
outdiv = 16;
D_RfDivSel = B100;
}
if (RFout < 13800000) {
outdiv = 32;
D_RfDivSel = B101;
}
if (RFout < 6900000) {
outdiv = 64;
D_RfDivSel = B110;
}
float PFDFreq = ADF4351_referenceFreq * ((1.0 + RD2refdoubl) / (R_Counter * (1.0 + RD1_Rdiv2))); //Referenzfrequenz *10 (все частоту сокращена в 10раз почему-то)
float N = ((RFout) * outdiv) / PFDFreq;
uint16_t N_Int = N;
uint16_t M_Mod = PFDFreq * (100000 / ADF4351_freqStepCurrent) / 100000;
uint16_t F_Frac = round((N - N_Int) * M_Mod);
ADF4351_registers[0] = (unsigned long)(0 + F_Frac * pow(2, 3) + N_Int * pow(2, 15));
ADF4351_registers[1] = (unsigned long)(1 + M_Mod * pow(2, 3) + P_Phase * pow(2, 15) + Prescal * pow(2, 27) + PhaseAdj * pow(2, 28));
// ADF4351_registers[1] = (ADF4351_registers[1])+1; // Registerselect adjust ?? because unpossible 2x12bit in pow() funktion
ADF4351_registers[2] = (unsigned long)(2 + U1_CountRes * pow(2, 3) + U2_Cp3state * pow(2, 4) + U3_PwrDown * pow(2, 5) + U4_PDpola * pow(2, 6) + U5_LPD * pow(2, 7) + U6_LPF * pow(2, 8) + CP_ChgPump * pow(2, 9) + D1_DoublBuf * pow(2, 13) + R_Counter * pow(2, 14) + RD1_Rdiv2 * pow(2, 24) + RD2refdoubl * pow(2, 25) + M_Muxout * pow(2, 26) + LoNoisSpur * pow(2, 29));
ADF4351_registers[3] = (unsigned long)(3 + D_Clk_div * pow(2, 3) + C_Clk_mode * pow(2, 15) + 0 * pow(2, 17) + F1_Csr * pow(2, 18) + 0 * pow(2, 19) + F2_ChgChan * pow(2, 21) + F3_ADB * pow(2, 22) + F4_BandSel * pow(2, 23) + 0 * pow(2, 24));
ADF4351_registers[4] = (unsigned long)(4 + D_out_PWR * pow(2, 3) + D_RF_ena * pow(2, 5) + D_auxOutPwr * pow(2, 6) + D_auxOutEna * pow(2, 8) + D_auxOutSel * pow(2, 9) + D_MTLD * pow(2, 10) + D_VcoPwrDown * pow(2, 11) + B_BandSelClk * pow(2, 12) + D_RfDivSel * pow(2, 20) + D_FeedBck * pow(2, 23));
ADF4351_registers[5] = (unsigned long)(5 + 0 * pow(2, 3) + 3 * pow(2, 19) + 0 * pow(2, 21) + D_LdPinMod * pow(2, 22));
}
По моему у меня меньше строчек во всем коде , то есть всего прибора…
Работа с синтезатором, с детектором и прогой на компе с WinNWT.
Зачем переписывать весь даташит в прогу если в проге нужно 5% из него?
Зачем переписывать весь даташит в прогу если в проге нужно 5% из него?
Сейчас нужно 5%, а потом 3 или 89.
Да и подстановка бит по нужным адресам - тоже неочевидное дело.
Поменялся кварц, захотелось менять мощность или low-noise-mode\low-spur-mode - надо ковыряться в битах.
Еще AD советуют избегать малого шага при низких частотах, когда дробление высокое - это можно удобно отследить по формулам в коде.
Вообще, я делаю ради энкодера и экранчика. Чтобы автономно выставлять частоту и быстро бегать с шагом N.
Фактически, коробочка на батарейках 35-4400 МГц или даже 8800 с усилителем и умножителем.
Репозиторий bitbucket.org/boris_n/ant/src
Сейчас нужно 5%, а потом 3 или 89.
Может задачу вы другую ставите…
Одно дело писать библиотеку под синтезатор на все случаи жизни…
Другое дело - под планируемые задачи.
Второй случай- мой. Но я, честно говоря, не представляю того что вам может понадобиться от синтезатора, но что не реализовано в моем коротком коде.
конкретно моя хотелка - получить аналог NWT6000 , только более правильный …
в NWT6000 не устраивает то что его продают только в корпусном исполнении с пачкордами и переходниками для вывода входа/выхода на переднюю панель устройства которые придется просто выкинуть … и смеситель там явно не на диапазон 6 ГГц …
поэтому хочется модульную конструкцию , как у Сергея , но именно с двумя отдельными генераторами (второй как гетеродин) …
если оно еще и в автономе будет работать , хотя бы как генератор и КСВметр будет вообще замечательно …
у Сергея я приобрел умножитель и несколько пустых плат под генераторы и детекторы , но вот так и не нашел исходники прошивок под атмегу …
, но вот так и не нашел исходники прошивок под атмегу …
исходник прицеплен к сообщению-
forum.vhfdx.ru/eteo-teato/adf4350/msg315403/#msg31…
но именно с двумя отдельными генераторами (второй как гетеродин)
ADF4351 в качестве гетеродина? Многие пишут про его фазовый шум, спуры, “неудачные” точки в диапазоне частот и китайский кварц 25МГц.
Я надеюсь, что без фильтров он сгодится как генератор “шума” более-менее конкретной частоты для прогонки антенны.
исходник прицеплен к сообщению
там как я понял код под один генератор и мне придется разбираться с протоколом и прикручивать второй … но это уже отправная точка чтобы не изобретать велосипед с нуля …
ADF4351 в качестве гетеродина?
ну я планирую всетаки использовать max2871 …
тут на фото плпта препарированного NWT6000 на максах
uglyduck.ath.cx/PDF/MiniVNA/NWT6000_PCB.jpg
в его предшественниках NWT4000 стояли adf4350 или adf4351 (их последний год производят на платах маркированных как NWT6000)
верхний Макс используется как генератор а нижний как гетеродин … под ним смеситель в соике 😵 …
чтобы просто посмотреть спектр adf4351 в качестве гетеродина вполне достаточно … о каких-то точных измерениях тут конечно речь не идет …
там как я понял код под один генератор и мне придется разбираться с протоколом и прикручивать второй … но это уже отправная точка чтобы не изобретать велосипед с нуля …
У чипа ADF есть пин LE, который переключает режимы “запись регистров через SPI” \ “рабочий режим”.
Если поставить 2 чипа, то на Ардуино (атмега, кому что привычнее) нужно выделить 2 ножки под 2 LE.
Конфигурация SPI для всех общая (делитель, порядок байт).
Дергаем LE_1, заливаем регистры.
Дергаем LE_2, заливаем регистры.
Это в теории…
Топология NWT6000 - дорогая. Явно не хоббийная в sprint-layout. Да и “рассыпуха” должна быть, иначе покупать ленты по 10-500 деталей накладно.
На Али искал резисторы 49R9 0402\0603, минимальный заказ 500 штук! Хобби накладное.
нужно в первую очередь смотреть протокол WINNWT и добавлять обработку команд для второго генератора … а прицепить физически к атмеге не проблема, хоть через LE , хоть на отдельные ноги , свободных ног навалом …
нарисовать такую плату в спринте не сложнее чем в любом другом CAD … расчитывается ширина вч дорожек и зазоры до земляных полигонов под конкретный материал платы и рисуется согласно расчетам … там не так много критичных участков … и кстати там далеко не все грамотно сделано …
вот и хочу сделать модульный вариант …
вообще этих плат три вида
- самый грамотный тот что я давал ссылку на фото ( с разЪёмами торчащими вверх из платы)
- почти тожсамое но разЪёмы выведены на край платы … в этой версии какие то проблемы с наводками , для устранения народ лепит на крышки вч болков пружинные контакты на металлический корпус прибора …
- с одним генератором (он и генератор и гетеродин , чсто сильно сужает его возможности ) и разЪёмами на край платы …
На Али искал резисторы 49R9 0402\0603, минимальный заказ 500 штук! Хобби накладное.
при грамотном подходе не очень накладное … для начала закупаются библиотеки элементов R/C/L по 100 штук каждого номинала всех нужных типоразмеров (0402/0603/0805) дальше отдельно закупаются ходовые и специализированные номиналы 1uF , 0.1uF , 0.01Uf , 0.001Uf , 10k , 4.7k , 1k , 0r , 49r9 и так далее в зависимости от востребованности в проектах … 49r9 0603 у меня лежит бобина 5000 штук вообщем как и всего ходового …
а самые ходовые у меня 0.1uFx50v , их больше 1000 в год уходит …