JH7UBCサイト[Si5351Aの実験その2(任意の周波数の発生)]を使い任意の周波数を設定して周波数出力されるテストを行いました。【http://jh7ubc.web.fc2.com/arduino/Si5351A_2.html】
●秋月電子通商 Si5351 レジスターマップ:【chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://akizukidenshi.com/goodsaffix/an619.pdf】
●PLL周波数:fvco = fxtal * ( a + ( b / c ) ).....(1)
(aは15~90,bは0~1048575,cは1~1048575)
●出力周波数:fout = fvco / ( d + ( e / f ) )......(2)
(( d + ( e/ f ) )の結果は6~1800の間であること)
(2)式を e=0, f=1, 6<=d<=18000にすると
fout = fvco / ( d + ( 0/ 1) )
■d = fvco / fout
■PLL周波数:fvco =d x fout
(1)式から fvco / fxtal = a + ( b / c )
整数部 a
a = fvco / fxtal = ( d * fout ) / fxtal
小数部 ( b / c )
L( 余り)= fvco % fxtal = fxtal * ( b / c)
b = (L * c ) / fxtal
■プログラムにおいて下記に変換されています
d = divider a = mult b = num c = denom
回路図
プログラム Arduino IDE【ボード:Raspberry Pi Pico】
#include <Wire.h>
#define Si5351A_ADDR 0x60
#define MSNA_ADDR 26
#define MS0_ADDR 42
#define CLK0_CTRL 16
#define OUTPUT_CTRL 3
#define PLL_RESET 177
#define XTAL_LC 183
unsigned long frequency = 7000000; //目的周波数
const unsigned long XtalFreq = 25000000; //水晶発振器の周波数
unsigned long divider;
unsigned long PllFreq;
unsigned int mult;
unsigned long l;
float f;
unsigned long num;
const unsigned long denom = 1048575;
unsigned long P1;
unsigned long P2;
unsigned long P3;
void setup()
{
Wire.setSDA(12); //SDA
Wire.setSCL(13); //SCL
Wire.begin(); // Arduino is Master.
Si5351_write(OUTPUT_CTRL,0xFF); //Reg3 Output Enable Control
Si5351_write(CLK0_CTRL,0x80); //Reg16 CLOCK0 Power down
Si5351_write(XTAL_LC,0x92); //Reg183 Crystal Load Capasitance=8pF
divider = 900000000 / frequency; //divider = fvco / fout
if (divider % 2) divider--;
PLLA_set();
MS0_set();
Si5351_write(PLL_RESET,0xA0); //Reset PLLA and PLLB
Si5351_write(CLK0_CTRL,0b01001111); //CLOCK0 Power up 8mA
Si5351_write(OUTPUT_CTRL,0xFE); //Enable CLOCK0
}
void loop()
{
}
void Si5351_write(byte Reg , byte Data)
{
Wire.beginTransmission(Si5351A_ADDR);
Wire.write(Reg);
Wire.write(Data);
Wire.endTransmission();
}
void PLLA_set()//PLL周波数
{
PllFreq = divider * frequency; //fvco =d * fout
mult = PllFreq / XtalFreq; //整数部 mult = a = fvco / fxtal
l = PllFreq % XtalFreq; // L = fvco % fxtal
f = l;
f *= denom;
f /= XtalFreq;
num = f;
//d=divider a=mult b=num c=denom
P1 = (unsigned long)(128 * ((float)num /(float)denom)); //128*(b/c)
P1 = (unsigned long)(128 * (unsigned long)mult + P1 - 512); //128*a + (128*(b/c))-512
P2 = (unsigned long)(128 * ((float)num / (float)denom)); //128*(b/c)
P2 = (unsigned long)(128 * num -denom * P2); //128*b–c*(128*(b/c))
P3=denom; //c=denom
//MSNA_ADDR=Reg26
Si5351_write(MSNA_ADDR + 0,(P3 & 0x0000FF00) >> 8); //Reg26 MSNA_P3[15:8]
Si5351_write(MSNA_ADDR + 1,(P3 & 0x000000FF)); //Reg27 MSNA_P3[7:0]
Si5351_write(MSNA_ADDR + 2,(P1 & 0x00030000) >> 16); //Reg28 MSNA_P1[17:16]
Si5351_write(MSNA_ADDR + 3,(P1 & 0x0000FF00) >> 8); //Reg29 MSNA_P1[15:8]
Si5351_write(MSNA_ADDR + 4,(P1 & 0x000000FF)); //Reg30 MSNA_P1[7:0]
Si5351_write(MSNA_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16)); //Reg31 MSNA_P3[19:16]MSNA_P2[19:16]
Si5351_write(MSNA_ADDR + 6,(P2 & 0x0000FF00) >> 8); //Reg32 MSNA_P2[15:8]
Si5351_write(MSNA_ADDR + 7,(P2 & 0x000000FF)); //Reg33 MSNA_P2[7:0]
}
void MS0_set() //出力分周
{
P1 = 128 * divider - 512; //128*d + Floor(128*(e/f))-512 e=0 f=1 d=divider
P2 = 0;
P3 = 1;
//MS0_ADDR=42
Si5351_write(MS0_ADDR + 0,(P3 & 0x0000FF00) >> 8); //Reg42 MS0_P3[15:8]
Si5351_write(MS0_ADDR + 1,(P3 & 0x000000FF)); //Reg43 MS0_P3[7:0]
Si5351_write(MS0_ADDR + 2,(P1 & 0x00030000) >> 16); //Reg44 MS0_P1[17:16]
Si5351_write(MS0_ADDR + 3,(P1 & 0x0000FF00) >> 8); //Reg45 MS0_P1[15:8]
Si5351_write(MS0_ADDR + 4,(P1 & 0x000000FF)); //Reg46 MS0_P1[7:0]
Si5351_write(MS0_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16)); //Reg47 MS0_P3[19:16]MS0_P2[19:16]
Si5351_write(MS0_ADDR + 6,(P2 & 0x0000FF00) >> 8); //Reg48 MS0_P2[15:8]
Si5351_write(MS0_ADDR + 7,(P2 & 0x000000FF)); //Reg49 MS0_P2[7:0]
}
0 件のコメント:
コメントを投稿