3CHクロックジェネレータSi5351Aの実験
2016.12.21 JH7UBC
Si5351Aは、SiliconLaboratories社の3チャンネルクロックジェネレータです。
秋月電子で販売しているモジュールを購入して、実験を行いました。
モジュールの大きさは、10mm×10mmと小さいです。価格は500円でした。
このモジュールをArduino UNOでコントロールする実験を行いましたので、紹介します。
Si5351の内部は、下図のように、2つのPLLと3つのMultiSynth(分周器)などから構成されています。
(上図は、メーカーの説明書より)
PLLの源発振器には、25MHzの水晶が使われています。
MultiSynth0〜2の分周器の後には、それぞれ1/1〜1/256のポスト分周器R0〜R2と出力用のドライバがあります。
これらのPLLとMultiSynth、ポスト分周器、ドライバなどを内部レジスタにより、コントロールしています。
内部レジスタ(8bit)は256個ありますが、実際に使用されているのは187番地までです。
各レジスタの設定は、I2Cによって各番地に書き込むことによって行います。
レジスタマップは、Silocon Labの説明書AN619を参照します。
CLK0に10MHzを出力させる実験
まず、PLLAとMultiSynth0を使って、10MHzを発生させてみます。
PLLA=800MHzとして、MultiSynthを80とすれば、CLK0に10MHzが出力されるはずです。
PLL周波数とMultiSynth設定のための設定値とレジスタにセットするパラメータの計算式は、次の通りです。
(Floorは小数点以下切り捨ての意味)
(PLL設定用の値a,b,cと分周器設定用の値a,b,cは別なものです。)
fxtalは水晶の発振周波数で、このモジュールでは、25MHzです。
b=0,c=1とすると、a=fvco/fxtal=800/25=32となります。
a=32,b=0,c=1とすると、パラ―メータP1,P2,P3は次のような値になります。
P1=128×32+(128×(0/1))−512=3584=0b0000 1110 0000 0000 P2=128×0-1×(128×(0/1))=0 P3=1 |
PLLAの設定は、レジスタ26〜33(MSNA)にP1,P2,P3を次のようにセットします。
(P3[15:8]は、P3のbit15〜bit8を表します。)
次にMultiSynth(分周器)に80をセットするためにa=80,b=0,c=1とすると
パラメータP1,P2,P3は次のようになります。
P1=128×80+(128×(0/1))−512=9728=0b0010 0110 0000 0000 P2=128×0-1×(128×(0/1))=0 P3=1 |
MultiSynth0の設定は、レジスタ(MS0)42〜49に次のようにセットします。
Arduino UNOからSi5351AにI2C通信でデータを送るには、Wireライブラリを使います。
Si5351AのI2Cアドレスは、0x60で、Si5351Aのデータの書き込みフォーマットは、次の通りです。
今回は、1バイト書き込みのフォーマットを使います。
1バイト書き込みのスケッチは、次のようになります。
void Si5351_write(byte Reg,byte Data) } Wire.beginTransmission(0x60); Wire.write(Reg); Wire.write'(Data); Wire.endTransmission();; { |
Si5351Aに目的の周波数を発生させる手順は、次のように行います。
この手順に関係するレジスタ3,16,177の設定内容です。
この実験のスケッチは、次のようになります。
#include <Wire.h>//I2Cライブラリをインクルード const byte Si5351_ADDR = 0x60; void setup() { Wire.begin(); // Arduino is Master. Si5351_write(3,0xFF); //Disable Output Si5351_write(16,0x80); //CLOCK0 Power down PLLA_set(); MS0_set(); Si5351_write(177,0xA0);//Reset PLLA and PLLB Si5351_write(16,0x4F); //CLOCK0 Power up 8mA Si5351_write(3,0xFE); //Enable CLOCK0 } void loop() { } void Si5351_write(byte Reg , byte Data) { Wire.beginTransmission(Si5351_ADDR); Wire.write(Reg); Wire.write(Data); Wire.endTransmission(); } void PLLA_set() { Si5351_write(26,0); //MSNA_P3[15:8] Si5351_write(27,1); //MSNA_P3[7:0] Si5351_write(28,0); //MSNA_P1[17:16] Si5351_write(29,0b00001110); //MSNA_P1[15:8] Si5351_write(30,0); //MSNA_P1[7:0] Si5351_write(31,0); //MSNA_P3[19:16]MSNA_P2[19:16] Si5351_write(32,0); //MSNA_P2[15:8] Si5351_write(33,0); //MSNA_P2[7:0] } void MS0_set(){ Si5351_write(42,0); //MS0_P3[15:8] Si5351_write(43,1); //MS0_P3[7:0] Si5351_write(44,0); //MS0_P1[17:16] Si5351_write(45,0b00100110); //MS0_P1[15:8] Si5351_write(46,0); //MS0_P1[7:0] Si5351_write(47,0); //MS0_P3[19:16]MS0_P2[19:16] Si5351_write(48,0); //MS0_P2[15:8] Si5351_write(49,0); //MS0_P2[7:0] } |
Arduino UNOとSi5351Aを下図のように接続します。
Si5351AのVDDとVDDOには、3.3Vを加えます。
Si5351AのI2Cバスは3.3Vなので、ARDUINO UNO(5V)の間にI2Cレベル変換モジュールPCA9306を入れました。(2017.10.16追記)
(直接Arduinoに接続しても問題は起きなかったのですが、Si5251Aの最大入力が4.1Vですので、安全のために入れました。)
Ardiono UNOとブレッドボード上のSi5351Aをジャンパー線で接続し
上記のスケッチをArduino IDE 1.6.12でコンパイル・ロードしました。
スケッチのサイズは、約2kBです。
このスケッチのままですと、やや低い周波数(-250Hz程度)が発生します。
そこで、水晶振動子の負荷容量を8pFに変更してみます。(デフォルトは、6pFです。)
負荷容量の設定は、レジスタ183のビット7とビット6で行います。
01で6pF
10で8pF
11で10pFです。
負荷容量を8pFに変更するには、Si5351_write(183,0x80);を
PLLA_set();の前に加えます。
変更した時の周波数です。(-80Hz程度)
秋月電子のモジュールでは、負荷容量は8pFに指定されています。
この時の出力波形です。
これで、10MHzの信号が発生していることが確認できました。
次は、任意の周波数を発生させてみます。
Si5351Aの実験その2