直線上に配置

DDSデジタルVFO

フレーム

 近作のAMトランシーバにはVXOを使用してきましたが、年々部品の入手がしにくくなり、価格も上がっています。
そこで、以前制作したFEMTO改のVXOに置き換えられるDDSデジタルVFOを作ってみました。
FEMTO改の送信局発と受信第1IFが共に10.7MHzですのでVFOの出力周波数は40MHz付近になっています。

今回使用したDDSはAD9834CRUZ(クロック75MHz版)、制御はATMEL社のAVR(ATmege88P)で、DDSから20MHz付近を出力し、2逓倍して40MHz付近を出力する構成です。
当然クロックの高いDDSを使えば必要な周波数を直接取出せますが、ICやマスタークロック用発振回路の値段が跳ね上がりますので、こんな構成にしました。

DDS制御はATMEL社のAVRチップATmega88PにMCSエレ社BASCOM-AVR (BASICコンパイラ デモ版)で書いたものを載せています。
BASCOM-AVRはBASICで書けますし、周辺制御のコマンドが充実していて大変生産性が良く、ありがたいことにコンパイル容量4kBの制限がありますが無償です。


1 DDS−VFOの機能

 今回DDS-VFOを製作するにあたり、以下の機能などを目標としました。

 ・FEMTOと同軸1本で接続して使用する
 ・出力は50MHz台-10.7MHz(=39MHz台)で1Vpp以上
 ・秋月クリック付RE使用 1クリックあたり5kHz/100kHz切替
 ・表示は16文字x2行キャラクタLCD使用 バックライト無 
 ・FEMTOのPTTと連携した帯域外送信禁止制御(バンド外受信は可)
  *調整後、スプリアスと運用状況から50.000〜50.995MHzを送信可能に設定しました
 ・RIT機能
 ・送受切替時のポップノイズ防止のためミュート信号を出力する
 ・単三電池と外部DCで使用
 ・携帯性を考え、できるだけ小型の筐体とする


2 DDS-VFOのハードウエア

 DDS-ICのAD9834は表面実装用パッケージということもあって、変換基板を使わずに熱転写法でプリント基板を作りました。
作り易い片面基板にしましたが、本来は両面基板にしたいところです。

VFOはホームセンターで見つけた樹脂製パーツケースに収めました。
本体寸法 約W165xD95xH35(つまみ突起部を除く) 完成後の重量340g(電池を含む)
消費電流は12V外部電源で約50mAでした。
大半は64MHzのOSCユニットが食っています。


(回路図はクリックで拡大↓)

VFO基板パターン面 VFO内部の配置

                       ◇

 DDS-VFOは、64MHzマスタークロックのDDSをAVRで制御して20MHz付近を発生させ、ポストアンプ→LPF→逓倍・SW→出力アンプの経路で出力します。
DDSの出力周波数としては、理論的にはマスタークロックの1/2までは可能ですが、1/3程度迄が実用限界の様です。
DDSからのスプリアスがあり、AVR(8MHzクロック)からのノイズがあるので、実験して現在の構成に落ち着きました。 
スプリアスの合間を縫って使う感じで、自由に周波数を設定できるという訳にはいきません。

DDS用クロックOSCは64.000MHz 安価な安定度±100ppm品ですがAMでは実用上問題なく使えます。

ポストアンプは小さいDDS出力を増幅し、AVRのノイズが後段に影響するのを小さくする目的があります。

LPFは入手し易い値で構成できる、カットオフ24MHz、Zo=320Ωの5次0.1dBチビシェフ形です。
当初は定K形2段の設計でしたが、損失と肩特性が不満でしたので変更しました。

逓倍・SW回路は、2逓倍と送信禁止時のスイッチを兼ね、AVRの制御で出力がオン・オフされます。

出力アンプからは1Vpp程度は出力できますが、今回のFEMTO用途ではそんなに要らないので、調整で0.4Vppに抑えました。

出力部にあるフォトカプラでは、同軸ケーブルに重畳された直流でPTTの状態を監視しています。
(トランシーバ側のI/FはFEMTO改の回路図参照)

                       ◇

 FEMTO改とVFOを接続した当初ですが、ロッドアンテナをFEMTO改に直接接続して受信するとAVRからのノイズが強く入りました。
基板のパターン引き回しなどに気を使ったつもりですが、片面基板と樹脂ケースでは予想通りというか、出るべくして出たように思えます。

対策として外部のケーブルに分割コアを取付けたところ大幅に下がり、さらに出力回路のグランド分離とLCD裏へのシールド、パスコン追加などで聞こえないところまで下げることが出来ました。
VFO内部写真の電池の上側で銀色に光っている部分がラミネートフィルムで挟んだシールド用アルミ箔で、回路の−側につながっています。



3 DDS-VFOのソフトウエア

 プログラム制作にはBASCOM-AVRコンパイラデモ版ver.2.0.7.1を使用しました。
BASCOM-AVRにはエンコーダ読込やDDS・LCDキャラクタモジュールへの出力コマンドが用意されているうえ、BASICで記述できるので大変楽にプログラムを作ることができました。

今回のプログラムはコンパイル容量に4kBの制限に収まりましたが、古いバージョンのコンパイラを使用した場合や、内臓フラッシュROMが8kB以上のデバイスを使うとサイズが大きくなりますので注意が必要です。

今回のプログラムです。
スマートでは無いと思いますが動作はしています。
ソースファイルは→ここをクリックして保存してください。
 * このプログラムの使用は自己責任でお願いします。
 * 利益を目的とした頒布や商用利用はできません。

'6mAMトランシーバ用DDS-VFOプログラム AM1.35d1 JA1VZV
'BASCOM AVR DEMO version 2.0.7.1   ※印は用途、接続先、DDS XO個体差により要調整


                          【各種初期設定】
$regfile = "m88pdef.dat"               使用するデバイスを指定
$crystal = 8000000                  クロック周波数を指定[Hz]

'--- config port ---                 ポートの入出力設定 1=OUT
Config Portb = &B10111111
Config Portc = &B0111100
Config Portd = &B11100000

'--- port pullup ---                 ポートのプルアップ設定 1=H
Portb = &B01000000
Portc = &B1111110
Portd = &B00011111

'--- debounce set ---                デバウンス時間設定
Config Debounce = 1                 1mSに設定

'---LCD port assign ---               LCD制御ピン・表示桁数設定
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.3
Config Lcdpin = Pin , Db6 = Portb.5 , Db7 = Portb.4
Config Lcdpin = Pin , E = Portb.2 , Rs = Portb.1
Config Lcd = 16 * 2

'ADC mode setting & start              ADC動作設定・起動
Config Adc = Single , Prescaler = Auto
Start Adc

'---Define Variables---               変数宣言
Dim R As Word                    RIT ボリウムADC値
Dim R1 As Integer                  RIT 計算用
Dim R2 As Integer                  RIT 計算用
Dim R3 As Integer                  RIT ボリウムADC値記憶用
Dim Rd As Integer                  RIT 計算用
Dim N As Word                    メインループ カウンタ値

Dim D As Byte                    逓倍値
Dim I As Long                    中間周波数値
Dim S As Dword                    周波数ステップ (Hz)
Dim Ft As Long                    周波数一時記憶
Dim F As Long                    周波数データ
Dim Ff As Single                   DDS設定データ計算用
Dim Fa As Long                    DDS設定データ計算用
Dim Fb As Long                    DDS設定データ計算用
Dim Fc As Long                    DDS設定データ計算用
Dim Fw As Word                    DDS設定データ
Dim Fs As String * 8                 周波数文字列
Dim Fd As String * 9                 周波数表示用文字列
Dim Tr As String * 2                 送受モード表示文字列

'---Variables initialize---
N = 0                        ループカウンタリセット
D = 2                        逓倍初期値設定 =2 ※
I = 10700000                     IF周波数設定 [Hz] ※
S = 5000                       ステップ初期値設定[Hz] ※
Tr = "Rx"                      モード表示"Rx"設定
F = 50620000                     デフォルト周波数設定[Hz] ※
R3 = 1026                      RIT VR初期値設定

'---LCD inital display ---              LCD初期表示設定
Cls                         表示全消去
Cursor Off                      LCDカーソルoff
Lowerline                      下段に
Lcd "AM1.35d1 JA1VZV"                バージョン表示 ※

'--- Timer set ---
Config Timer1 = Timer , Prescale = 8         割込みタイマ65.5mSに設定
On Timer1 Dsp                    タイマ割込みでDspを実行
Enable Interrupts                  全割込み許可
Enable Timer1                    Timer1割込み許可

'---Send control word to DDS---
Fw = &H2000                     DDSの制御パラメータ設定
Gosub Dsd                      DDSへ送信
Gosub Dds                      DDSへデフォルト周波数設定
Portd.6 = 1                     RX 制御ピンON

'*** Main loop ***               ******【メインループ】******
N = 0                        ループカウンタリセット
Do                          ループ先頭
If Portd.6 = 1 Then                 RX ONならエンコーダ読込へ
'Read RE
Debounce Pind.1 , 0 , Re , Sub            ENC-BinがLならReサブへ
End If
If N > 1000 Then                   ループ>1000回で以下を実行

                                         RIT処理】
If Portd.5 = 0 And Pinb.6 = 1 Then          RX ONかつRIT ONなら
R = Getadc(0)                    RIT VR のADC値読込
Else                         RX OFFまたはRIT OFFなら
R = 512                       RIT ADC値Rに512代入
End If
Rd = R - R3                     ADC値と過去値R3の差分計算
Rd = Abs(rd)                     差分を絶対値化
If Rd > 2 Then                    差分が2を越えたときだけ
R3 = R                        ADC値をR3に記憶
R1 = R - 512                     512中心にオフセットバイナリ化
R1 = R1 \ 17                     ±30ステップに変換 ※
R1 = R1 * 100                    1ステップに100Hz割当て ※
End If
If R1 <> R2 Then                   RITデータが変化していたら
R2 = R1                       RIT周波数データをR2へ記憶
Gosub Dds                      Ddsサブへ(DDS周波数設定)
End If
' Check PTT                     【PTTチェック】
Debounce Pind.2 , 0 , Tx , Sub            PTT ONならTxサブへ
Debounce Pind.2 , 1 , Rx , Sub            PTT OFFならRxサブへ
' Check RE Step                   【ダイアルステップSWチェック】
Debounce Pind.3 , 0 , Sf , Sub            ステップFast ならSfサブへ
Debounce Pind.4 , 0 , Ss , Sub            ステップSlow ならSsサブへ
N = 0                        ループカウンタNリセット
End If                        N>1000の処理ここまで
Incr N                        ループカウンタN+1
Loop                         ループ先頭に戻る
= End main loop =               *****【ループここまで】*****

'*** Rotary-encoder proc sub ***         【ロータリエンコーダ処理サブ】
Re:
If Pind.0 = 1 Then                  REのA入力がHなら

F = F - S                   周波数データから1ステップ分減算

Gosub Dds                      Ddsサブへ(DDS周波数設定)
Return

Else                         REのA入力がHでなければ

F = F + S                    周波数データへ1ステップ分加算

Gosub Dds
Return
End If
'= End RE proc sub =

'*** DDS data calc ******             【DDSデータ作成サブ】
Dds:
'Freq.calc
Fa = F - I                      周波数データ-IF周波数をFaへ
Fa = Fa + R1                     FaにRIT周波数加算
Fa = Fa \ D                      Faを逓倍数で割算
Ff = Fa * 4.1943060                  DDS制御値計算 
Fb = Ff                        整数化
'Generate Lower data
Fc = Fb And &H3FFF               下位データの上位2ビットをマスク
Fw = Fc Or &H4000                   マスク部に制御ビット付加
Gosub Dsd                       Dsdサブへ(DDSへ送信)
'Generate Upper data
Shift Fb , Right , 14                 上位14ビットを右シフト
Fw = Fb Or &H4000                   制御ビット付加
Gosub Dsd                       Dsdサブへ(DDSへ送信)
Return

'= End DDS Sub =

'*** DDS send sub ***               【DDSデータ送出サブ】
Dsd:
Reset Portc.5                    Fsyncピン >L
Shiftout Portc.3 , Portc.4 , Fw , 0         シリアルデータ送出
Set Portc.5                     Fsyncピン >H
Return

'*** Display sub ***               【LCD表示処理サブ】
Dsp:
Upperline
Fs = " " + Str(f)                  周波数データを文字列化
Fs = Right(fs , 8)                  文字数規制
Fd = Left(fs , 2) + "." + Mid(fs , 3 , 3) + ".0 "  周波数表示に小数点付加
Upperline                      LCD上段
Lcd Tr ; " " ; Fd                  に送受モードと周波数書込
If S > 5000 Then                  5000[Hz]/1クリック以上の時は
Lcd "F "                       LCDに"F"(Fast)を書込み
Else                         そうでなければ
Lcd "S "                       "S"(Slow)を書込み
End If

If R1 = 0 Then Lcd "R="               RIT値R1が0ならLCDに"R="表示
If R1 > 0 Then Lcd "R+"               RIT値R1が+ならLCDに"R+"表示
If R1 < 0 Then Lcd "R-"               RIT値R1が-ならLCDに"R-"表示
Return

'= End Display sub =

'***PTT proc sub***                【PTT処理サブ】
Tx:                        【送信切替処理】
If F < 50000000 Or F >= 51000000 Then        送信可能周波数外なら
Tr = "Ob"                      モード表示文字列に"Ob"代入
Portb.7 = 1                     送信禁止 制御ピン→H
Else                        送信可能範囲内で
If Portd.6 = 1 And Portb.7 = 0 Then        受信中で送信エラーがないなら
Ft = F                       現在周波数を一時記憶
Portd.7 = 1                     MUTE ON 制御ピン →H
Waitms 10                       
Portd.6 = 0                     RxOFF 制御ピン →L
Gosub Dds                      Ddsサブへ(送信周波数設定)
Waitms 5                    
  
Portd.5 = 1                     TxON 制御ピン →H
Waitms 10                      
Portd.7 = 0                     Mute OFF 制御ピン →L
Tr = "Tx"                      モード表示文字列に"Tx"代入
End If
End If
Return

'Tx to Rx                     【受信切替処理】
Rx:
If Portd.5 = 1 Then                 送信ピンがH(送信中)なら
Portd.7 = 1                     Mute ON 制御ピン →H
Waitms 10                      ※
Portd.5 = 0                     TxOFF 制御ピン →L
F = Ft                       送信開始前の周波数に戻す
Gosub Dds                      Ddsサブへ(受信周波数設定)
Waitms 5                       ※
Portd.6 = 1                     RxON  制御ピン →H
Waitms 10                      
Portd.7 = 0                     MuteOFF 制御ピン →L
End If
Tr = "Rx"                      モード表示文字列に"Rx"代入
Portb.7 = 0                     送信禁止解除 制御ピン →L
Return
= End PTT sub =

'*** RE Step select sub *** Rx          【ダイヤルステップ設定サブ】
'Set fast step
Sf:                        ダイアル早送りを
S = 100000                      100kHzに設定 ※
Return

'Set normal step
Ss:                        ダイアル標準ステップを
S = 5000                       5kHzに設定 ※
Return
'= End RE step sub =

                          プログラムここまで



プログラムの動作概要は以下のとおりです。

  プログラムではループのなかでロータリエンコーダの状態を読んで周波数データを加減してDDSに書き込み、ループ1000回毎にPTT、ステップ切替ボタン、RIT-VRの状態をチェックしています。

クリック付きエンコーダを使用するため、ENCODERコマンド(4倍速読込)ではなく、DEBOUNCEコマンドでエンコーダのポートを読み、変化を判断しています。

DDSには変化があったときのみ転送しています。
同じ内容の設定データであっても、転送した際に一瞬RF出力が不連続になるためです。

送信中はエンコーダは読みません。 また送信中にエンコーダを触っても、受信に戻ったときに周波数が飛ばない様に対策しています。

PTT信号を受けたとき、周波数が50.000〜50.995MHzでなければエラー信号を発生します。

ステップ切替は通常5kHz/クリック、高速で100kHz/クリックです。

RITはボリウムからの電圧をADCで受けますが、入力電圧がステップの境界にあってもデータがバタつかない様に不感帯を設けています。
100Hzステップで約±3kHzをカバーします。

LCDは当初ループ内で書いていましたが、書き込みに時間が掛かりロータリエンコーダを取落とすので、タイマ割り込みで65.5ms毎に書くように変更しました。
これでエンコーダを回したときの違和感は、ほぼなくなりました。

DDS周波数は(周波数データ−IF周波数計算)÷逓倍値で計算していて、プログラム内で送受別の設定も可能です。
今回はIF=10.7MHz、送受とも2逓倍で設定しています。

DDS設定値計算に使用した値はマスタークロックの誤差分を修正した値です。
 *DDS設定値=224÷64MHz(今回のマスタークロック周波数)

送受制御ピンの切替は音声ミュート信号を出してから行っています。 
このプログラムはTxサブとRxサブ内にあり、Waitms命令でミュートと送受各信号間の遅延量[ミリ秒]を決めています。 
Waitms値はミュート動作や送受信切替に要する時間に合わせて調整が必要となります。


詳細はプログラムを参照ください。


4 AVRライタの製作

 AVRにプログラムを書き込む方法は抵抗だけの簡単な方法からUSBに接続する方法など、いくつか発表されていますが、今回はパラレルIFでPCと接続するバッファ付シリアル(SPI)ライタを製作しました。
たまたまWIN2000のプリンタポートのあるノートPCが余っていて、接続に必要なプリンタケーブルの手持ちがあったことと、BASCOM-AVRはWIN2000でも動くのでこの方式になりました。
市販品のSTK200ライタと互換のためBASCOM-AVRからそのまま書込み操作ができます。

同じ方式の市販ライタが\1k、USB接続ライタが\3kかそれ以下で買えますから、わざわざ作る必要は無いかも・・

AVRはターゲット基板に載せたままSPIコネクタ経由で書込みが出来るので、この点でもZ8時代のROM焼きに比べたら格段に高効率ですね。

書き込みインタフェースの回路図です。
【注意】
 初期の回路に外部電源入力と5Vレギュレータが追加されています。
書き込み対象のAVRチップが既に何らかの機器に組みこまれていて、電源が供給できる状態の場合はI/Fに外部電源を絶対に接続しないでください。
I/Fは機器からの5Vで動作します。
機器側の電源がオフでI/Fから電源が供給されると、I/F内レギュレータの過負荷や供給先に故障を起こす可能性があります。
組み込み前のAVR基板など、他と接続されてない状態でI/Fコネクタから電源を供給して、プログラム書き込みを行う際に外部電源を使用します。 

(回路図はクリックで拡大↓)
パラレルI/Fシリアルライタ内部 デバッグ中
  *I/F内部写真は外部電源ジャック、レギュレータなどの追加改造を行う前のものです


5 FEMTO改との結合結果

 FEMTO改の受信系への影響はハードウエアの項で書いたとおりですが、送信スプリアスに関してはVXOの綺麗な信号に比べるとスプリアスが多く存在します。
下の写真は50.0MHz〜51MHzでスプリアスが低くなるよう調整した結果ですが、出力を維持しながらスプリアスの低いところに追い込むという細かい調整が必でした。

あまり気持ちの良い画ではありませんが、法令規制値より十分低く、全く問題ないレベルには収まりました
スプリアスの状態とAMの運用状況から、送信可能範囲を50.000MHz〜50.995MHzにプログラムで制限してあります。

(1) 50.000MHZでのスプリアス (2) 50.500MHZでのスプリアス
(3) 50.995MHZでのスプリアス (4) 50.500MHZでの高調波

 写真(1)〜(3)は近隣スプリアス 横軸1目盛2MHz (4)は高調波で1目盛20MHz
 縦軸は最上が30dBm(1W)で1目盛10dB 約100mW出力です
 スプリアスは1W以下の送信機の規制値50uW(-13dBm)を十分満足しています。


最後に

 DDSーICはシリアル制御ですし、エンコーダの読み込みやLCD表示となると、今までスルーを決め込んでいた何らかのマイクロコントローラを使わざるを得ませんでした。
Cやアセンブラだと手が出せないと思いながらWebを探してたところ"BASCOM-AVR"ならBASIC言語でATMEL社のAVRチップ用プログラムが書けることが判り、使ってみたのが今回のVFOです。
AVRといえば以前はAutomatic Voltage Regulatorだったんですが・・・

BASCOM-AVRにはDDS・LCD制御やエンコーダ読込みに必要な機能が既に実装されているので、計算や判断などを加えただけで、懸案だったプログラムが一応動作する状態には組めてしまいました。
かじった程度のBASICの経験があれば実用的なプログラムが作れる時代なんですね。

AVR自体も高速・高機能・低消費電力かつ安価、プログラム次第で欲しい機能のICに化けてくれるので、クロック漏れや制御ノイズに気をつければ今後も色々使えそうです。

実際、今回の製作は今後にとって大きな収穫になりました。
今後も機会があればAVRを使っていきたいと考えています。

ご覧頂いた各位にとって記事が何かの参考になれば幸いです。
                                                  (C)JA1VZV 2012-
                                        2012.4.26/2012.5.23/2012.9.10加筆修正


トップ アイコントップページへもどる

直線上に配置