ArduinoでAD9834をコントロールする実験

2015年10月 JH7UBC


ANLOGDEVICES社のDDSチップAD9834(BRUZ)をArduinoで動かす実験をしました。

AD9834チップは、20ピンのTSSOPという非常に小さなICです。
これを2.54mmピッチ変換基板にハンダ付けする作業から始めました。
TSSOPチップのハンダ付けは初めての作業で、緊張しましたが、ブリッジもなくうまくできました。
なお、この作業の詳細は、JH7UBCブログに掲載してあります。

ArduinoでAD9834DDSを製作した例は、JA2GQPさんのブログに記事があります。
この記事を参考にして、(というかコピーさせていただいて)動作実験をしました。

まず、AD9834を動かす方法についてAD9834の説明書をダウンロードして調べました。
AD9834のコントロールの方法は、以前に製作したAD9850DDSとはまったく異なります。

AD9834では、SPI通信により16ビットのコントロールワードと周波数データを2回または3回に分けて送ります。
AD9834の内部には、16ビットのコントロールレジスタ、28ビットの周波数レジスタ2個(FREQ0とFREQ1)、
位相変調用のレジスタ2個(PHASE0とFHASE1)があります。
どのレジスタにデータを入れるかは、16ビットデータの最初の2ビット(D15とD14)で指定されます。
この関係を図にすると次のようになります。

今回は、FREQ0に周波数データを送ります。
周波数データは、28ビットですから、14ビットずつ下位、上位の順にDDSに送ります。
つまり次の図のような順番とデータフォーマットでDDSにデータを送ります。

次にDDSに送る周波数データの計算方法ですが、これは、AD9850DDSの場合と同じですが、次のように行います。
マスタークロックfMCLKは、75MHz以下で、発生希望周波数fは、その半分くらいまで可能ですが、
今回は、マスタークロックは、計算しやすい67.108864MHz=2^26Hzとしました。
この周波数の場合、DDSに送る周波数データΔPhaseは、希望周波数のデータを左に2ビットシフトすることによって得られます。

AD9834のシリアルタイミングは、次の図のようになっています。

さて、ArduinoからAD9834にデータを送るにはどうすればよいでしょうか。
Arduinoには、shiftOut()という関数があり、書式は、shiftOut(dataPin,clockPin,bitOrder,value) です。
 value(8ビット)の各ビットは、bitOrder(MSBFIRST(最上位ビットから)または、LSBFIRST(最下位ビットから)の順に
dataPinに出力され、その後clockPinが反転し、そのビットが有効になったことが示されます。

今回は、dataPinは、SDATA = 4番ピン、clockPinは、SCLK = 5番ピンとし、
データの送信を可能にするFSYNCは、6番ピンに出力することにします。
例えば、wrk(16ビットデータ)をshiftOut関数で送る場合は、次のように2回に分けて記述します。
まず、上位8ビットをMSBから送信します。
shiftOut(SDATA,SCLK,MSBFIRST,(wrk >> 8));
 次に下位8ビットを送信します。
 shiftOut(SDATA,SCLK,MSBFIRST,wrk);

AD9834に周波数データFREQを送る関数は、次のようになります。
(JA2GQPブログのスケッチを使っています。TNX FER JA2GQP)

 
setup()の前にDDS_CLK と TWO_E28を定義しておきます。
const unsigned long DDS_CLK = 56000000L; // AD9834 Clock 56Mhz
const unsigned long TWO_E28 = 268435456L; // 2^28
 実は、今回DDS_CLKを67108864=2^26にしたため、上の2行の記載が不要になりました。
void Fnc_Dds(double frquency){
//unsigned long wrk = frquency * TWO_E28 / DDS_CLK; //wrkは、DDSに送る周波数データ(32ビット)
上の行の記載が不要になり下のようにfrequencyを2ビット左にシフトするだけでOKです。
ただし、引数frequencyのデータ型は、unsigned longにしなければなりません。
unsingned long wrk = frequency << 2;
unsigned int wrk1,wrk2,wrk3;
wrk1 = 0x2000;       //wrk1は、コントロールデータで、28ビットモード
wrk2 = wrk & 0x3fff;    //wrk2は、周波数データの下位14ビットを取り出したもの
wrk2 = wrk2 | 0x4000;   //wrk2にFREQ0を指定するビットを付け加える
wrk3 = wrk >> 14;     //右に14ビットシフトする。
wrk3 = wrk3 & 0x3fff;   //wrk3に周波数データの上位14ビットをセットする。
wrk3 = wrk3 | 0x4000;  //wrk3にFREQ0を指定するビットを付け加える。
digitalWrite(SCLK,HIGH); // SCLKをHIGHにする。
digitalWrite(FSYNC,LOW); //FSYNCをLOWにする。データ送信開始
shiftOut(SDATA,SCLK,MSBFIRST,(wrk1 >> 8)); //コントロールデータを送信
shiftOut(SDATA,SCLK,MSBFIRST,wrk1);
shiftOut(SDATA,SCLK,MSBFIRST,(wrk2 >> 8)); //周波数データの下位14ビットをFREQ0レジスタに送信
shiftOut(SDATA,SCLK,MSBFIRST,wrk2);

shiftOut(SDATA,SCLK,MSBFIRST,(wrk3 >> 8)); //周波数データの上位14ビットをFREQ0レジスタに送信
shiftOut(SDATA,SCLK,MSBFIRST,wrk3);
digitalWrite(FSYNC,HIGH); //FSYNCをHIGHにする、(データ送信終了)
}

ArduinoとAD9834との接続、およびI2CのLCD AQM0802、ロータリーエンコーダーを示す回路図です。

AQM0802への表示方法及びロータリーエンコーダーについては、前の記事を参照してください。

今回の実験では、STEPスイッチが押されるたびに、STEP周波数が、
1MHz→100KHz→10KHz→1KHz→100Hz→10Hz→1MHzと循環します。

ブレッドボード上に組んだAD9834DDSの回路です。

発生させた1MHz正弦波の波形です。

発生できた上限周波数は、約23.6MHzでした。

この実験を元に更に機能を加え、自作トランシーバーのVFOとして使いたいと考えています。

なお、参考までにスケッチ(テキストファイル)です。
(2015.11.3 表示を右詰めに修正しました。)

inserted by FC2 system