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  

20 件のコメント:

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

    返信削除
  2. 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.

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

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

    返信削除
  5. 下記ページへアップしましたのでご覧ください。

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

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

    返信削除
  7. 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

    返信削除
    返信
    1. 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

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

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

    返信削除
  10. ありがとうございます。
    なかなかうまくいきませんが、やってみます。

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

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

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

    返信削除
  14. 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

    返信削除
    返信
    1. 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.

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

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

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

    返信削除
    返信
    1. コメント有難う御座いました。

      削除