2014年1月8日水曜日

AD9834 DDS VFO Upper heterodyne

AD9834 DDS VFOの発振周波数を上側(アッパーヘテロダイン)のプログラム。
VFO frequency = IF frequency + Frequencyである。この変更に伴い、LPFのシュミレーションを行い定数を決めた。 









 
入出力インピーダンス50Ωの時のシュミレーション結果。
不整合で使った場合どの様な問題があるかを知るため、シュミレーション。
入力インピーダンス220Ω、出力インピーダンス50Ωの時のシュミレーション結果、4dBのリップルがある。問題ないレベルと考えるが気になるのであれば、入力側に変換トランスを入れれば良い。 







Program
KN-Q7A Likeを意識してプログラムが書いてあるが、キャリアポイントが正しいか検証手段が無いので判らない。また、最新のAD9850 Version1.1bを参考にすれば、機能追加も簡単な筈だ。

'********************************************************
'AD9834 DDS VFO program
'
'     7.000Mhz to 7.200Mhz Limitted!
'     (VFO frequency = IF frequency + Frequency)
'                                       2014/01/07
'                                           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 = &B00000000                                   '0=TX,1-6=none
Config Portd = &B00001111                                   '0=FSYNC,1=SCLK,2=SDATA,3=none
                                                            '4=ENC B,5=ENC A,6=STEP,7=RIT
'--- port pullup ---
Portb = &B11111111                                          'All
Portd = &B11110000                                          'RIT,STEP,ENC A,ENC B

'--- debounce set ---
Config Debounce = 1

'---LCD port assign ---
Config Lcdpin = Pin , Db7 = Portc.0 , Db6 = Portc.1
Config Lcdpin = Pin , Db5 = Portc.2 , Db4 = Portc.3
Config Lcdpin = Pin , E = Portc.4 , Rs = Portc.5
Config Lcd = 16 * 2

'--- constant data ---
Const If_frq = 8468500                                      'IF frequency(LSB carrier point)
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 = -10000                                       'RIT lower limit
Const Hi_rit = 10000                                        'RIT upper limit
'Const Scal = 4.00000                                       '2^28/2^26  2^26(X'tal 67.108864Mhz)
Const Scal = 5.36870912                                     '2^28/50000000 (X'tal 50.000Mhz)

'--- 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

'--------------
'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 Pind.5 , 0 , Enc_sub , Sub                'Encorder
         Debounce Pind.6 , 0 , Stp_sub , Sub                'Step
         Debounce Pind.7 , 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
   Int_wrk = Enc_stp
   If Pind.4 = 1 Then                                       'Up
      Lng_wk1 = Vfo_dat + Int_wrk
      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

'-----------------------------
'AD9834(DDS) Data write
'-----------------------------

Sub Dds_sub
   Sng_wrk = Dds_dat * Scal
   Lng_wk1 = Sng_wrk
   Wrd_wk1 = Lng_wk1 And &H3FFF
   Wrd_wk2 = Wrd_wk1 Or &H4000

   Shift Lng_wk1 , Right , 14
   Wrd_wk3 = Lng_wk1 Or &H4000

   Wrd_wk1 = &H2000

   Reset Portd.2
   Shiftout Portd.0 , Portd.1 , Wrd_wk1 , 0
   Shiftout Portd.0 , Portd.1 , Wrd_wk2 , 0
   Shiftout Portd.0 , Portd.1 , Wrd_wk3 , 0
   Set Portd.2
End Sub

'-----------------------------
'LCD Data write
'-----------------------------

Sub Lcd_sub
   Cls
   Locate 1 , 1
   Lng_wk1 = If_frq
   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

   If Enc_stp < 1000 Then
      Lcd Enc_stp
      Elseif Enc_stp = 10000 Then
         Lcd "10k  "
         Else
            Lcd "1k   "
            End If

   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   

1 件のコメント:

JA2GQP さんのコメント...

JF1PTLさん
現象から推測すると、Config Debounce=1が抜けているか、$crystal=800000が違う値でエンコーダのタイミングが合わず、上手く表示できないのかと思われます。
このプログラム(検証済み)を素直にコピーして$regfile="m88adef.dat"をデバイスに合わせて変更さえすれば動くはずです。
表示だけの問題であれば、簡単に解決すると思います。頑張って下さい。