中華AD9850モジュールを使ったDDS VFOの基板である。先に紹介のAD9850 DDS VFOと基本的に同じであるが、線の引き回し上、IOを変更した。また、親機へのヘテロダインを上側にし、スプリアスの低減を計った。 7Mhz BITXライクを想定したprogramである。
回路図である。将来の機能拡張の為にIOを整理した。
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
'********************************************************
'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
$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
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
Portb = &B00111111 'ENC B,ENC A,RIT,STEP,none,TX
'--- debounce set ---
Config Debounce = 1
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
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
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
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
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 roution
'--------------
Main:
Flg_tx = 0
Flg_rit = 0 'RIT flag
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
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
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
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
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
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
Dds_dat = Vfo_dat + Rit_dat
Else
Dds_dat = Vfo_dat
End If
If Flg_tx = 1 Then
Dds_dat = Vfo_dat
End If
Dds_dat = Vfo_dat
End If
Call Dds_sub
Loop
End
End
'-----------------------------
'Encoder check,Create DDS data
'-----------------------------
'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 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
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
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
Vfo_dat = Lw_vfo
End If
If Vfo_dat > Hi_vfo Then 'VFO upper limit check
Vfo_dat = Hi_vfo
End If
Vfo_dat = Hi_vfo
End If
If Rit_dat < Lw_rit Then 'RIT lower limit check
Rit_dat = Lw_rit
End If
Rit_dat = Lw_rit
End If
If Rit_dat > Hi_rit Then 'RIT upper limit check
Rit_dat = Hi_rit
End If
Rit_dat = Hi_rit
End If
Call Lcd_sub
End Sub
End Sub
'-----------------------------
'AD9850(DDS) Data write
'-----------------------------
'AD9850(DDS) Data write
'-----------------------------
Sub Dds_sub
Sng_wrk = Dds_dat * Scal
Lng_wk1 = Sng_wrk
Byt_cmd = Dds_cmd 'DDS command
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
Shiftout Portc.0 , Portc.2 , Lng_wk1 , 3
Shiftout Portc.0 , Portc.2 , Byt_cmd , 3
Set Portc.1
End Sub
'-----------------------------
'LCD Data write
'-----------------------------
'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
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
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
'-----------------------------
'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
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
End Sub
'-----------------------------
'RIT
'-----------------------------
'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
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
'-----------------------------
'RX
'-----------------------------
Sub Rx_sub
If Flg_tx = 1 Then
Flg_tx = 0 'TX flag rest
Locate 1 , 1
Lcd "F"
End If
End Sub
If Flg_tx = 1 Then
Flg_tx = 0 'TX flag rest
Locate 1 , 1
Lcd "F"
End If
End Sub
'-----------------------------
'TX
'-----------------------------
'TX
'-----------------------------
Sub Tx_sub
If Flg_tx = 0 Then
Flg_tx = 1 'TX flag set
Locate 1 , 1
Lcd "T"
End If
End Sub
If Flg_tx = 0 Then
Flg_tx = 1 'TX flag set
Locate 1 , 1
Lcd "T"
End If
End Sub
25 件のコメント:
mr. I have ATmega8 whether this source can be directly used without changing the source code?
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.
JA5NAF北川と申します。
回路図とソースを公開していただいていましたので、試作させていただきました。
DDSモジュールはebayで購入しましたが、GQPさんのモジュールとはピン配置が異なるものでした。
また、AVRはATmega168Pを使いましたが、支障なく動作しました。
ハードは部品数が少なく、ソフトは中華DDSモジュール制御の決定版だと思います。
どうもありがとうございました。
使って頂いて有難うございます。
BASCOMでPLL制御も書いてますが、殆ど同じです。本当に簡単にかけます。
異形状のモジューが有るのは知ってますが、PINアサインが異なるものが有るとは知りませんでした。PINアサインを教えて頂けませんか?
下記ページへアップしましたのでご覧ください。
http://iyo.ojaru.jp/dds.html
早速、拝見させて頂きました。
貴重な情報有難うございました。
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
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
ありがとうございます。
100KHzステップができるようになりました。
が、ステップの表示がうまくいきません。
ステップを切り変えても前のステップが消えず、LCDの2行目が数字でいっぱいになります。
Step Subが間違っているのでしょうか。
それから、コールサインを表示しないこととしたのはやむを得ないのでしょうか。
改造箇所の要点を書きましたが、この修正で試験して問題なく動作してます。改造方法が判りませんが、一度お試しを!
ありがとうございます。
なかなかうまくいきませんが、やってみます。
うまくいきました。
ゼネカバ受信機のVFOに使いたいと思いましたので、100KHzステップが必要でした。
アドバイスありがとうございました。
今回の100khz STEP修正をprogramを整理したら、UPします。その時は、プラスアロファの機能追加が出来ればと・・・・
10CHくらいのメモリがあればいいなと思います。
ヴァージョンアップを期待しています。
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
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.
Circuit diagram, "AD9850 DDS VFO Premixed Version 1.1a 2013/11/06".
If, when the split function is required.
Circuit diagram,”AD9850 DDS VFO Premixed Version 1.1b 2013/11/08”
こちらのDDS VFO 作らせていただきました。
7MHzCW フルブレークイン トランシーバーに使用しましたがFBに使えます。
ありがとうございます。
コメント有難う御座いました。
教えて下さい。
ロータリーエンコダーを早く回すと、追従してくれません。または、UP/DOWNが逆になることもあります。
プログラムで変更箇所があれば教えて頂けると助かります。
UEMAKOさん
お早う御座います。
随分前に開発した物なので、確認するための環境が有りません。
開発環境を整備してから、チェックしますので暫く時間をください。
追伸
早々 ご返事有難うございます。
以前Umakotoでコメントしたものです。
現在もQRP TRX で便利に使用させて頂いております。
今回100パルスという、ロータリーエンコーダーに交換したところ起きた現象です。
ゆっくり回せば問題なくUP/DOWNします。
宜しくお願いします。
UEMAKOさん
こんばんは
減税の環境を調べたところ、BASCOMはインストールされてない、開発したボードが見当らない。従って、検証困難です。
スケッチは、8MHzクロックで動作してるようなので、16MHzクロックにすれば改善されそうな気がします。不具合は、エンコーダ処理が次のぱるるが来るまでに終われない用です。
従って、CPUの能力を上げれば改善できます。
ご回答 有難うございました。
私のレベルでは教えて頂いたクロック、CPU、とも出来ませんので
交換しないで使用させてもらいます。
ありがとうございました。
コメントを投稿