↑ すでに曲のピンをはんだ付けしてます


Amazonで購入した標記DDS基板です

秋月ではこのシリーズのDDSは販売しなくなった様です。
Amazonで調味料を買うつもりで、(一応主夫ですので)サイト内をあちこち見てたら、思い付きで検索掛けたら、0.8K\位で出て来ました・・・
そして、購入者の評価すこぶる悪・・・
と言いながら思わずポチっとな、としてしまった・・・
本家中国のサイトではもっと安価に売っているのでしょうけど、何か怖いしね。
プライム対象品で、注文後すぐ送られてきました。
不良品かどうか不安だったので、 (^_^;)
即興で作成したプログラムで、とりあえず動作確認しましたです・・・
意外や、ちゃんと動作しました (^^♪
メーカーサイトに日本語マニュアルが存在するのは助かります。

参考文献
AD9833データシート ANALOG DEVICES


↑ 実験回路全体観






↑ 使用した実験基板

 DIPスイッチが付いているので、こう言う実験には便利




実験ハードウエア概要

(1)DDS基板
  購入した基板は、画像のように基板上にAD9833と水晶発振器と、
  コンデンサ数個と言うシンプル構成。
  でも、当局ではIC単体は扱えないので、助かります。
  基板に付属していたピンは使用せず、L字タイプの細ピンをはんだ付け。
  これによりシングルラインの丸ピンICソケットに挿入可能です。
  今回は実験なので、ピンソケットで接続してます。
  SPIによるシリアル接続なのは接続配線が楽で良いです。
  これをPIC実験基板に接続します。
  アナログ出力はオシロへ接続

(2)SPI機器プログラム開発用実験用基板
  これは当局公開の「南波君」基板を改造したもので、
  4bit列と2bit列のI/Oが使用でき、
  4bitのロータリーDIPが付属しています。
  SPIやI2C機器のプログラム作成やちょっとしたI/O実験に便利
  今回使用PICは20ピンの16F18346です

(3)ロータリーエンコーダモジュール
  以前にも使用しています

(4)オシロスコープ
  アナログオシロで、KenwoodのCS-5370です。
  当局実験テーブル用メインオシロは故障中です・・・ (-_-;)




↑ DDSモジュール

右側ピンは画像上から、

①VCC:電源ピン
②DGND:デジタルGNDピン
③SDATA:SPIデータ
④SCLK:SPIクロック
⑤FSYNC:スレーブセレクト(SS)
⑥AGND:アナログGNDピン
⑦OUT:DAC出力ピン

番号は当局が勝手につけた番号です






AD9833モジュールの概要

入手したモジュールの姿かたちは、「AD9833」で検索すると、何故か真っ先に出現する基板の様です。
送られてきた物は基板とピンだけで、資料等の付属は何も無し。(想定内)
基板の出力ピンに名前が記されているので、メーカーサイトの日本語マニュアルを入手すれば、とりあえず大丈夫そうです

後はマニュアルを読むだけですが・・・
日本語で書いてはあるが、よく解らん (^_^;)
で、読める内容の内、必要そうなとこだけを読む事に・・・ 

まず、
①5.5V以下で使えば良い事
②信号タイミングは結構高速で、PIC16F1の動作速度では考慮不要な事
③内部レジスタは、PIC側から見て16bit構成である事
④レジスタはコントロール、周波数、位相の3種類がある事
⑤SPI送信で、16bit単位で送信処理すれば良い事
と言う事が分かりましたです・・・

ならば、16bitのSPI送信関数を作り、適当に送信してみれば、何となく解って来るだろうと言う、いつものアマチュア思考・・・ (^O^)/

インターフェイスはSPIに準拠していると書いてある
よって、PIC・MSSPのSPI解説を斜め読み
⑥ビットはMSBから送信すれば良い事
⑦SSポートを普段Hに、データ送信時にLにして16bitデータ送信
⑧終了したら、SS=Hにして終了
⑨CLKはLになるとDATAビットを取り込む

以上①~⑨で16ビットSPI低レベル基本関数が作れそうです。
SS(スレーブセレクト)ポートは以後LATポートと記します。

今回のピン接続状況
PIC基板側     モジュール側(全7ピン)
 CLK RC0    ④SCLK
 DAT RC1    ③SDATA
 LAT RC2    ⑤FSYNC
 VCC        ①VCC
 GND        ②デジタルGND
オシロ
 AC入力       ⑦VOUT
 GND        ⑥アナログGND





↑ 100KHZ

Y軸 100mV





↑ 500KHZ






↑ 1MHZ






↑ 2MHZ






↑ 3MHZ






↑ 4MHZ






↑ 5MHZ






↑ 6MHZ

波形が汚くなってきたため、オシロの内蔵カウンタが誤動作してます





↑ 7MHZ

これも内蔵カウンタが誤動作してます
次画像でY軸を伸ばします






↑ 7MHZ

Y軸が50mV






↑ 7.2MHZ

 Y軸が50mV







↑ 8MHZ

 Y軸 100mVに戻しました。







↑ 9MHZ

 Y軸 50mV







↑ 10MHZ








↑ 11MHZ


もやは何だか分かりません・・・
カウンタも誤動作してます

AD9833モジュールの制御

注意
この記載事項について、当局では一切の責任を負いません。

(1)レジスタ
 レジスタには、コントロールレジスタ、FREQレジスタ2つ、
 PHASEレジスタ2つが存在します。
 それぞれ16ビットのワード1つ、あるいは2つでアプローチします。
 読み込みは出来ない
 各レジスタ共通事項としては下記のビットとなります。

bit15-14:レジスタ選択ビット
   00:コントロールレジスタ
   01:FREQ0レジスタ(周波数レジスタ0)
   10:FREQ1レジスタ(周波数レジスタ1)
   11:PHASExレジスタ(位相レジスタ)

(2)コントロールレジスタ(CTRL)
 DDSの動作指令等他を行います

bit13:B28
      周波数レジスタ書き込み方法指定ビット
    1:周波数レジスタに2ワード連続書き込む
    0:周波数レジスタ上位下位どちらか1つに書き込む

bit12:HLB
      bit13=0の場合の補足指定
    1:周波数レジスタの上位ワードに書き込み
    0:周波数レジスタの下位ワードに書き込み

bit11:FSELECT
      位相アキュムレータで使用する周波数レジスタ選択
    1:FREQ1レジスタ
    0:FREQ0レジスタ

bit10:PSELECT
      位相アキュムレータ出力に加算する位相レジスタ選択
    1:PHASE1レジスタ
    0:PHASE0レジスタ

bit9 :予約 常に”0”指定

bit8 :RESET
      パワーオン後は一度行った方が良いと書いてある
      周波数、位相、コントロールレジスタはリセットされない
    1:内部レジスタをリセット
    0:リセットは適用されない

bit7 :SLEEP1
    1:内部MCLKをディセーブル
    0:内部MCLKをイネーブル

bit6 :SLEEP12
    1:内蔵DACをパワーダウン
    0:内蔵DACアクティブ

bit5 :OPBITEN
    1:VOUT出力はデジタル出力
    0:VOUT出力はDAC出力

bit4 :予約 常に”0”

bit3 :DIV2
      VOUT出力がデジタルの場合の選択
    1:DACデータのMSB
    0:DACデータのMSB/2

bit2 :予約 常に”0”

bit1 :MODE
      bit5=0の時選択有効、bit5=1の時はMODE=0とする事
    1:SIN ROMをバイパスし、DACから三角波出力
    0:SIN ROMを使用し、DACからサイン波

bit0 :予約 常に”0”


(3)周波数レジスタ
  FREQ0とFREQ1の2つ存在、機能は同じ
  それぞれ28bitの有効ビットがある。
  1つの周波数レジスタに周波数データ書き込む場合、
  上位ワードと下位ワードに分けて書き込む
  つまり、周波数レジスタの28ビットの内、
  下位14ビット分を含んだワードと上位14ビットを含んだワード、
  2つのワードを、下位ワードから順に連続して書き込む
  各ワードのbit15-14はレジスタ選択ビットである。

 1)周波数レジスタ、FREQ0に28bitを書き込む
  ①CTRLレジスタ書き込み
   bit15:レジスタ選択ビット=0
   bit14:レジスタ選択ビット=0 CTRLレジスタ指定
   bit13:B28=1
   bit12-0:任意だが適切に
  ②FREQ0レジスタ書き込み
   bit15=0:
   bit14=1:FREQ0レジスタ指定
   bit13-0:FREQ0レジスタ下位14bit分
  ③FREQ0レジスタ書き込み
   bit15=0:
   bit14=1:FREQ0レジスタ指定
   bit13-0:FREQ0レジスタ上位14bit分

 2)周波数レジスタ、FREQ1に28bitを書き込む
  ①CTRLレジスタ書き込み
   bit15=0
   bit14=0:CTRLレジスタ指定
   bit13:B28=1
   bit12-0:任意
  ②FREQ1レジスタ書き込み
   bit15=1:
   bit14=0:FREQ1レジスタ指定
   bit13-0:FREQ1レジスタ下位14bit分
  ③FREQ0レジスタ書き込み
   bit15=1:
   bit14=0:FREQ1レジスタ指定
   bit13-0:FREQ1レジスタ上位14bit分

 3)周波数レジスタ、FREQ0の下位14bitを書き込む
  ①CTRLレジスタ書き込み
   bit15=0
   bit14=0:CTRLレジスタ指定
   bit13:B28=0
   bit12:HLB=0
   bit11-0:任意
  ②FREQ0レジスタ書き込み
   bit15=0:
   bit14=1:FREQ0レジスタ指定
   bit13-0:FREQ0レジスタ下位14bit分

 4)周波数レジスタ、FREQ1の上位14bitを書き込む
  ①CTRLレジスタ書き込み
   bit15=0
   bit14=0:CTRLレジスタ指定
   bit13:B28=0
   bit12:HLB=1
   bit11-0:任意
  ②FREQ1レジスタ書き込み
   bit15=1:
   bit14=0:FREQ1レジスタ指定
   bit13-0:FREQ1レジスタ上位14bit分

(4)位相レジスタ
  周波数レジスタと同様にPHASE0とPHASE1の2つある
  それぞれ12bitの有効ビットがある。
  位相レジスタは1ワードで完結するため、書き込みはCTRLを介さない

 1)ビット構成
   bit15=1
   bit14=1:PHASEレジスタ指定
   bit13:P1/P0
       1=PHASE1レジスタ指定
       0=PHASE0レジスタ指定
   bit12-0:有効データビット



AD9833DDS

デモ・プログラム(RE・DIP使用)

 XC8_16F18346_AD9833_DEMO.c


インクルード・関数群

 搭載LCD用

 SC1602v1_SPIB.h_

 SC1602v1_SPIB.c


 AD9833DDS用

 AD9833v1.h

 AD9833v1.c

 ロータリーエンコーダ用

 R_ENCODERv1.h

 R_ENCODERv1.c
PICプログラム

XC8で作ってみました。
当局としては珍しくASMによる事前実験はしてないです・・・
発生周波数の上限性能がそれ程でも無さそうと言うか
以前のAD9850の実験みたいに気持ちが入っていないと言うか、
とりあえずの動作確認用なので、色々問題点はあるかと思いますがご勘弁を・・・



(1)生成周波数の計算
  当然の事ながらマニュアルに計算式が示されており、下記の通りです

  VOUT(周波数)=(FMCLK÷2の28乗)×FREQレジスタ値

   注)FMCLK=25MHZ
     2の28乗=268435458

  a)FREG=A3D70AHの場合(1MHZ生成)

   VOUT=25000000÷268435458×10737418
       =999999.97(Hz)

  b)FREG=147AE14Hの場合(2MHZ生成)

   VOUT=25000000÷268435458×21474836
       =1999999.94(Hz)

  さて、XC8にこの計算式を記述するのかいな・・・
  億の桁の数値が入るが・・・
  と心配しましたが、意外と早く計算関数から戻ってきました。


(2)AD9833制御関数 Ver1
  XC8用関数です。
  「double」数値を使っているので、XC8グローバルオプションにて、
  32bitを指定した方が演算精度が上がると思います。
  デモでは、1),7),8)の3つの関数しか使用していませんが、
  取り合えず全関数の動作実験はしています。
  見ての通り、やっつけ仕事的な関数ばかりで、
  申し訳ありませんです・・・ <m(__)m>



1)SET_FREG0S(unsigned long 引数)
   引数を周波数レジスタ0に格納し、出力はサイン波

   引数:周波数レジスタ0に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無

2)SET_FREG0T(unsigned long 引数)
   引数を周波数レジスタ0に格納し、出力は三角波

   引数:周波数レジスタ0に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無


3)SET_FREG0D(unsigned long 引数)
   引数を周波数レジスタ0に格納し、出力は矩形波

   引数:周波数レジスタ0に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無


4)SET_FREG1S(unsigned long 引数)
   引数を周波数レジスタ1に格納し、出力はサイン波

   引数:周波数レジスタ1に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無

5)SET_FREG1T(unsigned long 引数)
   引数を周波数レジスタ1に格納し、出力は三角波

   引数:周波数レジスタ1に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無


6)SET_FREG1D(unsigned long 引数)
   引数を周波数レジスタ1に格納し、出力は矩形波

   引数:周波数レジスタ1に格納する32bitデータ
      有効なのは下位28bitです。
   戻値:無


7)INIT_DDS(void)
   DDSにリセットを掛けます。
   周波数・位相・コントロールレジスタはリセットされません。
   使いもしない位相レジスタは、悪さすると困るので、
   手動でデータクリアしています。

   引数:無
   戻値:無


8)SEND16_SPI(unsigned int引数)
   16bitの基本ワードをDDSに送信します。
   これがハードウエアに密着した下位レベル基本関数となります。
   他の殆どの関数がこの関数を呼び出します。

   引数:DDSに送信する1ワード基本的データ
   戻値:無


9)unsigned long CALC_REG(unsigned long引数)
   32bitの周波数データを対応するレジスタ用の数値に変換
   周波数データの単位は”HZ”で1HZ単位で記述
   小数点以下は対応しない

   引数:発生させる周波数データ、単位はHZ
   戻値:周波数レジスタ用に変換した32bitデータ

10)その他
  使用しないので省略



(3)ロータリーエンコーダ入力ポート
  R_ENCORDERv1を使用しています。
  ヘッダーファイルの使用ポートを下記の用に変更しています

 1)使用ポート
   RA4:REA ⇒ REA
   RA5:REB ⇒ REB
 2)使用方法
   右回転でアップカウント、左回転でダウンカウントします
 3)カウント変化量
   1カウントあたりの変化ステップは1HZ~1MHZの6種類となっています。
   デフォルトは1KHZステップです

(4)ロータリーディップスイッチ
  使用ポートはRB7~RB4です。
  ここで待たされるのが嫌で、チャタリング防止用のウエイトを入れていません
  専用関数を呼び出すと、その時点のつまみの位置で、
  0~15の数値が返ってきます。
  この値でロータリーエンコーダーの変化ステップを設定しています。

(5)SC1602LCD
  SC1602v1ライブラリを使用しています。
  使用ポートは下記の通りに変更しています。

   RC7:DB7
   RC6:DB6
   RC5:DB5
   RC4:DB4
   RA2:R/S
   RA1:R/W
   RA1:E





考察および追記等

以前に実験した、AD9850と比較すると高域性能はがっくり落ちます。
4MHZ位までは、まあまあきれいな出力波形ですけど、5MHZを超えると波形の変形が酷くなってきますし、10MHZを超えると波形が不明になりカウンタがカウントしなくなります

用途ですけれど、7M帯の受信機に使えるかどうかなと言った所でしょうか
もちろんそれなりのフィルタは必須でしょうけど
AF~中波帯なら、簡単なLPFで十分使えると思います。



戻る  実験・製作の記録TOPへ戻る