Внимание! Перед тем как создавать тему на форуме, воспользуйтесь поиском! Пользователь создавший тему, которая уже была, будет немедленно забанен! Читайте правила названия тем. Пользователи создавшие тему с непонятными заголовками, к примеру: "Помогите, Схема, Резистор, Хелп и т.п." также будут заблокированны навсегда. Пользователь создавший тему не по разделу форума будет немедленно забанен! Уважайте форум, и вас также будут уважать!
В известной библиотеке на qrp-labs.com есть пример работы с целочисленными делителями MultiSynth Si5351. Представляю Вашему вниманию модификацию этой библиотеки для работы с дробными делителями. Может быть, кому-нибудь пригодится. Пример написан на MikroC для отладочной платы EasyAVR6. Микроконтроллер AtMEGA328P с кварцем на 8 МГц. Si5351 подключено к PC4 - SDA и PC5 - SCL, к ней кварц 25 МГц. Программа формирует на выходе 0 частоту 45 МГц, на выходе 1 - 44,56 МГц, на выходе 2 - 460 кГц.
CODE
///установка дробного делителя void setupMultisynthFraq(char synth, unsigned long dividerA,unsigned long dividerB,unsigned long dividerC, char rDiv) { unsigned long P1; // Synth config addrister P1 unsigned long P2; // Synth config addrister P2 unsigned long P3; // Synth config addrister P3
P1 = 128 * dividerA+(unsigned long)Floor(128*dividerB/dividerC) - 512; P2 = 128*dividerB-dividerC*(unsigned long)Floor(128*dividerB/dividerC); // P2 = 0, P3 = 1 forces an integer value for the divider P3 = dividerC; //все по даташиту
void si5351aSetFrequencyOut23(unsigned long frequency2,unsigned long frequency3) //установка частоты на выходе 2 и 3 от PLLB { unsigned long pllFreq; unsigned long xtalFreq = XTAL_FREQ; unsigned long float f; char mult; unsigned long num; unsigned long denom; unsigned long divider; float dividerOut3;//дробный коэффициент деления третьего выхода unsigned long dividerA,dividerB,dividerC; //для третьего выхода - разбивка дроби // i2c_init(); // Initialise the I2C TWI_Init(100000);
divider = 900000000 / frequency2;// Calculate the division ratio. 900,000,000 is the maximum internal // PLL frequency: 900MHz if (divider % 2) divider--; // Ensure an even integer division ratio
pllFreq = divider * frequency2; // Calculate the pllFrequency: the divider * desired output frequency
mult = pllFreq / xtalFreq; // Determine the multiplier to get to the required pllFrequency l = pllFreq%xtalFreq; // It has three parts: f = // mult is an integer that must be in the range 15..90 f = f*1048575; // num and denom are the fractional parts, the numerator and denominator f = f/xtalFreq; // each is 20 bits (range 0..1048575) num = (unsigned long)f; // the actual multiplier is mult + num / denom denom = 1048575; // For simplicity we set the denominator to the maximum 1048575
// Set up PLL A with the calculated multiplication ratio setupPLL(SI_SYNTH_PLL_B, mult, num, denom); // Set up MultiSynth divider 0, with the calculated divider. // The final R division stage can divide by a power of two, from 1..128. // reprented by constants SI_R_DIV1 to SI_R_DIV128 (see si5351a.h header file) // If you want to output frequencies below 1MHz, you have to use the // final R division stage setupMultisynth(SI_SYNTH_MS_1, divider, SI_R_DIV_1);
dividerOut3=pllFreq/(128.0*frequency3);// для третьей частоты - будет с ошибкой и учитываем деление на 128 /* longtostr(pllFreq,txt2); Lcd_Out(1,1,txt2); floattostr(dividerOut3,txt2); Lcd_Out(2,1,txt2); */ //нужна точность до герца - берем делитель C до 1/128/1000 прибл 1/65535, хотя хватило бы и 1/32768 dividerC=65535;//принудительно dividerA=(unsigned long)dividerOut3;//округляем dividerB=(unsigned long)((dividerOut3-dividerA)*dividerC);//берем дробную часть, умножаем ее на знаменатель
setupMultisynthFraq(SI_SYNTH_MS_2, dividerA,dividerB,dividerC, SI_R_DIV_128); //делим на 128 для уменьшения джиттера и устанавливаем // Reset the PLL. This causes a glitch in the output. For small changes to // the parameters, you don't need to reset the PLL, and there is no glitch i2cSendRegister(SI_PLL_RESET, 0xA0); // Finally switch on the CLK0 output (0x4F) // and set the MultiSynth0 input to be PLL A i2cSendRegister(SI_CLK1_CONTROL, 0x4F | SI_CLK_SRC_PLL_B); //i2cSendRegister(SI_CLK2_CONTROL, 0x4F | SI_CLK_SRC_PLL_B); i2cSendRegister(SI_CLK2_CONTROL, 0x0F | SI_CLK_SRC_PLL_B); //0f - потому что работаем в дробном режиме // i2c_exit(); // Exit I2C TWI_Stop();
}
void main(){
si5351aSetFrequency(45000000); si5351aSetFrequencyOut23(45000000-460000,460000);//частоты второй пч и ssb детектора
}
Это сообщение отредактировал AntonSor - Nov 13 2016, 12:35 PM
Доброго времени суток. Нужна помощь в создании на основе этой микросхемы генератора до 150 мгц. Конкретнее : библиотека позволяющая обойти ограничение в 112.5 мгц по максимальной частоте. CLK1 и CLK2 не нужны. Вы можете как-то помочь?
2.1.1. Selecting the Proper VCO Frequencies and Divide Ratios The general criteria below may be used to set the VCO frequencies. This is a general model, and individual applications may require some modification. 1. Valid Multisynth divider ratios are 4, 6, 8, and any fractional value between 8 + 1/1,048,575 and 900 + 0/1. This means that if any output is greater than 112.5 MHz (900 MHz/8), then this output frequency sets one of the VCO frequencies --- 4.1.3. Output Multisynth Divider Equations (150 MHz <Fout<=200 MHz) Output frequencies greater than 150 MHz are available on Multisynths 0-5. For this frequency range a divide value of 4 must be used by setting MSx_P1=0, MSx_P2=0, MSx_P3=1, MSx_INT=1, and MSx_DIVBY4[1:0]=11b. Set the appropriate feedback Multisynth to generate f VCO =Fout*4
То есть, для выходной частоты от 112,5 до 200 МГц требуется использовать только целые четные делители, и для частоты выше 150 МГц отключать дробный делитель совсем (коэффициенты равны нулю) и делить лишь спецделителем на 4. При изменении частоты VCO от 600 до 900 МГц, отключенном делителе Multisynth и доп делителе 4 частота на выходе будет от 150 до 225 МГц. Чтобы перекрыть участок от 112,5 до 150 МГц, примените делитель Multisynth 6 и отключите доп делитель - получится перекрытие от 100 до 150 МГц. На самом деле, код для включения дополнительного делителя записывается туда же, куда и делитель Rdiv - в адрес synth + 2. Из библиотечного кода:
А для включения доп делителя на четыре здесь будет ещё и
CODE
const SI_R_DIV_1_DIV_4=12;// 0b00001100;
MSx_INT=1 находится в регистре SI_CLK0_CONTROL, а конкретно в 0x4F | SI_CLK_SRC_PLL_A . Если делитель целочисленный, там 4f, если дробный, то 0f. В исходной версии библиотеки 4f, так что это значение уже есть. Для формирования этих значений регистров можно применить два подхода. Первый заключается в том, что используется библиотечная процедура записи целочисленного делителя и в ней устанавливается делитель, подобранный так, чтобы на выходе были P1=0. В целочисленной библиотеке и так P2=0, P3=1. А P1 = 128 * divider - 512. Поэтому, чтобы был ноль, 128 * divider должно быть =512. Т.е. divider = 512/128 = 4. Таким образом, для выходной частоты от 150 до 225 МГц используем следующие куски кода в процедуре si5351aSetFrequency:
CODE
setupPLL(SI_SYNTH_PLL_A, mult, num, denom); //устанавливаем частоту генератора VCO setupMultisynth(SI_SYNTH_MS_0, 4, 0b00001100); //устанавливаем делитель в 4, чтобы P1=0 и включаем доп делитель на 4 i2cSendRegister(SI_PLL_RESET, 0xA0); //сброс ФАПЧ i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);//устанавливаем бит целого делителя
А для частот от 100 до 150 МГц напрямую и без затей указываем делитель 6 и без доп делителя
Второй путь - это написание собственной процедуры отправки данных. Берем процедуру setupMultisynth и меняем отправку вот на что (для частот от 150 до 200 МГц)
разобрался - почему-то не компилилось нормально через мобилу (ArduinoDroid) вечно ругался на незарегистрированные идентификаторы, перезалил через комп и всё заработало до 225 мгц проверил - работает, i2c адрес такой же 0x60