
Mała modyfikacja programu . Kręcenie enkoderem było czasochłonne i nie przypadło mi do gustu .
Miejsce enkodera zajęła klawiatura 4x4 na porcie PD .
Zmiana dotyczy również wyświetlacza który został zmieniony na 20x4 .
- $regfile = "m8def.dat"
- $crystal = 8000000 '8MHz internal RC clock
- $hwstack = 128
- $swstack = 64
- $framesize = 128
- '-------------------------------------------------------------------------------
- Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
- Config Lcd = 20 * 4
- Config Portb.1 = Output 'dds
- Config Portb.2 = Output 'dds
- Config Sda = Portb.1
- Config Scl = Portb.2
- Config Kbd = Portd 'klawiatura 4x4
- Set Portb.1
- Set Portb.2
- ' Declare Variables
- Dim Mhz As String * 2 'display subroutine variables
- Dim Khz As String * 3
- Dim Hz As String * 3
- Dim Lastftext As String * 6 'for display of freqb khz & Hz digits
- Dim Freqtxt As String * 9
- Dim Tekst1 As String * 9
- Dim Mem_hz(3) As Dword ' pamieć częstotliwości
- Dim Fcnt As Byte
- Dim Temp As Byte 'temporary variable used in sendfreq and sbarplot routines
- Dim Temp1 As Byte ' temp dla pamiec czestotliwosci
- Dim Frequency As Dword 'four byte unsigned variable
- Dim Gfreq As Dword 'calculates si5351 VFO output frequency
- Dim Stepsize As Byte
- Dim Delta As Dword
- Dim Update As Bit 'bit is set (1) if a switch or encoder has changed
- Dim Fvco As Dword 'si5351 vco frequency
- Dim Outdivider As Dword '4,6,8-900
- Dim Rdivider As Byte 'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
- Dim Rbyte As Byte 'used as temp store before final data load to si5351
- Dim Afactor As Dword
- Dim Bfactor As Dword
- Dim Fvalue As Single 'used to determine accuracy of fractional calculation
- Dim Finteger As Dword
- Dim Klw As Byte , Pozycja As Byte 'klawiatura
- Dim Znak As String * 1 , Wartosc As String * 9 ' klawiatura
- Dim Ms0p1 As Dword '18-bit MS0_P1 si5351 parameters for Output 0
- Dim M0p11 As Byte At Ms0p1 Overlay 'mirrored variables for dds calculation
- Dim M0p12 As Byte At Ms0p1 + 1 Overlay
- Dim M0p13 As Byte At Ms0p1 + 2 Overlay
- Dim M0p14 As Byte At Ms0p1 + 3 Overlay 'most significant byte for ms0p1
- 'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
- 'si5351 parameters for PLLA
- Dim Msnap1 As Dword '18-bit variable for MSNA_P1
- Dim Ms11 As Byte At Msnap1 Overlay 'mirrored variables for dds calculation
- Dim Ms12 As Byte At Msnap1 + 1 Overlay
- Dim Ms13 As Byte At Msnap1 + 2 Overlay
- Dim Ms14 As Byte At Msnap1 + 3 Overlay 'most significant byte
- Dim Msnap2 As Dword '20-bit variable for MSNA_P2
- Dim Ms21 As Byte At Msnap2 Overlay 'mirrored variables for dds calculation
- Dim Ms22 As Byte At Msnap2 + 1 Overlay
- Dim Ms23 As Byte At Msnap2 + 2 Overlay
- Dim Ms24 As Byte At Msnap2 + 3 Overlay 'most significant byte
- Dim Msnap3 As Dword '20-bit variable for MSNA_P3
- Dim Ms31 As Byte At Msnap3 Overlay 'mirrored variables for dds calculation
- Dim Ms32 As Byte At Msnap3 + 1 Overlay
- Dim Ms33 As Byte At Msnap3 + 2 Overlay
- Dim Ms34 As Byte At Msnap3 + 3 Overlay 'most significant byte
- Dim Regaddr As Byte , Regdata As Byte 'for i2c calls
- Dim Siaddr1 As Byte , Siaddr2 As Byte 'for writing to si5351 CLK0 and CLK1
- ' Declare Constants
- Const Startfreq = 10000 'xxx '40m starting frequency
- Const Xtal = 25001400 ' xxx 25000000 '**NOTE: Value may be adjusted during alignment ***
- Const Cfactor = 1048575 'xxx 1048575
- Frequency = Startfreq 'initialise frequency (20m for now)
- Stepsize = 3
- Delta = 1000
- Temp1 = 0
- Mem_hz(1) = 30000 ' Częstotliwości startowe pamięci
- Mem_hz(2) = 20000
- Mem_hz(3) = 10000
- ' Declare Subroutines
- Declare Sub Si5351init 'initialises si5351
- Declare Sub Displaylcd 'displays current oscillator frequency
- Declare Sub Calculate 'converts current VFO or BFO freq to data for si5351
- Declare Sub Sendfreq 'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
- Declare Sub Siout(sireg As Byte , Sidata As Byte) 'for i2c write to si5351
- Declare Sub Wybor_clk
- Declare Sub Zapis
- '***************************** Program *****************************************
- ' initialise i2c here...
- I2cinit
- Waitms 50 'for i2c to settle and for lcd RC reset time
- Cursor Off 'LCD cursor of
- Cls
- Update = 0 'clear the flags
- Si5351init 'initialises si5351
- Gfreq = Frequency
- Calculate
- Siaddr1 = 26
- Siaddr2 = 42
- Sendfreq
- Regaddr = 16
- Regdata = 79
- Call Siout(regaddr , Regdata)
- Siaddr1 = 34
- Siaddr2 = 50
- Sendfreq
- Siaddr1 = 34
- Siaddr2 = 58
- Sendfreq
- Regaddr = 17
- Regdata = 111
- Call Siout(regaddr , Regdata)
- Regaddr = 18
- Regdata = 111
- Call Siout(regaddr , Regdata)
- Wybor_clk
- Displaylcd 'then display frequency and status on lcd
- Do 'Start of main program
- Skok:
- If Klw = 11 Then
- Incr Stepsize
- Waitms 500 ' xxx
- If Stepsize = 8 Then 'xxx
- Stepsize = 1
- End If
- If Stepsize = 1 Then Delta = 5 'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
- If Stepsize = 2 Then Delta = 100 '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
- If Stepsize = 3 Then Delta = 1000
- If Stepsize = 4 Then Delta = 10000
- If Stepsize = 5 Then Delta = 100000 'xxx
- If Stepsize = 6 Then Delta = 1000000 ' xxx
- If Stepsize = 7 Then Delta = 10000000 ' xxx
- Update = 1
- Displaylcd 'to flag this change
- End If
- If Klw = 3 Then ' Hz +
- Frequency = Frequency + Delta
- If Frequency > 150000000 Then
- Frequency = 150000000
- End If
- Update = 1
- Displaylcd
- End If
- If Klw = 7 Then ' Hz -
- Frequency = Frequency - Delta
- If Frequency > 150000000 Then
- Frequency = 10000
- End If
- If Frequency < 10000 Then
- Frequency = 10000
- End If
- Update = 1
- Displaylcd
- End If
- If Klw = 15 Then : Wybor_clk : End If ' Wybor_clk
- If Update = 1 Then 'encoder or buttons changed so update display and si5351
- 'show new frequency and status
- Gfreq = Frequency
- Displaylcd 'gfreq holds value used for si5351
- Calculate 'calculate new VFO data
- Sendfreq 'and send it to the si5351
- Call Siout(regaddr , Regdata) 'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
- Update = 0
- 'and update flag
- End If
- '============================================================================
- ' Przejście do Sub zapis nowej Hz , zabezpieczenie przekroczenia Hz
- '============================================================================
- Waitms 100
- Klw = Getkbd()
- If Klw = 12 Then
- Locate 4 , 1 : Lcd " "
- Zapis
- End If
- Loop 'End of main program
- End
- '**********************************************************************
- 'Subroutines...
- '=====================================================================
- '==============================================================================================
- ' wybór wyjścia clk0 , clk1 , clk2
- '==============================================================================================
- Sub Wybor_clk
- Incr Temp1
- Waitms 500
- If Temp1 = 1 Then
- Mem_hz(3) = Frequency 'pamięć hz clk2
- Frequency = Mem_hz(1) ' odczyt hz clk0
- Siaddr1 = 26 'adres początkowy PLLA
- Siaddr2 = 42 'adres początkowy CLK0
- Update = 1
- Elseif Temp1 = 2 Then
- Mem_hz(1) = Frequency 'pamięć hz clk0
- Frequency = Mem_hz(2) ' odczyt hz clk1
- Siaddr1 = 34 'adres początkowy PLLB
- Siaddr2 = 50 'adres początkowy CLK1
- Update = 1
- Elseif Temp1 = 3 Then
- Mem_hz(2) = Frequency 'pamięć hz clk1
- Frequency = Mem_hz(3) ' odczyt hz clk2
- Siaddr1 = 34 'adres początkowy PLLB
- Siaddr2 = 58 'adres początkowy CLK2
- Update = 1
- End If
- If Temp1 = 4 Then
- Temp1 = 0
- End If
- End Sub
- '========================================================================
- '========================================================================
- Sub Displaylcd
- '
- Tekst1 = "000000000"
- Freqtxt = Str(frequency) ' (frequency)
- Fcnt = Len(freqtxt)
- If Fcnt = 1 Then
- Mid(tekst1 , 9 , Fcnt) = Freqtxt ' 9
- Elseif Fcnt = 2 Then
- Mid(tekst1 , 8 , Fcnt) = Freqtxt ' 8
- Elseif Fcnt = 3 Then
- Mid(tekst1 , 7 , Fcnt) = Freqtxt ' 7
- Elseif Fcnt = 4 Then
- Mid(tekst1 , 6 , Fcnt) = Freqtxt ' 6
- Elseif Fcnt = 5 Then
- Mid(tekst1 , 5 , Fcnt) = Freqtxt ' 5
- Elseif Fcnt = 6 Then
- Mid(tekst1 , 4 , Fcnt) = Freqtxt ' 5
- Elseif Fcnt = 7 Then
- Mid(tekst1 , 3 , Fcnt) = Freqtxt ' 3
- Elseif Fcnt = 8 Then
- Mid(tekst1 , 2 , Fcnt) = Freqtxt ' 2
- Elseif Fcnt = 9 Then
- Mid(tekst1 , 1 , Fcnt) = Freqtxt ' 1
- End If
- Locate 1 , 2
- Lcd Mid(tekst1 , 1 , 3)
- Lcd "."
- Lcd Mid(tekst1 , 4 , 3)
- Lcd "."
- Lcd Mid(tekst1 , 7 , 3)
- Lcd " Hz"
- Locate 2 , 1 'second line
- Select Case Stepsize
- Case 1 : Lcd " 5 Hz "
- Case 2 : Lcd " 100 Hz"
- Case 3 : Lcd " 1 kHz "
- Case 4 : Lcd " 10 kHz"
- Case 5 : Lcd " 100kHz "
- Case 6 : Lcd " 1 MHz "
- Case 7 : Lcd " 10 MHz "
- End Select
- Locate 2 , 10 'second line
- Select Case Temp1
- Case 1 : Lcd "CLK0"
- Case 2 : Lcd "CLK1"
- Case 3 : Lcd "CLK2"
- End Select
- End Sub
- '**********************************************************************
- ' subroutine to initialise the si5351 chip via I2C
- '**********************************************************************
- Sub Si5351init
- Regaddr = 183
- Regdata = 192
- Call Siout(regaddr , Regdata) 'set xtal load cap to 10pF
- Regaddr = 3
- Regdata = 0
- Call Siout(regaddr , Regdata) 'enable all outputs
- Regaddr = 15
- Regdata = 0
- Call Siout(regaddr , Regdata) 'select xtal as PLL input source
- Regaddr = 16
- Regdata = 15 'PLLA is source, 8mA output
- Call Siout(regaddr , Regdata) 'configure clock 0 control register
- Waitms 10 'wait 10ms just in case
- End Sub
- '********************************************************************************
- ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
- '********************************************************************************
- Sub Calculate
- Rdivider = 1 'initialise r
- Outdivider = 900000000 \ Gfreq 'and outdivider
- While Outdivider > 900 '900
- Rdivider = 2 * Rdivider
- Outdivider = Outdivider \ 2
- Wend
- Fvco = Outdivider Mod 2 'check outdivider is an even number
- If Fvco <> 0 Then Outdivider = Outdivider - 1 'using fvco as a temporary register
- Fvco = Outdivider * Rdivider
- Fvco = Fvco * Gfreq 'determine PLL frequency
- Select Case Rdivider 'determine value of R44 bits [6:4]
- Case 1 : Rbyte = 0 '000 0000
- Case 2 : Rbyte = 16 '001 0000
- Case 4 : Rbyte = 32 '010 0000
- Case 8 : Rbyte = 48 '011 0000
- Case 16 : Rbyte = 64 '100 0000
- Case 32 : Rbyte = 80 '101 0000
- Case 64 : Rbyte = 96 '110 0000
- Case 128 : Rbyte = 112 '111 0000
- End Select
- Afactor = Fvco \ Xtal
- Fvalue = Afactor * Xtal 'fvalue = fvco -afactor * xtal
- Fvalue = Fvco - Fvalue 'a+b/c
- Fvalue = Fvalue * Cfactor
- Fvalue = Fvalue \ Xtal
- Bfactor = Fvalue
- Ms0p1 = 128 * Outdivider
- Ms0p1 = Ms0p1 - 512
- Fvalue = 128 * Bfactor
- Fvalue = Fvalue \ Cfactor
- Finteger = Fvalue
- Msnap1 = 128 * Afactor
- Msnap1 = Msnap1 + Finteger 'finteger used instead of fvalue for variable matching
- Msnap1 = Msnap1 - 512
- Msnap3 = Finteger * Cfactor 'using msnap3 as temp result buffer
- Msnap2 = 128 * Bfactor
- Msnap2 = Msnap2 - Msnap3
- Msnap3 = Cfactor
- 'calculations are complete so now build and send the required output data bytes by calling sendfreq (About 20 bytes sent per frequency)
- End Sub
- '**********************************************************************
- ' send converted freq data to si5351 for CLK0 output
- '**********************************************************************
- Sub Sendfreq
- Regaddr = Siaddr1
- Call Siout(regaddr , Ms32) 'R26=msnap3[15:8]
- Incr Regaddr
- Call Siout(regaddr , Ms31) 'R27=msnap3[7:0]
- Incr Regaddr
- Call Siout(regaddr , Ms13) 'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
- Incr Regaddr
- Call Siout(regaddr , Ms12) 'R29=msnap1[15:8]
- Incr Regaddr
- Call Siout(regaddr , Ms11) 'R30=msnap1[7:0]
- Temp = Ms33 'temp[3:0]=msnap3[19:16]
- Swap Temp 'temp[7:4]=msnap3[19:16]
- Temp = Temp Or Ms23 'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
- Incr Regaddr
- Call Siout(regaddr , Temp) 'R31=(msnap3[19:16],msnap2[19:16])
- Incr Regaddr
- Call Siout(regaddr , Ms22) 'R32=msnap2[15:8]
- Incr Regaddr
- Call Siout(regaddr , Ms21) 'R33=msnap2[7:0]
- Regaddr = Siaddr2
- Regdata = 0
- Call Siout(regaddr , Regdata) 'R42=MS0_P3[15:8]
- Incr Regaddr
- Regdata = 1
- Call Siout(regaddr , Regdata) 'R43=MS0_P3[7:0]
- Temp = Rbyte
- Temp = Temp Or M0p13
- Incr Regaddr
- Call Siout(regaddr , Temp) 'R44=(0,R[7:4],MS0_P1[17:16])
- Incr Regaddr
- Call Siout(regaddr , M0p12) 'R45=MS0_P1[15:8]
- Incr Regaddr
- Call Siout(regaddr , M0p11) 'R46=MS0_P1[7:0]
- Incr Regaddr
- Regdata = 0
- Call Siout(regaddr , Regdata) 'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
- Incr Regaddr
- Regdata = 0
- Call Siout(regaddr , Regdata) 'R48=MS0_P2[15:8]=0 always
- Incr Regaddr
- Regdata = 0
- Call Siout(regaddr , Regdata) 'R49=MS0_P2[7:0]=0 always
- End Sub
- '===================================================================================
- ' obsluga klawiatury wpisujemy czestotliwość w Hz 150000000 , 000010000
- ' Użycie klawiszy A (Hz +) , B (Hz -) , C (step) , D (wybor_clk) wpisze do ciągu znakow " 0 "
- '===================================================================================
- Sub Zapis
- Skok1:
- Cursor On
- Cursor Blink
- Wartosc = Space(0)
- Pozycja = 0
- Locate 4 , 1 : Lcd "Nowa Hz "
- Do
- Klw = Getkbd()
- If Pozycja = 10 Then
- Frequency = Val(wartosc)
- If Frequency < 10000 Then
- Locate 4 , 1 : Lcd " MIN Hz 10.000 khz "
- Waitms 1000
- Locate 4 , 1 : Lcd "Nowa Hz "
- Goto Skok1
- End If
- If Frequency > 150000000 Then
- Locate 4 , 1 : Lcd " MAX Hz 150.000 Mhz "
- Waitms 1000
- Locate 4 , 1 : Lcd "Nowa Hz "
- Cursor Off
- Cursor Noblink
- Goto Skok1
- End If
- Update = 1
- Cursor Off
- Cursor Noblink
- Locate 4 , 1 : Lcd " "
- Goto Skok
- End If
- Waitms 300
- If Klw = 14 Then
- Wartosc = Space(0)
- Pozycja = 0
- End If
- If Klw <> 16 Then
- Znak = Lookupstr(klw , Dta)
- Insertchar Wartosc , Pozycja , Znak
- Locate 4 , 9 : Lcd Wartosc
- Pozycja = Pozycja + 1
- End If
- Loop
- End Sub
- Dta:
- Data "1" , "2" , "3" , "0" , "4" , "5" , "6" , "0" , "7" , "8" , "9" , "0" , "0" , "0" , "0" , "0"
- '**********************************************************************
- ' i2c transmission to si5351
- '**********************************************************************
- Sub Siout(sireg As Byte , Sidata As Byte)
- 'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
- 'Write a single byte (slave address 192, register sireg, value sibyte)
- I2cstart
- I2cwbyte 192 'i2c address of si5351a
- Waitus 1 'suggested delay from forum
- I2cwbyte Sireg
- Waitus 1
- I2cwbyte Sidata
- Waitus 1
- I2cstop
- End Sub
Sposób podłączenia klawiatury do portu . Klawisze numeryczne wiadomo do czego służą

"A " częstotliwość +
"B" częstotliwość -
"C" krok częstotliwości
"D" wybór wyjścia CLK0 , CLK1 , CLK2 które chcemy regulować
" * " wejście w tryb wprowadzania częstotliwości z klawiatury
" # " cofanie na początek wiersza w razie błędu podczas pisania
Częstotliwość wpisujemy dziewięć cyfr częstotliwości w Hz np. 145500000 , 000555000 , użycie klawiszy A,B,C,D wstawi wartość 0 do ciągu znaków .
Dziesiąta pozycja wpisze automatycznie częstotliwość do generatora .
Pozdrawiam Henryk
