2013年9月9日月曜日

AD9850 DDS 50Mhz VFO

中華AD9850 DDSモジュールを使った50Mhz VFOである。DDS発振周波数25Mhzを2逓倍し、50Mhz AM想定(受信機は、シングルスーパーでIF 455khz)とした。16Mhz 3逓倍でも動作するが、2逓倍の成分が問題である。2逓倍とした事で、満足な結果となった。

 

 


 回路図を示す。2逓倍の時、1.2mW出力であった。空きポートは、将来の機能拡張用として考えている。









 

 基板サイズ 59 x 56













SOURCE PROGRAM
 逓倍数は、Const Multi=2で指定しているので、他の逓倍数でも簡単に変更できる。
 
'********************************************************
'AD9850 DDS VFO program
'
'     50.000Mhz to 51.000Mhz Limitted!
'                                       2013/09/08
'                                           JA2GQP
' BASCOM AVR 2.0.7.5(DEMO version) Compiled
'--------------------------------------------------------
'  Function
'
'     1.RIT operation(-10khz to +10khz)
'     2.STEP(10000,1000,100,10)
'     3.Memory operation is push RIT
'       (Frequency and Step)
'     4. 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 = 455000                   'IF frequency
Const Lw_frq = 50000000                 'Lower limit operation frequency
Const Hi_frq = 51000000                 'Upper limit operation frequency
Const Def_frq = 50600000                'Operation frequency(initial)
Const Lw_vfo = Lw_frq - If_frq          'VFO lower limit(RX)
Const Hi_vfo = Hi_frq - If_frq          'VFO upper limit(RX)
Const Multi = 2                         'Multiplication
Const Def_vfo = Def_frq - If_frq        'VFO operation frequency(RX)
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 + If_frq
            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 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 / Multi
   Lng_wk1 = Sng_wrk * Scal
   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

0 件のコメント: