Генератор adf4351 arduino
Да и вообще какой смысл что то заново изобретать- весь код рабочий, схемы рабочие, плата так же.
У меня все параметры доступны для настройки по даташиту. Это замедляет цикл, но позволяет “в лоб” дорабатывать код.
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 в год уходит …
нужно в первую очередь смотреть протокол WINNWT и добавлять обработку команд для второго генератора …
А зачем NWT даже знать о том есть там второй-третий генератор?
NWT к тому как выполнен сам прибор никакого отношения не имеет.
Просто чуть меняется математика в коде и все, совсем немного.
То есть совсем проблем нет, все что нужно- в моем коде есть…
нарисовать такую плату в спринте не сложнее чем в любом другом CAD … расчитывается ширина вч дорожек и зазоры до земляных полигонов под конкретный материал платы и рисуется согласно расчетам
Я взял FR4 1.6мм, у него диэлектрическая константа сигма-эр Er от 4.0 до 4.9 как повезет.
Калькулятор chemandy.com/…/coplanar-waveguide-with-ground-calc…
Чтобы получить 50R копланар с землей, нужно дорожку делать 1.85мм и зазоры 0.36мм, что многовато для 0603 смд.
Вот если бы FR4 0.8мм, тогда дорожки шириной 1.0мм - как раз мелкие СМД торцом встают.
Чтобы получить 50R копланар с землей, нужно дорожку делать 1.85мм и зазоры 0.36мм, что многовато для 0603 смд.
я бы в первую очередь смотрел на рекомендации производителя SMA разЪёма который будет использоваться так чтобы был минимум потерь …
Вот если бы FR4 0.8мм, тогда дорожки шириной 1.0мм - как раз мелкие СМД торцом встают.
ну так а в чем проблема ??? материал доступен в широком ассортименте , параметры материалов которые в наличии в данный момент можно уточнить у изготовителя плат …
www.pselectro.ru/materialy_pechatnyh_plat/
То есть совсем проблем нет, все что нужно- в моем коде есть…
значит нужно распечатать и внимательно почитать с карандашиком …