Si5351Aの実験その5(位相制御)

2017年10月16日 JH7UBC


3チャンネルクロックジェネレータSi5351Aの出力の位相を制御する方法について説明します。
JA2GQPブログの記事Tj Labのサイトの記事を参考にしました。)
Si5351のレジスタマップAN619の10ページを参照します。
出力信号の位相(遅延時間)を決めるのは、レジスタ165(CLK0),166(CLK1),167(CLK2)の値でその値は、次の式で決定します。

CLKx_PHOFF [6:0] = Round(DesiredOffset (sec) * 4 * Fvco)
N = CLKx_PHOFF[6:0], dt = Desired Offset(delay time)とおくと
N= dt * 4 * Fvco (1) (0<= N <= 127,FvcoはPLLの周波数)
遅延時間dtが決まれば、設定値Nを得ることができます。

今回は、単純化のために位相を90度遅らせる(遅延時間は4分の1周期)ことにします。
出力の周波数をFoutとすると周期T=1/Foutで
dt = T/4 = 1/(4*Fout) (2)

(2)を(1)に代入すると
N = 1/(4*Fout) * 4 * Fvco = Fvco/Fout となります。(ただし、Nは整数で127以下)
今回の実験では、PLLの周波数Fvco=900MHz,出力周波数Fout=10MHz,位相90度(遅延時間T/4)とすると
N=900/10=90 となります。

Si5351Aの実験3(マルチチャンネル化)のスケッチを利用して実験します。
PLLAに分周期MS0,MS1を接続し、CLK0とCLK1に10MHzを出力します。
CLK0は、遅延0,CLK1はT/4遅延します。

Arduino UNOにスケッチを書き込み、出力波形を観測しました。(青がCLK0,赤がCLK1)

4分の1周期位相がずれることが確認できました。
Nの値を変えることによって遅延時間を変えることができます。

回路図です。秋月電子のI2C電圧レベル変換モジュールPCA9306をArduinoとSi5351Aの間に入れました。
Si5351Aだけの接続なら3.3Vに直接接続してOKです。

ブレッドボードです。

参考までに実験に使ったスケッチです。
Nは、スケッチの中では、dividerです。

/*
* Si5351A 位相制御test
* 2017.10.10
* JH7UBC Keiji Hata
* 秋月電子のSi5351Aモジュール使用
*/

#include <Wire.h>

#define Si5351A_ADDR 0x60
#define OUTPUT_CTRL 3
#define CLK0_CTRL 16
#define CLK1_CTRL 17
#define CLK2_CTRL 18
#define MSNA_ADDR 26
#define MSNB_ADDR 34
#define MS0_ADDR 42
#define MS1_ADDR 50
#define MS2_ADDR 58
#define CLK0_PHOFF 165
#define CLK1_PHOFF 166
#define PLL_RESET 177
#define XTAL_LOAD_C 183

uint32_t frequency;
const uint32_t XtalFreq = 25000000;

uint32_t P1;
uint32_t P2;
uint32_t P3;
uint32_t PllFreq;
uint32_t l;
float f;
uint8_t mult;
uint32_t num;
uint32_t denom;
uint32_t divider;
char PLL;
uint8_t PLL_ADDR;
uint8_t MS_ADDR;


void setup(){
Wire.begin(); // Arduino is Master
Si5351_init(); //Si5351 initialize

//PLLAのセット 900MHz,CLK0=10MHz
frequency = 10000000;
divider = 900000000 / frequency;
if (divider % 2) divider--;
PLL_Set('A',frequency,divider);

//CLK0の設定
Si5351_write(CLK0_CTRL,0x4C); //CLK0 Sorce PLLA
MS_Set(0,divider);
Si5351_write(CLK0_PHOFF,0);//CLK0 delay 0

//CLK1の設定
Si5351_write(CLK1_CTRL,0x4C); //CLK1 Sorce PLLA
MS_Set(1,divider);
Si5351_write(CLK1_PHOFF,divider);//CLK1 delay T/4 (90degree)

Si5351_write(PLL_RESET,0xA0); //Reset PLLA and PLLB
}

void loop(){

}

//Si5351のレジスタに1バイトデータを書き込む。
void Si5351_write(byte Reg , byte Data)
{
Wire.beginTransmission(Si5351A_ADDR);
Wire.write(Reg);
Wire.write(Data);
Wire.endTransmission();
}


//Si5351Aの初期化
void Si5351_init(){
Si5351_write(OUTPUT_CTRL,0xFF); //Disable Output
Si5351_write(CLK0_CTRL,0x80); //CLOCK0 Power down
Si5351_write(CLK1_CTRL,0x80); //CLOCK1 Power down
Si5351_write(CLK2_CTRL,0x80); //CLOCK2 Power down
Si5351_write(XTAL_LOAD_C,0x92); //Crystal Load Capasitance=8pF
Si5351_write(PLL_RESET,0xA0); //Reset PLLA and PLLB
Si5351_write(CLK0_CTRL,0x4F); //CLOCK0 Power up
Si5351_write(CLK1_CTRL,0x4F); //CLOCK0 Power up
// Si5351_write(CLK2_CTRL,0x4F); //CLOCK0 Power up
Si5351_write(OUTPUT_CTRL,0xFC); //Enable CLOCK0,CLOCK1
}


//PLLの設定
void PLL_Set(char Pll,uint32_t Freq,uint32_t Div){
PllFreq = Div * Freq;
mult = PllFreq / XtalFreq;
l = PllFreq % XtalFreq;
f = l;
f *= 1048575;
f /= XtalFreq;
num = f;
denom = 1048575;

P1 = (uint32_t)(128 * ((float)num /(float)denom));
P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
P2 = (uint32_t)(128 * ((float)num / (float)denom));
P2 = (uint32_t)(128 * num -denom * P2);
P3=denom;

if (Pll == 'A')
{
PLL_ADDR = MSNA_ADDR;
}else
{
PLL_ADDR = MSNB_ADDR;
}
Parameter_write(PLL_ADDR,P1,P2,P3);
}

//MultiSynth(分周器)のセット
void MS_Set(uint8_t MS_No,uint32_t Div){
P1 = 128 * Div - 512;
P2 = 0;
P3 = 1;
switch(MS_No){
case 0:
MS_ADDR = MS0_ADDR;
break;
case 1:
MS_ADDR = MS1_ADDR;
break;
case 2:
MS_ADDR = MS2_ADDR;
break;
default:
MS_ADDR = MS0_ADDR;
}
Parameter_write(MS_ADDR,P1,P2,P3);
}

//レジスタにパラメータP1,P2,P3を書き込む。
void Parameter_write(uint8_t REG_ADDR,uint32_t Pa1,uint32_t Pa2,uint32_t Pa3)
{
Si5351_write(REG_ADDR + 0,(Pa3 & 0x0000FF00) >> 8);
Si5351_write(REG_ADDR + 1,(Pa3 & 0x000000FF));
Si5351_write(REG_ADDR + 2,(Pa1 & 0x00030000) >> 16);
Si5351_write(REG_ADDR + 3,(Pa1 & 0x0000FF00) >> 8);
Si5351_write(REG_ADDR + 4,(Pa1 & 0x000000FF));
Si5351_write(REG_ADDR + 5,((Pa3 & 0x000F0000) >> 12) | ((Pa2 & 0X000F0000) >> 16));
Si5351_write(REG_ADDR + 6,(Pa2 & 0x0000FF00) >> 8);
Si5351_write(REG_ADDR + 7,(Pa2 & 0x000000FF));

inserted by FC2 system