↑ この状態で入手しました


以前にヤフオクで仕入れていた安価なDDSモジュールです

秋月やAitendoにもDDSモジュールは売っていますが、結構高価だったりします
以前オークションで比較的安価に出品されていたので、落札してました。
入手後しばらく部品箱に転がっていましたけど・・・
今回ようやく日の目を見る事となりました。
いわゆる中華DDSなので、どうなるか解りませんが、まずは弄ってみる事にしました。
今回はただの動作実験が目的なので、気負わずお手軽に行ってみます。

参考文献
AD9850データシート ANALOG DEVICES
モジュール回路図等はAitendoの商品ページリンクより

↑ モジュールと基板の接続回路



↑ 基板に乗せました

このままでは使いづらいので、秋月のC基板に乗せて、接続用ピンを配置



↑ 基板背面
配線箇所が見えますでしょうか?
上の画像と左右は同じ
上画像の手前が、この画像の上側です



↑ 汎用CPU基板にPICと各配線

PIC20ピン用CPUモジュール基板使用
汎用ですので、接続ピンが出ているだけ
しかし、使い勝手の良い基板です



↑ ロータリーエンコーダモジュール



↑ 8ビットLED付ジャンパピンモジュール

回路図上ではロータリースイッチとなっていますが、その代わりに使用、6ビット分使います



↑ LED付ボリウムモジュール

RITの代わりに使用します
スイッチはRITスイッチとなります



↑ CPU周囲回路図

20ピンのPIC16F1828使用
すべてのI/Oピンに機能を割り振っています
28ピンで構成した方が良かったかも



↑ 全体構成画像

画像中央のREがメインダイヤル
RSWは10HZステップのつもり
RITはON状態
出力周波数は10MHZ
画像右上は、表示切替SWのつもり
この4ビットタクトスイッチの一番左を押すと、
RIT周波数に表示が瞬時に切り替わります
離すと瞬時に元に戻ります
実験ハードウエア概要

(1)DDSモジュールを乗せる基板の製作

購入したモジュールのままでは扱いずらいので、基板上にAD9850モジュールを差し込み、
PIC基板への接続コネクタを取り付けた、DDS基板構成とします。
今回、実際に製作した物は、このDDS基板のみと言う、超手抜き試作です。

(2)汎用20ピンPICモジュール
  今回使用PICは20ピンの16F1828です

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

(4)8ビット ジャンパピン モジュール
  ロータリースイッチ代わりに使用

(5)VRモジュール
  RIT動作用に使用

(6)8桁7セグLEDモジュール
  AitendoのSPI7セグLEDモジュール、何度か使用しています

(7)その他
  電源分配モジュール、
  それぞれを接続コードで結線すると左記の回路図となります。

↑ 実験状態で、左側はRF出力

左側配線は画像上から、
 D7(DAT) 白コード
 W_CLK(CLK) オレンジコード
 FQ_UP(LAT) 茶コード
 RESET(RESET) 緑コード

 VCC 赤コード
 GND 青コード



↑ DDS出力周波数

10MHZの出力周波数です。
電源投入から、数十HZ動きます。
周波数が安定するまで、数時間を要します。
室内温度によっても、結構変移します



↑ DDS出力波形

10MHZの出力周波数です。
200mV/DIV、50ns
TRIOのテストオシレータと比較して、
輝線が太めで、少々波形も波打っている
感じがしますが・・・
AD9850モジュールの概要

入手したモジュールの姿かたちは、Aitendoで売っている同名DDSモジュールと
かなり似ています。
しかし、Aitendoの販売価格と比較して、当局の入手価格はかなり安価なので、
当局入手品はバチモンかも・・・ (^_^;)
まずは、その商品ページに記載されている資料やリンクを参照しています。
資料が英文なので、英語力の無い当局ではすべてを読んで理解するのは不可能です
断片的にWeblioを利用して翻訳、勝手に解釈しています。

回路図をざっと眺めると、AD9850中心に周辺CR類およびLPFが乗っています。
基板上X'TAL発振器は125MHZで、微調整は不可の様です・・・
制御はパラレルあるいはシリアルデータ転送でコマンドを送るみたいで、
シリアル制御は3線SPIの様な感じです。
今回は、このシリアルデータ転送を使用する事とします。
コマンドやデータは40ビット(5バイト分)で1パケットとなるようです。
そのうち、周波数データは32ビット、その他は各種設定ビットの様です。

シリアル制御ピン
PIC側(任意I/Oピン)  モジュール側
 DAT             D7(J5-6)
 CLK             W_CLK(J5-5)
 LAT             FQ_UP(J5-4)
 RESET           RESET(J5-3)

AD9850モジュール各ピン用法概要
注意
この記載事項について、当局では一切の責任を負いません。

J1 シリアル/パラレル切替
   ON(ショート)で使用

J2 矩形波出力
   OFF(オープン)で使用

J3 DAC電流
   ON(ショート)で使用

J4 LPFを通らないDAC出力
   使用しない

J5 各種制御
  -7 GND
  -6 D7(シリアルデータ入力)
  -5 W_CLK(シフトレジスタへ書込みクロック)
  -4 FQ_UP(シフトレジスタのラッチアップ)
  -3 RESET
  -2 VCC
  -1 V-ADJ(内部でJ3-1と接続、J3でGNDに落とします)
    ※ 基板上から見てX'TAL側から1ピン

J6 パラレルデータピン(使用しませんが、ポート値=x3H固定)
  -7 D6
  -6 D5
  -5 D4
  -4 D3
  -3 D2(内部でJ1-2と接続、J1でGNDに落とします))
  -2 D1(内部プルアップ済、ピン解放で1のままとなる)
  -1 D0(内部プルアップ済、ピン解放で1のままとなる)
     ※ 基板上から見てX'TAL側から1ピン

J7 出力ピン(3,4,5ピンを出力に使用、他は使用しない))
  -7 コンパレータ入力
  -6 コンパレータ電位
  -5 GND
  -4 正弦波出力(RF出力として使用)
  -3 GND
  -2 矩形波2出力
  -1 矩形波1出力
     ※ 基板上から見てX'TAL側から1ピン
  

また、今回表示にはAitendoのSPI接続8桁7セグLEDを使用します。
よって、PIC側ではSPIバスを2ポート用意する必要があります。
VFO周波数表示を、見ずらい液晶モジュールで行う気がしません。
ロータリーエンコーダと設定スイッチをいくつか使用します。
主用途としてはVFOと言う事になりますので、HF帯を生成できればOKと言う事になります。
まさかこれでAMラジオの局発には使用しないでしょう



命令パケット(命令ワード)送信方法の実験

 PIC側 - AD9850側
 DAT     D7
 CLK     W_CLK
 LAT     FQ_UP


命令送信シーケンス
 概要
 W0はパラレル受信モードでの最初のコマンドワード(8bit)
 シリアル受信モードにする場合、最初はW0=x3Hとし、レジスタにロード、
 そして、ラッチさせると、シリアル受信モードとなる
 パラレル入力ポートはハードウエアでx3Hとなる様に設定されている
 その後は40ビットのデータをLSBより送信する。

①LAT=L、CLK=L、W0=x3H(パラレル値固定なのでデータ設定は不要)
②CLK1パルス送信(L→H→L)
③LAT1パルス送信(イネーブル シリアルモード)

④DATにデータビットを提示、(bit0からbit39まで順番に提示)
⑤CLK=L→H(シフトレジスタにデータビットをロード)
⑥CLK=H→L、④に行く、これを40回繰り返す。
  40ビット分がシフトレジスタにロードされたら⑦に行く

⑦LAT=L→H、40ビットのワードがラッチされる。
⑧必要に応じて次のワードを送信するため、④に行く

DDS出力周波数設定サブルーチンの考察

SPI用低レベルルーチンは過去に作成した物を使い回すので、簡単です。
発振周波数に関しては、10MHZ固定値を送信してみました。
すると、意外とあっさりと出力してくれましたので、驚いています・・・
もっとハマるかと思っていました。
とりあえず指定の周波数で出力するようですが、オシロの輝線がちょっと太いかな・・・
当局はスペアナが無いので、出力信号の質に関しては不明ですけど・・・

ここでは周波数可変をどうするかが考察点です。
VFOならば、10HZ単位で、できれば1HZ単位で周波数可変したい。
計算式はデータシートに提示されているのですが・・・
アッセンブラで浮動小数点の演算ルーチンに手を出したくないです・・・
と言うより、無理・・・ (^_^;)

1HZや10HZが整数値で無いので、周波数可変時に四捨五入値をどんどん積み重ねると、
表示周波数と生成周波数との誤差が無視できないくらい大きくなります。
近似値の掛け算は、極力やりたくないですしね。
かと言って、1HZや10HZ単位で全データを用意するのは、しんどいです。
よって、各桁単位で近似値を用意し、各桁近似値を加算すると言うのはどうでしょうか?
これなら70数個程のデータを用意し、その中から8個のデータを加算すれば、
1HZ単位の莫大な数の周波数データを合成できます。
この程度の加算なら許されるのでは?
と言っても、誤差は意外と解らない程の結構な精度です

出力周波数計算式は、
 FOUT=(FRQ×CLKIN)/2^32 より
 FRQ=FOUT*2^32/CLKIN

ここで、
2^32=4294967296
CLKIN=125000000

よって、求める11.111111MHZのFRQは、

1HZ=34.35973837⇒22H
10HZ=343.5973837⇒158H
100HZ=3435.973837⇒D6CH
1KHZ=34359.73837⇒8638H
10KHZ=343597.3837⇒53E2DH
100KHZ=3435973.837⇒346DC6H
1MHZ=34359738.37⇒20C49BAH
10MHZ=343597383.7⇒147AE148H

以上の8ケタ分の16進近似値を加算します。

この方法で作成した、DDS用データ生成プログラムが
「GET_DDS}と言うラベルのサブルーチンです。
これが、指定周波数に対応した、DDSデータFRQを生成します。
詳細はソースリストをご覧ください。
この後はDDSにデータを送信すると、指定周波数を出力します。
ロータリーエンコーダをぐるぐる回すと、結構高速で広範囲に追従します。
DDSに対するFRQ送信ルーチンが、
「SEND_DDS]と言うラベルのサブルーチンです。
PIC16F1828 DDS-VFO
実験プログラム
アッセンブラ・ソースファイル

 16f1828_ad9850_test01.asm

使用ツール
MPLAB’X IDE Ver3.05
MPLAB’X IPE Ver3.05
PICKIT3

HEXファイル

 16f1828_ad9850_test01.hex


制御PICの全体プログラム

基本的に前出の「PIC16F1705低周波発生器」と同じ流れで制作されています。

(1)ロータリーエンコーダの回転チェック
 1)回転しないなら、何もしないで最初に戻る
 2)回転したなら、指定の数値をアップダウン・カウンタから加算・減算する。

(2)アップダウン・カウンタ値を周波数値として、
 1)DDS処理ルーチンへ渡す
 2)7セグLED処理ルーチンへ渡す
 3)最初に戻る

と言ったあんばいで、割込み処理が無い分、「PIC16F1705低周波発生器」より、
シンプルな構成となっています。
もちろん、作成時間も遥かに短いです
こんな田舎の測定機器が揃っていないアマチュア局が、メーカーしか出来ないような
イメージのあるDDS VFOを、超安価・安直に作ってしまうのは、良い事なのでしょうか?

ちょっとお楽しみが少なかったので、IF差分指定、RIT、の機能を付けてみました・・・
RITに関してはADコンバータおよびボリウムを使用します。
これのプログラミングは結構楽しめました・・・ (^_^;)
また、このDDSモジュールの大きな欠点の内の1つの回避策は後述します。



主要ルーチン等の概略

使用ポート設定について

(1)MAX1729 7セグLEDモジュール用SPIバス
 1)RA0:DAT ⇒ DIN (注1)
 2)RA1:LAT ⇒ LOAD (注1)
 3)RA2:CLK ⇒ CLK
  注1)ICSPと兼用

(2)ロータリーエンコーダ入力ポート
 1)RC0:REA ⇒ REA
 2)RC1:REB ⇒ REB

(3)AD9850モジュール用SPIバス
 1)RC2:RESET ⇒ RESET
 2)RB4:LAT ⇒ FQ_UP
 3)RB5:CLK ⇒ W_CLK
 4)RB6:DAT ⇒ D7

(4)RIT制御入力
 1)RA5:H=OFF、L=ON

(5)A/Dコンバータ アナログ入力
 1)RA4(AN3):ボリウムに接続

(6)変化ステップ用ロータリースイッチ入力(H=OFF、L=ON)
 0)すべてOFF(入力H)で1HZ
 1)RC5:SEL1 10HZ
 2)RC4:SEL2 100HZ
 3)RC3:SEL3 1KHZ
 4)RC6:SEL4 10KHZ
 5)RC7:SEL5 100KHZ
 6)RB7:SEL6 1MHZ

MAX1729 7セグLEDモジュール用
(1)事前準備
 1)FLG(ソース内では小文字です)
   8ケタ表示、3,6にドット、ブランク制御有にビット設定
 2)「BCD」をコールし、専用ワークに十進変換しておく
(2)送信
 1)「SETBUF」をコールし、送信バッファにデータを用意
 2)「PUTL」をコールし、モジュールに送信

ロータリーエンコーダ用
(1)使用方法
  右回転でアップカウント、左回転でダウンカウントします
(2)32ビットアップダウンカウンタとなっています。
  使用32ビット変数 FDA0~FDA3
  これが周波数の基本値となり、この変数中心に動作します
(3)変化ステップ指定 RESP0~RESP2
  この24ビットの変数に設定された数値でアップダウンします。
  ロータリースイッチ等で変化量を指定して使用します。
  1カウントあたりの変化ステップは1HZ~1MHZの6種類となっています。

AD9850モジュール用

(1)DDS出力周波数の計算し、FRQ0~FRQ3に用意
  「GET_DDS」をコールします
  とりあえずこのルーチンが今回のプログラムの肝となります。
  これはFDAxの周波数をDDS用の設定値に変換します
  1HZの分解能で動作し、FRQxに32ビットデータを出力
(2)「SEND_DDS」モジュールへ送信
  事前に用意されたFRQxの32ビット周波数データ+制御用8ビットの
  40ビットDDS用データパケットを送信します。

RITボリウム、IF差分用

(1)「MODE」フラグ
  このバイトは8bitの動作フラグとして使用しています。
  メインルーチンの前に初期設定部分があり、ここで動作設定を行います。
  RIT機能およびIF差分機能の設定を行います。
  動作中に変更はできません、この部分の設定数値変更にてのみ対応します。

(2)RITボリウムおよびスイッチ
  ボリウム位置は、中央をゼロとし、左右+-絶対値で処理します。
  左右どちらを+とするかは、MODEフラグで設定します。
  分解能は±63STEPで、1STEPあたりの変化周波数はMODEフラグで設定
  以上の処理は「RITM」サブルーチンで行います。
  尚、隠し機能としている訳では無いですが・・・
  RA3を0にすると、7セグLED表示がRIT変化周波数に変わります。
  回路図上、そのためのタクトスイッチ等は記載されていません。
  デバッグ用だったのを、メインプログラムに埋め込んだだけですが、
  2行表示のLCDと表現力で負けない様、操作性を少々考慮しましたけど・・・
  できれば7セグLEDを2つ使いたかったが、ポートが足りなかった・・・
  28ピンPICなら、さらに表現力の良いグラフィカルな表示デバイスが使えそうです。
  この表現力に関しては、今後の課題と言うより、楽しみとなりそうです。



DDSモジュール内基準クロック補正について

このDDSモジュールの欠点の内の1つ、内部基準クロックですが、
これがハードウエア的に微調整等できないようです。
外部クロックに改造し、高精度発振器を接続と言う手もありますが・・・
こんな小さな基板を弄る気になりません、と言うか見えません・・・ (^_^;)
ならば、プログラムで補正するしかありません。

当局が今回使用したモジュールはDDS出力を周波数カウンタで計測すると、
10MHZ出力を測定すると、数時間程で9.999.964HZで安定となります。
36HZ程低い周波数を発生している事になります。(注1)
これは、20MHZ出力で72HZ、5MHZでは18HZ低くなります。
逆算すると、124.999549MHZとなり、450HZ程下方にずれている勘定になります
これを可とするか否とするかは、何とも言えませんが・・・ 

10MHZのDDSデータ標準値(125.000000MHZで計算)は147AE148Hですが、
再計算後は、147AE61FHとなり、1~2HZ以内の満足した10MHZとなります。(注1)
補正については、DDSモジュール内のX'TAL発振周波数を何らかの方法で求め、
当局は標準値による出力を周波数カウンタで求め、逆算しています。
そして、その発振周波数で再計算するのが、てっとり早く補正できると思います。

注1)
基準は当局SSG 「KSG4310」で校正した、周波数カウンタ「SC-7210」によるもの
普遍的な精度で表現している訳ではありません



ADC出力データのバタつきについて

今回、意外な所で少々ハマりました・・・
それは、ADコンバータの出力データの末尾がバタつく事です。
今までもそれは把握していましたが、それ程考慮する必要が無かった。
RITではバタつきあると困るので、完全に無くせるか試行錯誤してみました。
多分、一番時間が掛かったかも・・・でも、結局完全には無くせませんでした

結局対策としては、下記の通りです。
①VRにすぐ傍にパスコン、VRへのVDD・GNDラインはPICの傍から取る

②下位ビットの破棄
  率直に効果的ですけど・・・当然分解能が下がります。
  今回は下位3ビットを破棄し、7ビットで使用しています。
  傍にTS520を置いて、実際DDS信号を受信して決めました

③VRを低抵抗値とする
  内部コンデンサの放電時間を早くする意図があります
  少々効果があるようです。
  今回は、あまり大きな電流をVRに流したくないので、5KΩを使用しています。



考察および追記等

今回は単にVFO部分単体、特に制御マイコンの試作を中心に製作しただけです
スプリアス等を測定する機器が、当局には無いのでRFの質は不明です
実際には受信機等に、このDDSを使用してみないと使い物になるのか何とも言えません。
プログラムのバグも実機に使用しないと、なかなか出てきません。
その辺は今後の課題として、何か製作してみたいとは思いますが、いつになる事やら。

早速2日で追記です。
少々ADCのバタつきが良くなったので、ソースの不要なウエイトを削除
これで、操作性が良くなりました
そして、回路図のミス、以上の2カ所を修正しています。
戻る  実験・製作の記録TOPへ戻る