Si5351Aを使ったVFOを作りたいと思い、この2週間ほど、Si5351の説明書を読んだり、Webサイトを参考にしたりして、実験をしていました。
参考にしたWebサイトは、
そして、ML仲間のJA2GQP局のブログ 「JA2GQP's BLOG」 です。
JA2GQP局のブログのスケッチでは、Hans Summers氏作のヘッダーファイルが使われています。
任意の周波数を発生させるには、どのようにPLLレジスタとMultiSynthレジスタを設定したらよいのでしょうか。
計算式を再度掲載します。
さて、問題は、希望の周波数foutに対して、上記のa,b,cをどのような値にしたらよいかです。
混乱しやすいのですが、実は、PLL周波数設定用のa,b,cと出力分周器設定用のa,b,cは別物なのです。
そこで、分周器設定用のa,b,cをd,e,fとして、各値(a~f)の計算方法は、次のようになります。
Image may be NSFW.
Clik here to view.
Clik here to view.

JA2GQP's ブログで使われているスケッチでは、c の最大値 c=denom=1048757が、使われています。
PLLの周波数を設定するa,b,c,d(mult,num,denom,divider)とパラメータP1,P2,P3を計算するスケッチは、次のようになります。(Hans Summers氏作です)
(uint32_t は、符号なし32ビットで、unsigned longと同じです。uint8 は符号なし8ビットで、byteと同じです。)
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;
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;
divider = 900000000 / frequency;
if (divider % 2) divider--;
pllFreq = divider * frequency;
if (divider % 2) divider--;
pllFreq = divider * frequency;
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;
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;
このパラメータをPLLAにセットアップするスケッチです。
(MSNA_ADDRは、PLLAパラメータセットアドレスの先頭アドレス26です)
Si5351_write(MSNA_ADDR + 0,(P3 & 0x0000FF00) >> 8);
Si5351_write(MSNA_ADDR + 1,(P3 & 0x000000FF));
Si5351_write(MSNA_ADDR + 2,(P1 & 0x00030000) >> 16);
Si5351_write(MSNA_ADDR + 3,(P1 & 0x0000FF00) >> 8);
Si5351_write(MSNA_ADDR + 4,(P1 & 0x000000FF));
Si5351_write(MSNA_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16));
Si5351_write(MSNA_ADDR + 6,(P2 & 0x0000FF00) >> 8);
Si5351_write(MSNA_ADDR + 7,(P2 & 0x000000FF));
Si5351_write(MSNA_ADDR + 1,(P3 & 0x000000FF));
Si5351_write(MSNA_ADDR + 2,(P1 & 0x00030000) >> 16);
Si5351_write(MSNA_ADDR + 3,(P1 & 0x0000FF00) >> 8);
Si5351_write(MSNA_ADDR + 4,(P1 & 0x000000FF));
Si5351_write(MSNA_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16));
Si5351_write(MSNA_ADDR + 6,(P2 & 0x0000FF00) >> 8);
Si5351_write(MSNA_ADDR + 7,(P2 & 0x000000FF));
分周器MS0のパラメータの計算は、
d=divider e=0 f=1 として、上記のPLL周波数の計算とレジスタセットと同様に行います。
MS0の先頭アドレスは、42です。
なお、スケッチ全体は、VFOができた時点で掲載します。