2013年9月6日金曜日

AD9850 DDS VFO PCB




 

 中華AD9850モジュールを使ったDDS VFOの基板である。先に紹介のAD9850 DDS VFOと基本的に同じであるが、線の引き回し上、IOを変更した。また、親機へのヘテロダインを上側にし、スプリアスの低減を計った。 7Mhz BITXライクを想定したprogramである。



 

 回路図である。将来の機能拡張の為にIOを整理した。 
       
 

基板サイズ 59 x 56。  
 
AD9850 SOURCE PRGRAM
 
'********************************************************
'AD9850 DDS VFO program
'
'     7.000Mhz to 7.200Mhz Limitted!
'     (VFO frequency = IF frequency + Frequency)
'                                       2013/09/04
'                                           JA2GQP
' BASCOM AVR 2.0.7.5(DEMO version) Compiled
'--------------------------------------------------------
'  Function
'
'     1.Upper heterodyne
'     2.RIT operation(-10khz to +10khz)
'     3.STEP(10000,1000,100,10)
'     4.Memory operation is push RIT
'       (Frequency and Step)
'     5. Protection operation at the time of transmission
'********************************************************
$regfile = "m88adef.dat"
$crystal = 800000                       '0.8Mhz clock
'--- config port ---
Config Portb = &B11000000               '0=TX,1=none,2=STEP,3=RIT
                                         '4=ENC A,5=ENC B,6-7=LCD
Config Portc = &B00000111               '0=DATA,1=FU_UD,2=W_CLK,3-5=none
'--- port pullup ---
Portb = &B00111111                      'ENC B,ENC A,RIT,STEP,none,TX
'--- debounce set ---
Config Debounce = 1
'---LCD port assign ---
Config Lcdpin = Pin , Db7 = Portd.6 , Db6 = Portd.5
Config Lcdpin = Pin , Db5 = Portb.7 , Db4 = Portb.6
Config Lcdpin = Pin , E = Portd.2 , Rs = Portd.0
Config Lcd = 16 * 2
'--- constant data ---
Const If_frq = 9996500                  'IF frequency
Const Lw_frq = 7000000                  'Lower limit operation frequency
Const Hi_frq = 7200000                  'Upper limit operation frequency
Const Def_frq = 7050000                 'Operation frequency(initial)
Const Lw_vfo = If_frq + Lw_frq          'VFO lower limit
Const Hi_vfo = If_frq + Hi_frq          'VFO upper limit
Const Def_vfo = If_frq + Def_frq        'VFO operation frequency(initial)
Const Enc_dir = 1                       '1:CW up count,-1:CW down count
Const Lw_rit = -10000                   'RIT lower limit
Const Hi_rit = 10000                    'RIT upper limit
Const Scal = 34.35973837                '2^32/125.000Mhz
Const Dds_cmd = &B00000000              'DDS command
'--- define subrutine ---
Declare Sub Enc_sub                     'Encorder
Declare Sub Dds_sub                     'DDS
Declare Sub Lcd_sub                     'LCD
Declare Sub Stp_sub                     'STEP
Declare Sub Rit_sub                     'RIT
Declare Sub Rx_sub                      'RX
Declare Sub Tx_sub                      'TX
'--- define memory ---
Dim Vfo_dat As Long                     'VFO freqency data
Dim Dds_dat As Long                     'DDS frequency data
Dim Str_frq As String * 10              'String frequency
Dim Dsp_frq As String * 10              'Display frequency
Dim Sng_wrk As Single                   'main channel
Dim Lng_wk1 As Long                     'Long work1
Dim Lng_wk2 As Long                     'Long work2
Dim Wrd_wk1 As Word                     'Word work1
Dim Wrd_wk2 As Word                     'Word work2
Dim Wrd_wk3 As Word                     'Word work3
Dim Enc_stp As Integer                  'Encorder step
Dim Rit_dat As Integer                  'RIT data
Dim Int_wrk As Integer                  'Integer work
Dim Flg_rit As Byte                     'RIT flag
Dim Flg_tx As Byte                      'TX flag
Dim Frq_eep As Eram Long                'power off frequency A
Dim Stp_eep As Eram Integer             'EEP STEP data
Dim Flg_enc As Byte                     'Encorder dir flag
Dim Byt_cmd As Byte                     'DDS command
'--------------
'Main roution
'--------------
Main:
   Flg_tx = 0
   Flg_rit = 0                          'RIT flag
   If Frq_eep =< 0 Then                 'EEP VFO data check
      Vfo_dat = Def_vfo                 'Initialize VFO data
      Frq_eep = Vfo_dat
      Else
         Vfo_dat = Frq_eep              'Restore VFO data
         End If
   If Stp_eep =< 0 Then                 'EEP STEP data check
      Enc_stp = 1000
      Stp_eep = Enc_stp                 'Initialize STEP data
      Else
         Enc_stp = Stp_eep
         End If                         'Restore STEP data
   Cursor Off
   Cls
   Call Lcd_sub                         'LCD
   Do
      If Flg_tx = 0 Then
         Debounce Pinb.4 , 0 , Enc_sub , Sub       'Encorder
         Debounce Pinb.2 , 0 , Stp_sub , Sub       'Step
         Debounce Pinb.3 , 0 , Rit_sub , Sub       'RIT
         End If
         Debounce Pinb.0 , 1 , Rx_sub , Sub       'RX
         Debounce Pinb.0 , 0 , Tx_sub , Sub       'TX
         If Flg_rit = 1 Then
            Dds_dat = Vfo_dat + Rit_dat
            Else
               Dds_dat = Vfo_dat
               End If
         If Flg_tx = 1 Then
            Dds_dat = Vfo_dat
            End If
         Call Dds_sub
   Loop
End
'-----------------------------
'Encoder check,Create DDS data
'-----------------------------
Sub Enc_sub
   If Pinb.5 = 1 Then
      Flg_enc = 0                       'Up
      Else
         Flg_enc = 1                    'down
         End If
   Int_wrk = Enc_stp * Enc_dir
   If Flg_enc = 0 Then
      Lng_wk1 = Vfo_dat + Int_wrk       'Up
      Lng_wk2 = Rit_dat + Enc_stp
      Else
         Lng_wk1 = Vfo_dat - Int_wrk    'down
         Lng_wk2 = Rit_dat - Enc_stp
         End If
   If Flg_rit = 1 Then
      Rit_dat = Lng_wk2
      Else
         Vfo_dat = Lng_wk1
         Rit_dat = 0
         End If
   If Vfo_dat < Lw_vfo Then             'VFO lower limit check
      Vfo_dat = Lw_vfo
      End If
   If Vfo_dat > Hi_vfo Then             'VFO upper limit check
      Vfo_dat = Hi_vfo
      End If
   If Rit_dat < Lw_rit Then             'RIT lower limit check
      Rit_dat = Lw_rit
      End If
   If Rit_dat > Hi_rit Then             'RIT upper limit check
      Rit_dat = Hi_rit
      End If
   Call Lcd_sub
End Sub
'-----------------------------
'AD9850(DDS) Data write
'-----------------------------
Sub Dds_sub
   Sng_wrk = Dds_dat * Scal
   Lng_wk1 = Sng_wrk
   Byt_cmd = Dds_cmd                    'DDS command
   Reset Portc.1
   Shiftout Portc.0 , Portc.2 , Lng_wk1 , 3
   Shiftout Portc.0 , Portc.2 , Byt_cmd , 3
   Set Portc.1
End Sub
'-----------------------------
'LCD Data write
'-----------------------------
Sub Lcd_sub
   Locate 1 , 1
   Lng_wk1 = Vfo_dat - If_frq
   Str_frq = Str(lng_wk1)
   Str_frq = Format(str_frq , "00.000000")
   Dsp_frq = Left(str_frq , 3) + Mid(str_frq , 4 , 3) + "." + Mid(str_frq , 7 , 3)
   Lcd "F:" ; Dsp_frq ; "Mhz"
   Locate 2 , 1
   Lcd "S:     "
   Locate 2 , 3
   Lcd Enc_stp
   If Flg_rit = 1 Then
      Locate 2 , 8
      Lcd "R:       "
      Str_frq = Str(rit_dat)
      Str_frq = Format(str_frq , "00.000")
      Locate 2 , 10
      Lcd Str_frq
      Else
         Locate 2 , 8
         Lcd "   JA2GQP"
         End If
End Sub
'-----------------------------
'Step
'-----------------------------
Sub Stp_sub
   Select Case Enc_stp
      Case 10000:
         Enc_stp = 1000                 '1000
      Case 1000:
         Enc_stp = 100                  '100
      Case 100:
         Enc_stp = 10                   '10
      Case 10:
         Enc_stp = 10000                '10000
      Case Else:
         Enc_stp = 1000                 '1000(initial)
   End Select
   Call Lcd_sub
End Sub
'-----------------------------
'RIT
'-----------------------------
Sub Rit_sub
   If Flg_rit = 0 Then
      Rit_dat = 0
      Flg_rit = 1
      Frq_eep = Vfo_dat                 'Save VFO data
      Stp_eep = Enc_stp                 'Save STEP data
      Else
         Flg_rit = 0
         End If
   Call Lcd_sub
End Sub
'-----------------------------
'RX
'-----------------------------
Sub Rx_sub
   If Flg_tx = 1 Then
      Flg_tx = 0                        'TX flag rest
      Locate 1 , 1
      Lcd "F"
      End If
End Sub
'-----------------------------
'TX
'-----------------------------
Sub Tx_sub
   If Flg_tx = 0 Then
      Flg_tx = 1                        'TX flag set
      Locate 1 , 1
      Lcd "T"
      End If
End Sub  

25 件のコメント:

AG さんのコメント...

mr. I have ATmega8 whether this source can be directly used without changing the source code?

JA2GQP さんのコメント...

ATmega8 and ATmega88 is basically the same. However, at the time of writing, it might be out error. it should be fixed by changes to the MPU to the desired line of $ regfile.

kita さんのコメント...

JA5NAF北川と申します。
回路図とソースを公開していただいていましたので、試作させていただきました。
DDSモジュールはebayで購入しましたが、GQPさんのモジュールとはピン配置が異なるものでした。
また、AVRはATmega168Pを使いましたが、支障なく動作しました。
ハードは部品数が少なく、ソフトは中華DDSモジュール制御の決定版だと思います。
どうもありがとうございました。

JA2GQP さんのコメント...

使って頂いて有難うございます。
BASCOMでPLL制御も書いてますが、殆ど同じです。本当に簡単にかけます。
異形状のモジューが有るのは知ってますが、PINアサインが異なるものが有るとは知りませんでした。PINアサインを教えて頂けませんか?

kita さんのコメント...

下記ページへアップしましたのでご覧ください。

http://iyo.ojaru.jp/dds.html

JA2GQP さんのコメント...

早速、拝見させて頂きました。
貴重な情報有難うございました。

kita さんのコメント...

100KHzステップを追加するときのソースはこれで良いでしょうか。

'-----------------------------
'Step
'-----------------------------

Sub Stp_sub
Select Case Enc_stp
Case 100000:
Enc_stp = 10000 '10000
Case 10000:
Enc_stp = 1000 '1000
Case 1000:
Enc_stp = 100 '100
Case 100:
Enc_stp = 10 '10
Case 10:
Enc_stp = 100000 '100000
Case Else:
Enc_stp = 1000 '1000(initial)
End Select

Call Lcd_sub
End Sub

JA2GQP さんのコメント...

STEP SUBは、これでOKです。しかし、下記変更が必要となります。
1.define memoryの対象行のSingleをLongに変更
 Dim Enc_stp As Long
 Dim Stp_eep As Eram Long
2.Enc_subの計算workエリアのInt_wrkをLng_wk1に変更
 Lng_wk1 = Enc_stp * Enc_dir
 Lng_wk1 = Vfo_dat + Lng_wk1
 Lng_wk1 = Vfo_dat - Lng_wk1
3.Lcd_sub
 Lcd Enc_stpの行を下記に変更
 If Enc_stp => 1000 Then
    Lng_wk2 = Enc_stp / 1000
    Lcd Lng_wk2 ; "k"
    Else
      Lcd Enc_stp
      End If

kita さんのコメント...

ありがとうございます。
100KHzステップができるようになりました。
が、ステップの表示がうまくいきません。
ステップを切り変えても前のステップが消えず、LCDの2行目が数字でいっぱいになります。
Step Subが間違っているのでしょうか。
それから、コールサインを表示しないこととしたのはやむを得ないのでしょうか。

JA2GQP さんのコメント...

改造箇所の要点を書きましたが、この修正で試験して問題なく動作してます。改造方法が判りませんが、一度お試しを!

kita さんのコメント...

ありがとうございます。
なかなかうまくいきませんが、やってみます。

kita さんのコメント...

うまくいきました。
ゼネカバ受信機のVFOに使いたいと思いましたので、100KHzステップが必要でした。
アドバイスありがとうございました。

JA2GQP さんのコメント...

今回の100khz STEP修正をprogramを整理したら、UPします。その時は、プラスアロファの機能追加が出来ればと・・・・

kita さんのコメント...

10CHくらいのメモリがあればいいなと思います。
ヴァージョンアップを期待しています。

Unknown さんのコメント...

Akio San,

I am trying to use your design into my Bitx. It is very nice. It works well.
I am now trying to use your model to get a dualband DDS. I wanna try using dds on my 80/40m transceiver. I would use rit button into band change button.
My 80m band is on the range of 3.700 - 3.900 mhz.

Would you please help me to add some code to meet with my need.

Arigotou

JA2GQP さんのコメント...

For the memory limit, complete thing can not be, but there are the following methods.
Use the program "AD9850 DDS VFO Premixed Version 1.1b 2013/11/08", and change the Const Lw_frq = 3700000.
However, the transmission of protection between 7.0Mhz can not be from 3.9Mhz.

JA2GQP さんのコメント...

Circuit diagram, "AD9850 DDS VFO Premixed Version 1.1a 2013/11/06".

JA2GQP さんのコメント...

If, when the split function is required.
Circuit diagram,”AD9850 DDS VFO Premixed Version 1.1b 2013/11/08”

Umakoto さんのコメント...

こちらのDDS VFO 作らせていただきました。
7MHzCW フルブレークイン トランシーバーに使用しましたがFBに使えます。
ありがとうございます。

JA2GQP さんのコメント...

コメント有難う御座いました。

UEMAKO さんのコメント...

教えて下さい。
ロータリーエンコダーを早く回すと、追従してくれません。または、UP/DOWNが逆になることもあります。
プログラムで変更箇所があれば教えて頂けると助かります。

JA2GQP さんのコメント...

UEMAKOさん 
お早う御座います。
随分前に開発した物なので、確認するための環境が有りません。
開発環境を整備してから、チェックしますので暫く時間をください。

UEMAKO さんのコメント...

追伸
早々 ご返事有難うございます。
以前Umakotoでコメントしたものです。
現在もQRP TRX で便利に使用させて頂いております。
今回100パルスという、ロータリーエンコーダーに交換したところ起きた現象です。
ゆっくり回せば問題なくUP/DOWNします。
宜しくお願いします。

JA2GQP さんのコメント...

UEMAKOさん
こんばんは
減税の環境を調べたところ、BASCOMはインストールされてない、開発したボードが見当らない。従って、検証困難です。
スケッチは、8MHzクロックで動作してるようなので、16MHzクロックにすれば改善されそうな気がします。不具合は、エンコーダ処理が次のぱるるが来るまでに終われない用です。
従って、CPUの能力を上げれば改善できます。

UEMAKO さんのコメント...

ご回答 有難うございました。

私のレベルでは教えて頂いたクロック、CPU、とも出来ませんので 
交換しないで使用させてもらいます。

ありがとうございました。