2013年11月8日金曜日

AD9850 DDS VFO Premixed Version 1.1b


AD9850 DDS VFO Premixed版にスプリット機能を追加した。これで一通りの機能が揃った事になる。本来ならば、全ての機能を織り込んで、Version 1.0とすべきだが、他との識別の為、Version 1.1bとした。スプリット操作は、split SWを押し、Xと表示が出たら、ロータリーエンコーダで値をセットするのみである。他のVFOをセットする必要もない。簡単にSPLIT運用ができる。


回路図である。SPLITスイッチを追加した以外、Ver1.1aと同じ。
 
Program

SPLIT機能は、RIT機能のサブルーチンを使ってメモリー消費をおさえた。SPLITとRITは排他的な関係で、直感的なオペレーションが出来るが、RIT制限範囲 = SPLIT制限範囲である。
最大STEP値が、100kと50kを選択出来るよう、条件付コンパイルプログラムとした。STEP 100kにする時Step_100k=1。また、STEP 50kにする時、Step_100k=0と書き換えれば良い。(下記プログラムは、STEP 50k)

'********************************************************
'AD9850 DDS VFO Premixed type program ver.1.1b
'
'  Copyright (C)2013.JA2GQP.All rights reserved.
'
'     7.000Mhz to 7.200Mhz Limitted!
'     (Target frequency = IF frequency + frequency)
'                                       2013/11/07
'                                           JA2GQP
' BASCOM AVR 2.0.7.5(DEMO version) Compiled
'--------------------------------------------------------
'  Function
'
'     1.Upper heterodyne
'     2.RIT operation(-50khz to +50khz)
'     3.STEP(100k,10k,1k,100,10)
'     4.Memory operation is push RIT
'       (Frequency and Step)
'     5.Protection operation at the time of transmission
'     6.Channel memory main channel(ch0) + 2 chanenl(ch1,ch2)
'     7.Sprit operation(-50khz to +50khz)
'********************************************************
$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=ch_SW
'--- port pullup ---
Portb = &B00111111                      'ENC B,ENC A,RIT,STEP,none,TX
Portc = &B00111000                      'Bit 3-5 pull up
'--- 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
'---Max STEP select ---
Const Step_100k = 0                     'STEP 100k=1,50k=0
'--- 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 Lw_rit = -50000                   'RIT lower limit
Const Hi_rit = 50000                    '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
Declare Sub Chsw_sub                    'Channel SW check
Declare Sub Eep_rd_sub                  'EEP read
Declare Sub Spl_sub                     'SPLIT
'--- 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 Long                     'Encorder step
Dim Rit_dat As Long                     'RIT data
Dim Rit_datb As Long                    'RIT data old
Dim Int_wrk As Integer                  'Integer work
Dim Flg_rit As Byte                     'RIT flag
Dim Flg_ritb As Byte                    'RIT flag old
Dim Flg_tx As Byte                      'TX flag
Dim Flg_spl As Byte                     'SPLIT flag
Dim Frq_eep0 As Eram Long               'EEP frequency ch0
Dim Frq_eep1 As Eram Long               '              ch1
Dim Frq_eep2 As Eram Long               '              ch2
Dim Stp_eep0 As Eram Long               'EEP STEP ch0
Dim Stp_eep1 As Eram Long               '         ch1
Dim Stp_eep2 As Eram Long               '         ch2
Dim Flg_enc As Byte                     'Encorder dir flag
Dim Byt_cmd As Byte                     'DDS command
Dim Byt_wrk As Byte                     'Byte work
Dim Byt_chn As Byte                     'Channel
'--------------
'Main roution
'--------------
Main:
   Flg_tx = 0
   Flg_rit = 0                          'RIT flag
   Flg_spl = 0
   Cursor Off
   Cls
   Call Chsw_sub                        'Channel SW check
   Byt_wrk = Byt_chn
   Call Eep_rd_sub                      'EEP initial
   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
         Debounce Pinb.1 , 0 , Spl_sub , Sub       'SPLIT
         Call Chsw_sub                  'Channel SW check
         If Byt_wrk <> Byt_chn Then
            If Byt_wrk = 0 Then
               Frq_eep0 = Vfo_dat       'Save VFO0 data
               Stp_eep0 = Enc_stp       'Save STEP0 data
               Flg_ritb = Flg_rit       'Save RIT flag
               Rit_datb = Rit_dat       'Save RIT data
               Flg_rit = 0
               Flg_spl = 0
               Rit_dat = 0
               End If
               If Byt_wrk <> 0 Then
                  Flg_rit = 0
                  Flg_spl = 0
                  If Byt_chn = 0 Then
                     If Flg_ritb = 1 Then
                        Flg_rit = 1
                        Rit_dat = Rit_datb
                        End If
                     End If
                  End If
               Byt_wrk = Byt_chn
               Call Eep_rd_sub          'EEP load
               End If
            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
            If Flg_spl = 1 Then
               Dds_dat = Vfo_dat + Rit_dat
               Else
                  Dds_dat = Vfo_dat
                  End If
               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
   If Flg_enc = 0 Then
      Lng_wk1 = Vfo_dat + Enc_stp       'Up
      Lng_wk2 = Rit_dat + Enc_stp
      Else
         Lng_wk1 = Vfo_dat - Enc_stp    'down
         Lng_wk2 = Rit_dat - Enc_stp
         End If
   If Flg_rit = 1 Or Flg_spl = 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 Byt_chn ; ":" ; Dsp_frq ; "Mhz"
   Locate 2 , 1
   Lcd "S:     "
   Locate 2 , 3
   If Enc_stp < 1000 Then
      Lcd Enc_stp
#if Step_100k = 1
      Elseif Enc_stp = 100000 Then
         Lcd "100k "
#else
      Elseif Enc_stp = 50000 Then
         Lcd "50k  "
#endif
         Elseif Enc_stp = 10000 Then
            Lcd "10k  "
            Else
               Lcd "1k   "
               End If
   Locate 2 , 8
   If Flg_rit = 1 Then
      Lcd "R:       "
      End If
   If Flg_spl = 1 Then
      Lcd "X:       "
      End If
   Str_frq = Str(rit_dat)
   Str_frq = Format(str_frq , "00.000")
   Locate 2 , 10
   Lcd Str_frq
   If Flg_rit = 0 And Flg_spl = 0 Then
      Locate 2 , 8
      Lcd "   JA2GQP"
      End If
End Sub
'-----------------------------
'Step
'-----------------------------
Sub Stp_sub
   Select Case Enc_stp
#if Step_100k = 1
      Case 100000:
         Enc_stp = 10000                '10000
#else
      Case 50000:
         Enc_stp = 10000                '10000
#endif
      Case 10000:
         Enc_stp = 1000                 '1000
      Case 1000:
         Enc_stp = 100                  '100
      Case 100:
         Enc_stp = 10                   '10
      Case 10:
#if Step_100k = 1
         Enc_stp = 100000               '100000
#else
         Enc_stp = 50000                '50000
#endif
      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
      Flg_spl = 0
      Select Case Byt_chn
         Case 1:
            Frq_eep1 = Vfo_dat          'Save VFO1 data
            Stp_eep1 = Enc_stp          'Save STEP1 data
         Case 2:
            Frq_eep2 = Vfo_dat          'Save VFO2 data
            Stp_eep2 = Enc_stp          'Save STEP2 data
         Case Else:
            Frq_eep0 = Vfo_dat          'Save VFO0 data
            Stp_eep0 = Enc_stp          'Save STEP0 data
            End Select
      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 Byt_chn
      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
'-----------------------------
'Channel SW check
'-----------------------------
Sub Chsw_sub
   If Pinc.3 = 0 Then
      Byt_chn = 1
      Elseif Pinc.4 = 0 Then
         Byt_chn = 2
            Else
               Byt_chn = 0
               End If
   Locate 1 , 1
   Lcd Byt_chn
End Sub
'-----------------------------
'EEP set
'-----------------------------
Sub Eep_rd_sub
   If Frq_eep0 =< 0 Then                'EEP VFO data check
      Vfo_dat = Def_vfo                 'Initialize VFO data
      Frq_eep0 = Vfo_dat
      Frq_eep1 = Vfo_dat
      Frq_eep2 = Vfo_dat
      Else                              'Restore VFO data
        Select Case Byt_chn
            Case 1:
               Vfo_dat = Frq_eep1
            Case 2:
               Vfo_dat = Frq_eep2
            Case Else:
               Vfo_dat = Frq_eep0
               End Select
            End If
   If Stp_eep0 =< 0 Then                'EEP STEP data check
      Enc_stp = 1000
      Stp_eep0 = Enc_stp                'Initialize STEP data
      Stp_eep1 = Enc_stp
      Stp_eep2 = Enc_stp
      Else                              'Restore STEP data
        Select Case Byt_chn
            Case 1:
               Enc_stp = Stp_eep1
            Case 2:
               Enc_stp = Stp_eep2
            Case Else:
               Enc_stp = Stp_eep0
               End Select
            End If
   Call Lcd_sub
End Sub
'-----------------------------
'SPLIT
'-----------------------------
Sub Spl_sub
   If Flg_spl = 0 Then
      Flg_spl = 1
      Flg_rit = 0
      Rit_dat = 0
      Else
         Flg_spl = 0
         End If
   Call Lcd_sub
End Sub

  

3 件のコメント:

  1. こんにちは
    AD9851モジュールでテストしてみました。
    Const Scal = 34.35973837
    Const Dds_cmd = &B00000000

    Const Scal = 23.8609294222
    Const Dds_cmd = &B00000001
    に変更、動作は確認出来ました。
    ほかに修正箇所が必要でしょうか?
    JF1PTL

    返信削除
    返信
    1. JF1PTLさん
      AD9851モジュールに関する変更部分は、30MhzクロックであればOK(モジュールを持ってないので未確認)かと思います。
      ターゲットに合して、Const If_frq, Const Lw_frq,Const Hi_frq,Const Def_frqの変更。
      また、最大STEP=50kですが100kにする場合、Const Step_100k=0をConst Step_100k=1に変更する位です。
      Ver1.1bは、SPLIT機能が使えるので、使い勝手が良くなるかと・・・・

      削除
    2. こんばんは
      いろいろアドバイスありがとうございます。プログラム記述がわかり易く大変参考になります。
      これからもよろしくお願いします。
      JF1PTL

      削除