Generator Si5351

Pytania, kody i porady dotyczące nie tylko Bascom.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 25 mar 2023, 13:03

Witam :)

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 .
  1.    $regfile = "m8def.dat"
  2.     $crystal = 8000000                                      '8MHz internal RC clock
  3.  
  4.     $hwstack = 128
  5.     $swstack = 64
  6.     $framesize = 128
  7.  
  8.   '-------------------------------------------------------------------------------
  9.     Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
  10.     Config Lcd = 20 * 4
  11.  
  12.     Config Portb.1 = Output                                 'dds
  13.     Config Portb.2 = Output                                 'dds
  14.     Config Sda = Portb.1
  15.     Config Scl = Portb.2
  16.     Config Kbd = Portd                                      'klawiatura 4x4
  17.     Set Portb.1
  18.     Set Portb.2
  19.  
  20.         ' Declare Variables
  21.  
  22.     Dim Mhz As String * 2                                   'display subroutine variables
  23.     Dim Khz As String * 3
  24.     Dim Hz As String * 3
  25.     Dim Lastftext As String * 6                             'for display of freqb khz & Hz digits
  26.     Dim Freqtxt As String * 9
  27.     Dim Tekst1 As String * 9
  28.     Dim Mem_hz(3) As Dword                                  ' pamieć częstotliwości
  29.     Dim Fcnt As Byte
  30.     Dim Temp As Byte                                        'temporary variable used in sendfreq and sbarplot routines
  31.     Dim Temp1 As Byte                                       ' temp dla pamiec czestotliwosci
  32.     Dim Frequency As Dword                                  'four byte unsigned variable
  33.     Dim Gfreq As Dword                                      'calculates si5351 VFO output frequency
  34.     Dim Stepsize As Byte
  35.     Dim Delta As Dword
  36.     Dim Update As Bit                                       'bit is set (1) if a switch or encoder has changed
  37.     Dim Fvco As Dword                                       'si5351 vco frequency
  38.     Dim Outdivider As Dword                                 '4,6,8-900
  39.     Dim Rdivider As Byte                                    'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  40.     Dim Rbyte As Byte                                       'used as temp store before final data load to si5351
  41.     Dim Afactor As Dword
  42.     Dim Bfactor As Dword
  43.     Dim Fvalue As Single                                    'used to determine accuracy of fractional calculation
  44.     Dim Finteger As Dword
  45.     Dim Klw As Byte , Pozycja As Byte                       'klawiatura
  46.     Dim Znak As String * 1 , Wartosc As String * 9          ' klawiatura
  47.  
  48.  
  49.     Dim Ms0p1 As Dword                                      '18-bit MS0_P1 si5351 parameters for Output 0
  50.     Dim M0p11 As Byte At Ms0p1 Overlay                      'mirrored variables for dds calculation
  51.     Dim M0p12 As Byte At Ms0p1 + 1 Overlay
  52.     Dim M0p13 As Byte At Ms0p1 + 2 Overlay
  53.     Dim M0p14 As Byte At Ms0p1 + 3 Overlay                  'most significant byte for ms0p1
  54.  
  55.     'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  56.                                                           'si5351 parameters for PLLA
  57.     Dim Msnap1 As Dword                                     '18-bit variable for MSNA_P1
  58.     Dim Ms11 As Byte At Msnap1 Overlay                      'mirrored variables for dds calculation
  59.     Dim Ms12 As Byte At Msnap1 + 1 Overlay
  60.     Dim Ms13 As Byte At Msnap1 + 2 Overlay
  61.     Dim Ms14 As Byte At Msnap1 + 3 Overlay                  'most significant byte
  62.  
  63.     Dim Msnap2 As Dword                                     '20-bit variable for MSNA_P2
  64.     Dim Ms21 As Byte At Msnap2 Overlay                      'mirrored variables for dds calculation
  65.     Dim Ms22 As Byte At Msnap2 + 1 Overlay
  66.     Dim Ms23 As Byte At Msnap2 + 2 Overlay
  67.     Dim Ms24 As Byte At Msnap2 + 3 Overlay                  'most significant byte
  68.  
  69.     Dim Msnap3 As Dword                                     '20-bit variable for MSNA_P3
  70.     Dim Ms31 As Byte At Msnap3 Overlay                      'mirrored variables for dds calculation
  71.     Dim Ms32 As Byte At Msnap3 + 1 Overlay
  72.     Dim Ms33 As Byte At Msnap3 + 2 Overlay
  73.     Dim Ms34 As Byte At Msnap3 + 3 Overlay                  'most significant byte
  74.  
  75.     Dim Regaddr As Byte , Regdata As Byte                   'for i2c calls
  76.     Dim Siaddr1 As Byte , Siaddr2 As Byte                   'for writing to si5351 CLK0 and CLK1
  77.  
  78.         '    Declare Constants
  79.     Const Startfreq = 10000                                 'xxx                          '40m starting frequency
  80.     Const Xtal = 25001400                                   ' xxx 25000000   '**NOTE: Value may be adjusted during alignment ***
  81.     Const Cfactor = 1048575                                 'xxx 1048575
  82.  
  83.     Frequency = Startfreq                                   'initialise frequency (20m for now)
  84.     Stepsize = 3
  85.     Delta = 1000
  86.     Temp1 = 0
  87.     Mem_hz(1) = 30000                                       ' Częstotliwości startowe pamięci
  88.     Mem_hz(2) = 20000
  89.     Mem_hz(3) = 10000
  90.     '     Declare Subroutines
  91.     Declare Sub Si5351init                                  'initialises si5351
  92.     Declare Sub Displaylcd                                  'displays current oscillator frequency
  93.     Declare Sub Calculate                                   'converts current VFO or BFO freq to data for si5351
  94.     Declare Sub Sendfreq                                    'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  95.     Declare Sub Siout(sireg As Byte , Sidata As Byte)       'for i2c write to si5351
  96.     Declare Sub Wybor_clk
  97.     Declare Sub Zapis
  98.     '***************************** Program *****************************************
  99.  
  100.     '      initialise i2c here...
  101.     I2cinit
  102.     Waitms 50                                               'for i2c to settle and for lcd RC reset time
  103.     Cursor Off                                              'LCD cursor of
  104.     Cls
  105.     Update = 0                                              'clear the flags
  106.  
  107.     Si5351init                                              'initialises si5351
  108.     Gfreq = Frequency
  109.      Calculate
  110.     Siaddr1 = 26
  111.     Siaddr2 = 42
  112.      Sendfreq
  113.     Regaddr = 16
  114.     Regdata = 79
  115.      Call Siout(regaddr , Regdata)
  116.     Siaddr1 = 34
  117.     Siaddr2 = 50
  118.      Sendfreq
  119.     Siaddr1 = 34
  120.     Siaddr2 = 58
  121.      Sendfreq
  122.     Regaddr = 17
  123.     Regdata = 111
  124.       Call Siout(regaddr , Regdata)
  125.     Regaddr = 18
  126.     Regdata = 111
  127.       Call Siout(regaddr , Regdata)
  128.      Wybor_clk
  129.     Displaylcd                                              'then display frequency and status on lcd
  130.  
  131.  
  132.     Do                                                      'Start of main program
  133.       Skok:
  134.      If Klw = 11 Then
  135.           Incr Stepsize
  136.           Waitms 500                                        ' xxx
  137.        If Stepsize = 8 Then                                 'xxx
  138.           Stepsize = 1
  139.        End If
  140.        If Stepsize = 1 Then Delta = 5                       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  141.        If Stepsize = 2 Then Delta = 100                     '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  142.        If Stepsize = 3 Then Delta = 1000
  143.        If Stepsize = 4 Then Delta = 10000
  144.        If Stepsize = 5 Then Delta = 100000                  'xxx
  145.        If Stepsize = 6 Then Delta = 1000000                 ' xxx
  146.        If Stepsize = 7 Then Delta = 10000000                ' xxx
  147.         Update = 1
  148.          Displaylcd                                         'to flag this change
  149.      End If
  150.       If Klw = 3 Then                                       ' Hz +
  151.           Frequency = Frequency + Delta
  152.            If Frequency > 150000000 Then
  153.               Frequency = 150000000
  154.  
  155.            End If
  156.            Update = 1
  157.           Displaylcd
  158.  
  159.       End If
  160.  
  161.       If Klw = 7 Then                                       ' Hz -
  162.         Frequency = Frequency - Delta
  163.  
  164.          If Frequency > 150000000 Then
  165.             Frequency = 10000
  166.          End If
  167.          If Frequency < 10000 Then
  168.              Frequency = 10000
  169.          End If
  170.            Update = 1
  171.           Displaylcd
  172.  
  173.       End If
  174.  
  175.       If Klw = 15 Then : Wybor_clk : End If                 ' Wybor_clk
  176.  
  177.      If Update = 1 Then                                     'encoder or buttons changed so update display and si5351
  178.                                                             'show new frequency and status
  179.        Gfreq = Frequency
  180.          Displaylcd                                         'gfreq holds value used for si5351
  181.          Calculate                                          'calculate new VFO data
  182.          Sendfreq                                           'and send it to the si5351
  183.          Call Siout(regaddr , Regdata)                      'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  184.          Update = 0
  185.                                                             'and update flag
  186.      End If
  187.       '============================================================================
  188.       '   Przejście do Sub zapis nowej Hz , zabezpieczenie przekroczenia Hz
  189.       '============================================================================
  190.       Waitms 100
  191.        Klw = Getkbd()
  192.        If Klw = 12 Then
  193.          Locate 4 , 1 : Lcd "                    "
  194.            Zapis
  195.        End If
  196.  
  197.     Loop                                                    'End of main program
  198.    End
  199.  
  200.     '**********************************************************************
  201.     'Subroutines...
  202.     '=====================================================================
  203.  
  204.     '==============================================================================================
  205.               ' wybór wyjścia clk0 , clk1 , clk2
  206.     '==============================================================================================
  207.       Sub Wybor_clk
  208.            Incr Temp1
  209.            Waitms 500
  210.         If Temp1 = 1 Then
  211.            Mem_hz(3) = Frequency                            'pamięć hz clk2
  212.            Frequency = Mem_hz(1)                            ' odczyt hz clk0
  213.            Siaddr1 = 26                                     'adres początkowy PLLA
  214.            Siaddr2 = 42                                     'adres początkowy CLK0
  215.            Update = 1
  216.           Elseif Temp1 = 2 Then
  217.            Mem_hz(1) = Frequency                            'pamięć hz clk0
  218.            Frequency = Mem_hz(2)                            ' odczyt hz clk1
  219.            Siaddr1 = 34                                     'adres początkowy PLLB
  220.            Siaddr2 = 50                                     'adres początkowy CLK1
  221.            Update = 1
  222.           Elseif Temp1 = 3 Then
  223.            Mem_hz(2) = Frequency                            'pamięć hz clk1
  224.            Frequency = Mem_hz(3)                            ' odczyt hz clk2
  225.            Siaddr1 = 34                                     'adres początkowy PLLB
  226.            Siaddr2 = 58                                     'adres początkowy CLK2
  227.            Update = 1
  228.         End If
  229.           If Temp1 = 4 Then
  230.             Temp1 = 0
  231.           End If
  232.       End Sub
  233.  
  234.     '========================================================================
  235.  
  236.     '========================================================================
  237.     Sub Displaylcd
  238.                            '
  239.          Tekst1 = "000000000"
  240.        Freqtxt = Str(frequency)                             ' (frequency)
  241.        Fcnt = Len(freqtxt)
  242.      If Fcnt = 1 Then
  243.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    ' 9
  244.            Elseif Fcnt = 2 Then
  245.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    ' 8
  246.            Elseif Fcnt = 3 Then
  247.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    ' 7
  248.            Elseif Fcnt = 4 Then
  249.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    ' 6
  250.            Elseif Fcnt = 5 Then
  251.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    ' 5
  252.            Elseif Fcnt = 6 Then
  253.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    ' 5
  254.            Elseif Fcnt = 7 Then
  255.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    ' 3
  256.            Elseif Fcnt = 8 Then
  257.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    ' 2
  258.            Elseif Fcnt = 9 Then
  259.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    ' 1
  260.      End If
  261.  
  262.           Locate 1 , 2
  263.            Lcd Mid(tekst1 , 1 , 3)
  264.            Lcd "."
  265.          Lcd Mid(tekst1 , 4 , 3)
  266.           Lcd "."
  267.          Lcd Mid(tekst1 , 7 , 3)
  268.           Lcd " Hz"
  269.           Locate 2 , 1                                      'second line
  270.      Select Case Stepsize
  271.        Case 1 : Lcd " 5 Hz  "
  272.        Case 2 : Lcd " 100 Hz"
  273.        Case 3 : Lcd " 1 kHz "
  274.        Case 4 : Lcd " 10 kHz"
  275.        Case 5 : Lcd " 100kHz "
  276.        Case 6 : Lcd " 1 MHz "
  277.        Case 7 : Lcd " 10 MHz "
  278.      End Select
  279.  
  280.         Locate 2 , 10                                       'second line
  281.      Select Case Temp1
  282.        Case 1 : Lcd "CLK0"
  283.        Case 2 : Lcd "CLK1"
  284.        Case 3 : Lcd "CLK2"
  285.  
  286.  
  287.  
  288.      End Select
  289.  
  290.  
  291.     End Sub
  292.  
  293.     '**********************************************************************
  294.     ' subroutine to initialise the si5351 chip via I2C
  295.     '**********************************************************************
  296.  
  297.     Sub Si5351init
  298.  
  299.         Regaddr = 183
  300.         Regdata = 192
  301.      Call Siout(regaddr , Regdata)                          'set xtal load cap to 10pF
  302.         Regaddr = 3
  303.         Regdata = 0
  304.      Call Siout(regaddr , Regdata)                          'enable all outputs
  305.         Regaddr = 15
  306.         Regdata = 0
  307.      Call Siout(regaddr , Regdata)                          'select xtal as PLL input source
  308.         Regaddr = 16
  309.         Regdata = 15                                        'PLLA is source, 8mA output
  310.      Call Siout(regaddr , Regdata)                          'configure clock 0 control register
  311.       Waitms 10                                             'wait 10ms just in case
  312.  
  313.     End Sub
  314.  
  315.     '********************************************************************************
  316.     ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  317.     '********************************************************************************
  318.     Sub Calculate
  319.  
  320.         Rdivider = 1                                        'initialise r
  321.         Outdivider = 900000000 \ Gfreq                      'and outdivider
  322.       While Outdivider > 900                                '900
  323.         Rdivider = 2 * Rdivider
  324.         Outdivider = Outdivider \ 2
  325.       Wend
  326.         Fvco = Outdivider Mod 2                             'check outdivider is an even number
  327.  
  328.       If Fvco <> 0 Then Outdivider = Outdivider - 1         'using fvco as a temporary register
  329.         Fvco = Outdivider * Rdivider
  330.         Fvco = Fvco * Gfreq                                 'determine PLL frequency
  331.      Select Case Rdivider                                   'determine value of R44 bits [6:4]
  332.         Case 1 : Rbyte = 0                                  '000 0000
  333.         Case 2 : Rbyte = 16                                 '001 0000
  334.         Case 4 : Rbyte = 32                                 '010 0000
  335.         Case 8 : Rbyte = 48                                 '011 0000
  336.         Case 16 : Rbyte = 64                                '100 0000
  337.         Case 32 : Rbyte = 80                                '101 0000
  338.         Case 64 : Rbyte = 96                                '110 0000
  339.         Case 128 : Rbyte = 112                              '111 0000
  340.      End Select
  341.        Afactor = Fvco \ Xtal
  342.        Fvalue = Afactor * Xtal                              'fvalue = fvco -afactor * xtal
  343.        Fvalue = Fvco - Fvalue                               'a+b/c
  344.        Fvalue = Fvalue * Cfactor
  345.        Fvalue = Fvalue \ Xtal
  346.        Bfactor = Fvalue
  347.        Ms0p1 = 128 * Outdivider
  348.        Ms0p1 = Ms0p1 - 512
  349.        Fvalue = 128 * Bfactor
  350.        Fvalue = Fvalue \ Cfactor
  351.        Finteger = Fvalue
  352.        Msnap1 = 128 * Afactor
  353.        Msnap1 = Msnap1 + Finteger                           'finteger used instead of fvalue for variable matching
  354.        Msnap1 = Msnap1 - 512
  355.        Msnap3 = Finteger * Cfactor                          'using msnap3 as temp result buffer
  356.        Msnap2 = 128 * Bfactor
  357.        Msnap2 = Msnap2 - Msnap3
  358.        Msnap3 = Cfactor
  359.      'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  360.     End Sub
  361.  
  362.     '**********************************************************************
  363.     ' send converted freq data to si5351 for CLK0 output
  364.     '**********************************************************************
  365.     Sub Sendfreq
  366.  
  367.           Regaddr = Siaddr1
  368.      Call Siout(regaddr , Ms32)                             'R26=msnap3[15:8]
  369.      Incr Regaddr
  370.      Call Siout(regaddr , Ms31)                             'R27=msnap3[7:0]
  371.      Incr Regaddr
  372.      Call Siout(regaddr , Ms13)                             'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  373.      Incr Regaddr
  374.      Call Siout(regaddr , Ms12)                             'R29=msnap1[15:8]
  375.      Incr Regaddr
  376.      Call Siout(regaddr , Ms11)                             'R30=msnap1[7:0]
  377.           Temp = Ms33                                       'temp[3:0]=msnap3[19:16]
  378.      Swap Temp                                              'temp[7:4]=msnap3[19:16]
  379.           Temp = Temp Or Ms23                               'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  380.      Incr Regaddr
  381.      Call Siout(regaddr , Temp)                             'R31=(msnap3[19:16],msnap2[19:16])
  382.      Incr Regaddr
  383.      Call Siout(regaddr , Ms22)                             'R32=msnap2[15:8]
  384.      Incr Regaddr
  385.      Call Siout(regaddr , Ms21)                             'R33=msnap2[7:0]
  386.  
  387.  
  388.           Regaddr = Siaddr2
  389.           Regdata = 0
  390.      Call Siout(regaddr , Regdata)                          'R42=MS0_P3[15:8]
  391.      Incr Regaddr
  392.           Regdata = 1
  393.      Call Siout(regaddr , Regdata)                          'R43=MS0_P3[7:0]
  394.           Temp = Rbyte
  395.           Temp = Temp Or M0p13
  396.      Incr Regaddr
  397.      Call Siout(regaddr , Temp)                             'R44=(0,R[7:4],MS0_P1[17:16])
  398.      Incr Regaddr
  399.      Call Siout(regaddr , M0p12)                            'R45=MS0_P1[15:8]
  400.      Incr Regaddr
  401.      Call Siout(regaddr , M0p11)                            'R46=MS0_P1[7:0]
  402.      Incr Regaddr
  403.           Regdata = 0
  404.      Call Siout(regaddr , Regdata)                          'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  405.      Incr Regaddr
  406.           Regdata = 0
  407.      Call Siout(regaddr , Regdata)                          'R48=MS0_P2[15:8]=0 always
  408.      Incr Regaddr
  409.           Regdata = 0
  410.      Call Siout(regaddr , Regdata)                          'R49=MS0_P2[7:0]=0 always
  411.  
  412.  
  413.     End Sub
  414.     '===================================================================================
  415.     '   obsluga klawiatury       wpisujemy czestotliwość w Hz   150000000   , 000010000
  416.     '      Użycie klawiszy A (Hz +) , B (Hz -) , C (step) , D (wybor_clk) wpisze do ciągu znakow " 0 "
  417.     '===================================================================================
  418.     Sub Zapis
  419.          Skok1:
  420.         Cursor On
  421.         Cursor Blink
  422.         Wartosc = Space(0)
  423.         Pozycja = 0
  424.         Locate 4 , 1 : Lcd "Nowa Hz "
  425.        Do
  426.  
  427.             Klw = Getkbd()
  428.  
  429.           If Pozycja = 10 Then
  430.                Frequency = Val(wartosc)
  431.               If Frequency < 10000 Then
  432.                   Locate 4 , 1 : Lcd " MIN Hz 10.000 khz "
  433.                    Waitms 1000
  434.                   Locate 4 , 1 : Lcd "Nowa Hz             "
  435.                   Goto Skok1
  436.               End If
  437.  
  438.              If Frequency > 150000000 Then
  439.                Locate 4 , 1 : Lcd " MAX Hz 150.000 Mhz "
  440.                 Waitms 1000
  441.                Locate 4 , 1 : Lcd "Nowa Hz             "
  442.                  Cursor Off
  443.                  Cursor Noblink
  444.  
  445.                   Goto Skok1
  446.              End If
  447.               Update = 1
  448.                Cursor Off
  449.                  Cursor Noblink
  450.                   Locate 4 , 1 : Lcd "                    "
  451.                    Goto Skok
  452.           End If
  453.              Waitms 300
  454.           If Klw = 14 Then
  455.               Wartosc = Space(0)
  456.                Pozycja = 0
  457.           End If
  458.           If Klw <> 16 Then
  459.              Znak = Lookupstr(klw , Dta)
  460.                Insertchar Wartosc , Pozycja , Znak
  461.                  Locate 4 , 9 : Lcd Wartosc
  462.                   Pozycja = Pozycja + 1
  463.           End If
  464.  
  465.        Loop
  466.     End Sub
  467.  
  468.  
  469. Dta:
  470. Data "1" , "2" , "3" , "0" , "4" , "5" , "6" , "0" , "7" , "8" , "9" , "0" , "0" , "0" , "0" , "0"
  471.  
  472.  
  473.  
  474.     '**********************************************************************
  475.     ' i2c transmission to si5351
  476.     '**********************************************************************
  477.     Sub Siout(sireg As Byte , Sidata As Byte)
  478.      'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  479.      'Write a single byte (slave address 192, register sireg, value sibyte)
  480.      I2cstart
  481.      I2cwbyte 192                                           'i2c address of si5351a
  482.      Waitus 1                                               'suggested delay from forum
  483.      I2cwbyte Sireg
  484.      Waitus 1
  485.      I2cwbyte Sidata
  486.      Waitus 1
  487.      I2cstop
  488.  
  489.     End Sub
Klawiatura użyta jest taka sama jak na obrazku .
Sposób podłączenia klawiatury do portu .
klawiatura 4x4 do si5351.JPG
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 :D
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Generator Si5351

Post autor: Jacek » 25 mar 2023, 15:31

Pan Henryk piękna robota.
pozdrawiam Jacek.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 26 mar 2023, 13:42

Jacek pisze:
25 mar 2023, 15:31
Pan Henryk piękna robota.
pozdrawiam Jacek.
Dziękuje Jacku , do pięknej roboty jeszcze daleko ;)

Na chwilę obecną generator wylądował w zgrabnym pudełku jako podręczny przyrządzik radiowy .
si5351.JPG
Teraz konieczna jest optymalizacja kodu , bo po ostatnich moich modyfikacjach ( których brak w wersji zamieszczonej w wątku ;) ) zostało mi wolnej pamięci w procku 100 bajtów :(
Na sam koniec jeszcze jeden problem jaki mnie dotyka , to pomiar częstotliwości oscylatora z którym mam spory kłopot .Skubany układ jest tak mały , że nie potrafię precyzyjnie przyłożyć sondy pomiarowej .

Pozdrawiam Henryk .
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Generator Si5351

Post autor: Jacek » 26 mar 2023, 17:48

Fajny przyrząd a możesz przypomnieć do ilu śmiga MHz? przydał by się taki w moim schack'u ;)
pozdrawiam Jacek.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 26 mar 2023, 18:17

Śmiga od 10 kHz do 150 MHz , powyżej mój moduł się dusi .
Jeszcze nie ogarniam tej matematyki w subach PLL , jak " rozgryzę " co autor przykładu miał na myśli to będzie śmigać do 160 MHz .
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Generator Si5351

Post autor: Jacek » 26 mar 2023, 21:12

Witam to jak projekt będzie gotowy to ja się piszę na pcb jeśli będzie dostępne oraz kod.
pozdrawiam Jacek.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 27 mar 2023, 9:40

Jacek pisze:
26 mar 2023, 21:12
Witam to jak projekt będzie gotowy to ja się piszę na pcb jeśli będzie dostępne oraz kod.
pozdrawiam Jacek.
Płytki pcb nie planuje projektować bo ten układzik można złożyć na płytce uniwersalnej ;)
si5351_schemat.JPG
Co do kodu , to ten z klawiaturą można ładować do procka , a jak będzie już w ostatecznej wersji to sobie zrobisz aktualizację .

Pozdrawiam Henryk .
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 30 mar 2023, 17:43

Dzieńdoberek :)
Na ile wiedza pozwoliła , na tyle namieszałem w programie .
Dodane opcje :
Regulacja prądu wyjściowego wybranego generatora 2 , 4 , 6 , 8 mA .
W linii 3 mamy częstotliwość x mnożnik powielacza + częstotliwość pośrednia .
Dodane są trzy częstotliwości pośrednie 455 kHz , 9 MHz i 10,7 MHz .
Klawiszologia na fotce .
opis_klw.JPG
Ufff ..więcej z mojej głowy nie wydusze , to jest wersja ostatnia ;)
Na moje potrzeby zupełnie wystarczy .
  1.    $regfile = "m8def.dat"
  2.     $crystal = 8000000                                      '8MHz internal RC clock
  3.  
  4.     $hwstack = 128
  5.     $swstack = 64
  6.     $framesize = 128
  7.  
  8.   '-------------------------------------------------------------------------------
  9.     Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
  10.     Config Lcd = 20 * 4
  11.  
  12.     Config Portb.1 = Output                                 'dds
  13.     Config Portb.2 = Output                                 'dds
  14.     Config Sda = Portb.1
  15.     Config Scl = Portb.2
  16.     Config Kbd = Portd                                      'klawiatura 4x4
  17.     Set Portb.1
  18.     Set Portb.2
  19.  
  20.         ' Declare Variables
  21.  
  22.     Dim Mhz As String * 2                                   'display subroutine variables
  23.     Dim Khz As String * 3
  24.     Dim Hz As String * 3
  25.     Dim Lastftext As String * 6                             'for display of freqb khz & Hz digits
  26.     Dim Freqtxt As String * 9
  27.     Dim Tekst1 As String * 9
  28.     Dim Mem_hz(3) As Dword                                  ' pamieć częstotliwości
  29.     Dim Miliamp(3) As Byte                                  ' pamięć prądu wyjściowego
  30.     Dim Fcnt As Byte
  31.     Dim Temp As Byte                                        'temporary variable used in sendfreq and sbarplot routines
  32.     Dim Temp1 As Byte                                       ' temp dla pamiec czestotliwosci
  33.     Dim Temp2 As Byte                                       ' temp dla wyboru pośredniej częstotliwości
  34.     Dim Temp3 As Byte
  35.     Dim Powiel As Byte                                      ' zmienna mnoznik powielacza
  36.     Dim Frequency As Dword                                  'four byte unsigned variable
  37.     Dim Hz_temp As Dword
  38.     Dim Gfreq As Dword                                      'calculates si5351 VFO output frequency
  39.     Dim Stepsize As Byte
  40.     Dim Delta As Dword
  41.     Dim Update As Bit                                       'bit is set (1) if a switch or encoder has changed
  42.     Dim Fvco As Dword                                       'si5351 vco frequency
  43.     Dim Outdivider As Dword                                 '4,6,8-900
  44.     Dim Rdivider As Byte                                    'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  45.     Dim Rbyte As Byte                                       'used as temp store before final data load to si5351
  46.     Dim Afactor As Dword
  47.     Dim Bfactor As Dword
  48.     Dim Fvalue As Single                                    'used to determine accuracy of fractional calculation
  49.     Dim Posrednia As Dword                                  'częstotliwość pośrednia
  50.     Dim Finteger As Dword
  51.     Dim Klw As Byte , Pozycja As Byte                       'klawiatura
  52.     Dim Znak As String * 1 , Wartosc As String * 9          ' klawiatura
  53.  
  54.  
  55.     Dim Ms0p1 As Dword                                      '18-bit MS0_P1 si5351 parameters for Output 0
  56.     Dim M0p11 As Byte At Ms0p1 Overlay                      'mirrored variables for dds calculation
  57.     Dim M0p12 As Byte At Ms0p1 + 1 Overlay
  58.     Dim M0p13 As Byte At Ms0p1 + 2 Overlay
  59.     Dim M0p14 As Byte At Ms0p1 + 3 Overlay                  'most significant byte for ms0p1
  60.  
  61.     'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  62.                                                           'si5351 parameters for PLLA
  63.     Dim Msnap1 As Dword                                     '18-bit variable for MSNA_P1
  64.     Dim Ms11 As Byte At Msnap1 Overlay                      'mirrored variables for dds calculation
  65.     Dim Ms12 As Byte At Msnap1 + 1 Overlay
  66.     Dim Ms13 As Byte At Msnap1 + 2 Overlay
  67.     Dim Ms14 As Byte At Msnap1 + 3 Overlay                  'most significant byte
  68.  
  69.     Dim Msnap2 As Dword                                     '20-bit variable for MSNA_P2
  70.     Dim Ms21 As Byte At Msnap2 Overlay                      'mirrored variables for dds calculation
  71.     Dim Ms22 As Byte At Msnap2 + 1 Overlay
  72.     Dim Ms23 As Byte At Msnap2 + 2 Overlay
  73.     Dim Ms24 As Byte At Msnap2 + 3 Overlay                  'most significant byte
  74.  
  75.     Dim Msnap3 As Dword                                     '20-bit variable for MSNA_P3
  76.     Dim Ms31 As Byte At Msnap3 Overlay                      'mirrored variables for dds calculation
  77.     Dim Ms32 As Byte At Msnap3 + 1 Overlay
  78.     Dim Ms33 As Byte At Msnap3 + 2 Overlay
  79.     Dim Ms34 As Byte At Msnap3 + 3 Overlay                  'most significant byte
  80.  
  81.     Dim Regaddr As Byte , Regdata As Byte                   'for i2c calls
  82.     Dim Siaddr1 As Byte , Siaddr2 As Byte                   'for writing to si5351 CLK0 and CLK1
  83.  
  84.         '    Declare Constants
  85.     Const Startfreq = 10000                                 'xxx                          '40m starting frequency
  86.     Const Xtal = 25001400                                   ' xxx 25000000   '**NOTE: Value may be adjusted during alignment ***
  87.     Const Cfactor = 1048575                                 'xxx 1048575
  88.  
  89.  
  90.  
  91.     Powiel = 1
  92.     Temp1 = 0
  93.     Temp2 = 1
  94.     Temp3 = 0
  95.     Posrednia = 0
  96.     Frequency = Startfreq                                   'initialise frequency (20m for now)
  97.     Stepsize = 3
  98.     Delta = 1000
  99.  
  100.     Mem_hz(1) = 30000                                       ' Częstotliwości startowe pamięci
  101.     Mem_hz(2) = 20000
  102.     Mem_hz(3) = 10000
  103.     Miliamp(1) = 8
  104.     Miliamp(2) = 8
  105.     Miliamp(3) = 8
  106.  
  107.     '     Declare Subroutines
  108.     Declare Sub Si5351init                                  'initialises si5351
  109.     Declare Sub Displaylcd                                  'displays current oscillator frequency
  110.     Declare Sub Calculate                                   'converts current VFO or BFO freq to data for si5351
  111.     Declare Sub Sendfreq                                    'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  112.     Declare Sub Siout(sireg As Byte , Sidata As Byte)       'for i2c write to si5351
  113.     Declare Sub Wybor_clk
  114.     Declare Sub Zapis
  115.     Declare Sub Ma_out
  116.  
  117.     '***************************** Program *****************************************
  118.  
  119.     '      initialise i2c here...
  120.     I2cinit
  121.     Waitms 50                                               'for i2c to settle and for lcd RC reset time
  122.     Cursor Off                                              'LCD cursor of
  123.     Cls
  124.     Update = 0                                              'clear the flags
  125.  
  126.     Si5351init                                              'initialises si5351
  127.     Gfreq = Frequency
  128.      Calculate
  129.     Siaddr1 = 26
  130.     Siaddr2 = 42
  131.      Sendfreq
  132.     Regaddr = 16
  133.     Regdata = 79
  134.      Call Siout(regaddr , Regdata)
  135.     Siaddr1 = 34
  136.     Siaddr2 = 50
  137.      Sendfreq
  138.     Siaddr1 = 34
  139.     Siaddr2 = 58
  140.      Sendfreq
  141.     Regaddr = 17
  142.     Regdata = 111
  143.       Call Siout(regaddr , Regdata)
  144.     Regaddr = 18
  145.     Regdata = 111
  146.       Call Siout(regaddr , Regdata)
  147.      Wybor_clk
  148.      Displaylcd                                             'then display frequency and status on lcd
  149.  
  150.  
  151.     Do                                                      'Start of main program
  152.       Skok:
  153.        If Temp1 = 0 Then
  154.           Locate 2 , 15 : Lcd "mA " ; Miliamp(3)
  155.          Elseif Temp1 > 0 Then
  156.           Locate 2 , 15 : Lcd "mA " ; Miliamp(temp1)
  157.        End If
  158.       Locate 4 , 1 : Lcd "Pcz " ; Posrednia
  159.       Locate 3 , 15 : Lcd " x " ; Powiel
  160.        If Klw < 15 Then : Ma_out : End If
  161.      If Klw = 11 Then
  162.           Incr Stepsize
  163.           Waitms 200                                        ' xxx
  164.        If Stepsize = 8 Then                                 'xxx
  165.           Stepsize = 1
  166.        End If
  167.        If Stepsize = 1 Then Delta = 5                       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  168.        If Stepsize = 2 Then Delta = 100                     '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  169.        If Stepsize = 3 Then Delta = 1000
  170.        If Stepsize = 4 Then Delta = 10000
  171.        If Stepsize = 5 Then Delta = 100000                  'xxx
  172.        If Stepsize = 6 Then Delta = 1000000                 ' xxx
  173.        If Stepsize = 7 Then Delta = 10000000                ' xxx
  174.         Update = 1
  175.          Displaylcd                                         'to flag this change
  176.      End If
  177.       If Klw = 3 Then                                       ' Hz +
  178.           Frequency = Frequency + Delta
  179.            If Frequency > 150000000 Then
  180.               Frequency = 150000000
  181.  
  182.            End If
  183.            Update = 1
  184.           Displaylcd
  185.  
  186.       End If
  187.  
  188.       If Klw = 7 Then                                       ' Hz -
  189.         Frequency = Frequency - Delta
  190.  
  191.          If Frequency > 150000000 Then
  192.             Frequency = 10000
  193.          End If
  194.          If Frequency < 10000 Then
  195.              Frequency = 10000
  196.          End If
  197.            Update = 1
  198.           Displaylcd
  199.  
  200.       End If
  201.  
  202.        '=============================================================================
  203.        ' wybór częstotliwości pośredniej
  204.        '=============================================================================
  205.        If Klw = 14 Then
  206.              Incr Temp2
  207.             Waitms 300
  208.           If Temp2 = 1 Then
  209.             Posrednia = 0
  210.             Elseif Temp2 = 2 Then
  211.              Posrednia = 455000
  212.             Elseif Temp2 = 3 Then
  213.              Posrednia = 9000000
  214.             Elseif Temp2 = 4 Then
  215.              Posrednia = 10700000
  216.             Elseif Temp2 > 4 Then
  217.              Posrednia = 0
  218.              Temp2 = 0
  219.              Locate 4 , 5 : Lcd Posrednia ; "        "
  220.  
  221.           End If
  222.           Displaylcd
  223.        End If
  224.      '======================================================================
  225.               ' mnoznik powielacza
  226.      '================================================================
  227.         If Klw = 0 Then
  228.              Incr Temp3
  229.             Waitms 300
  230.           If Temp3 = 1 Then
  231.             Powiel = 1
  232.             Elseif Temp3 = 2 Then
  233.              Powiel = 2
  234.             Elseif Temp3 = 3 Then
  235.              Powiel = 3
  236.             Elseif Temp3 = 4 Then
  237.              Powiel = 4
  238.             Elseif Temp3 > 4 Then
  239.              Powiel = 1
  240.              Temp3 = 0
  241.  
  242.           End If
  243.             Displaylcd
  244.         End If
  245.  
  246.         If Klw = 15 Then : Wybor_clk : End If               ' Wybor_clk
  247.  
  248.      If Update = 1 Then                                     'encoder or buttons changed so update display and si5351
  249.                                                             'show new frequency and status
  250.        Gfreq = Frequency
  251.          Displaylcd                                         'gfreq holds value used for si5351
  252.          Calculate                                          'calculate new VFO data
  253.          Sendfreq                                           'and send it to the si5351
  254.          Call Siout(regaddr , Regdata)                      'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  255.          Update = 0
  256.                                                             'and update flag
  257.      End If
  258.  
  259.       Waitms 100
  260.        Klw = Getkbd()
  261.        If Klw = 12 Then                                     '   Przejście do Sub zapis nowej Hz
  262.          Locate 4 , 1 : Lcd "                    "
  263.            Zapis
  264.        End If
  265.  
  266.     Loop                                                    'End of main program
  267.    End
  268.  
  269.     '**********************************************************************
  270.     'Subroutines...
  271.     '=====================================================================
  272.  
  273.  
  274.     '===============================================================================
  275.       ' blok ustawień prądu wyjściowego clk0 , clk1 , clk2
  276.       '================================================================================
  277.      Sub Ma_out
  278.  
  279.        If Temp1 = 1 Then
  280.  
  281.          If Klw = 1 Then
  282.             Regaddr = 16
  283.             Regdata = 76
  284.             Miliamp(1) = 2
  285.           Elseif Klw = 4 Then
  286.             Regaddr = 16
  287.             Regdata = 77
  288.             Miliamp(1) = 4
  289.           Elseif Klw = 6 Then
  290.             Regaddr = 16
  291.             Regdata = 78
  292.             Miliamp(1) = 6
  293.           Elseif Klw = 9 Then
  294.             Regaddr = 16
  295.             Regdata = 79
  296.             Miliamp(1) = 8
  297.          End If
  298.            Call Siout(regaddr , Regdata)
  299.          Waitms 100
  300.           Update = 1
  301.           Regaddr = 49
  302.  
  303.        End If
  304.  
  305.        If Temp1 = 2 Then
  306.  
  307.          If Klw = 1 Then
  308.             Regaddr = 17
  309.             Regdata = 108
  310.             Miliamp(2) = 2
  311.           Elseif Klw = 4 Then
  312.             Regdata = 109
  313.             Miliamp(2) = 4
  314.             Regaddr = 17
  315.           Elseif Klw = 6 Then
  316.             Regaddr = 17
  317.             Regdata = 110
  318.             Miliamp(2) = 6
  319.           Elseif Klw = 9 Then
  320.             Regaddr = 17
  321.             Regdata = 111
  322.             Miliamp(2) = 8
  323.          End If
  324.            Call Siout(regaddr , Regdata)
  325.             Waitms 100
  326.              Update = 1
  327.              Regaddr = 57
  328.        End If
  329.  
  330.        If Temp1 = 3 Then
  331.  
  332.          If Klw = 1 Then
  333.             Regaddr = 18
  334.             Regdata = 108
  335.             Miliamp(3) = 2
  336.           Elseif Klw = 4 Then
  337.              Regaddr = 18
  338.              Regdata = 109
  339.              Miliamp(3) = 4
  340.           Elseif Klw = 6 Then
  341.             Regaddr = 18
  342.             Regdata = 110
  343.             Miliamp(3) = 6
  344.           Elseif Klw = 9 Then
  345.             Regaddr = 18
  346.             Regdata = 111
  347.             Miliamp(3) = 8
  348.          End If
  349.             Call Siout(regaddr , Regdata)
  350.             Waitms 100
  351.             Update = 1
  352.             Regaddr = 65
  353.        End If
  354.  
  355.      End Sub
  356.  
  357.     '==============================================================================================
  358.               ' wybór wyjścia clk0 , clk1 , clk2
  359.     '==============================================================================================
  360.       Sub Wybor_clk
  361.  
  362.            Waitms 300
  363.            Incr Temp1
  364.         If Temp1 = 1 Then
  365.            Mem_hz(3) = Frequency                            'pamięć hz clk2
  366.            Frequency = Mem_hz(1)                            ' odczyt hz clk0
  367.            Siaddr1 = 26                                     'adres początkowy PLLA
  368.            Siaddr2 = 42                                     'adres początkowy CLK0
  369.            Update = 1
  370.           Elseif Temp1 = 2 Then
  371.            Mem_hz(1) = Frequency                            'pamięć hz clk0
  372.            Frequency = Mem_hz(2)                            ' odczyt hz clk1
  373.            Siaddr1 = 34                                     'adres początkowy PLLB
  374.            Siaddr2 = 50                                     'adres początkowy CLK1
  375.            Update = 1
  376.           Elseif Temp1 = 3 Then
  377.            Mem_hz(2) = Frequency                            'pamięć hz clk1
  378.            Frequency = Mem_hz(3)                            ' odczyt hz clk2
  379.            Siaddr1 = 34                                     'adres początkowy PLLB
  380.            Siaddr2 = 58                                     'adres początkowy CLK2
  381.            Update = 1
  382.  
  383.         End If
  384.  
  385.           If Temp1 > 3 Then
  386.              Temp1 = 0
  387.           End If
  388.  
  389.       End Sub
  390.  
  391.     '========================================================================
  392.  
  393.     '========================================================================
  394.     Sub Displaylcd
  395.           Hz_temp = Frequency                               '
  396.           Hz_temp = Hz_temp * Powiel                        '
  397.           Hz_temp = Hz_temp + Posrednia                     '
  398.          Tekst1 = "000000000"
  399.        Freqtxt = Str(frequency)                             ' (frequency)
  400.        Fcnt = Len(freqtxt)
  401.      If Fcnt = 1 Then
  402.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    ' 9
  403.            Elseif Fcnt = 2 Then
  404.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    ' 8
  405.            Elseif Fcnt = 3 Then
  406.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    ' 7
  407.            Elseif Fcnt = 4 Then
  408.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    ' 6
  409.            Elseif Fcnt = 5 Then
  410.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    ' 5
  411.            Elseif Fcnt = 6 Then
  412.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    ' 5
  413.            Elseif Fcnt = 7 Then
  414.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    ' 3
  415.            Elseif Fcnt = 8 Then
  416.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    ' 2
  417.            Elseif Fcnt = 9 Then
  418.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    ' 1
  419.      End If
  420.  
  421.           Locate 1 , 1
  422.            Lcd Mid(tekst1 , 1 , 3)
  423.            Lcd "."
  424.          Lcd Mid(tekst1 , 4 , 3)
  425.           Lcd "."
  426.          Lcd Mid(tekst1 , 7 , 3)
  427.           Lcd " Hz"
  428.           Locate 2 , 1                                      'second line
  429.      Select Case Stepsize
  430.        Case 1 : Lcd "5 Hz  "
  431.        Case 2 : Lcd "100 Hz"
  432.        Case 3 : Lcd "1 kHz "
  433.        Case 4 : Lcd "10 kHz"
  434.        Case 5 : Lcd "100kHz"
  435.        Case 6 : Lcd "1 MHz "
  436.        Case 7 : Lcd "10 MHz"
  437.      End Select
  438.  
  439.         Locate 2 , 9                                        'second line
  440.      Select Case Temp1
  441.        Case 1 : Lcd "CLK0"
  442.        Case 2 : Lcd "CLK1"
  443.        Case 3 : Lcd "CLK2"
  444.  
  445.  
  446.  
  447.      End Select
  448.        Freqtxt = Str(hz_temp)                               ' (frequency)
  449.        Fcnt = Len(freqtxt)
  450.      If Fcnt = 1 Then
  451.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    ' 9
  452.            Elseif Fcnt = 2 Then
  453.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    ' 8
  454.            Elseif Fcnt = 3 Then
  455.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    ' 7
  456.            Elseif Fcnt = 4 Then
  457.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    ' 6
  458.            Elseif Fcnt = 5 Then
  459.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    ' 5
  460.            Elseif Fcnt = 6 Then
  461.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    ' 5
  462.            Elseif Fcnt = 7 Then
  463.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    ' 3
  464.            Elseif Fcnt = 8 Then
  465.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    ' 2
  466.            Elseif Fcnt = 9 Then
  467.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    ' 1
  468.      End If
  469.  
  470.           Locate 3 , 1
  471.          Lcd Mid(tekst1 , 1 , 3)
  472.           Lcd "."
  473.          Lcd Mid(tekst1 , 4 , 3)
  474.            Lcd "."
  475.          Lcd Mid(tekst1 , 7 , 3)
  476.           Lcd " Hz"
  477.  
  478.  
  479.     End Sub
  480.  
  481.     '**********************************************************************
  482.     ' subroutine to initialise the si5351 chip via I2C
  483.     '**********************************************************************
  484.  
  485.     Sub Si5351init
  486.  
  487.         Regaddr = 183
  488.         Regdata = 192
  489.      Call Siout(regaddr , Regdata)                          'set xtal load cap to 10pF
  490.         Regaddr = 3
  491.         Regdata = 0
  492.      Call Siout(regaddr , Regdata)                          'enable all outputs
  493.         Regaddr = 15
  494.         Regdata = 0
  495.      Call Siout(regaddr , Regdata)                          'select xtal as PLL input source
  496.         Regaddr = 16
  497.         Regdata = 15                                        'PLLA is source, 8mA output
  498.      Call Siout(regaddr , Regdata)                          'configure clock 0 control register
  499.       Waitms 10                                             'wait 10ms just in case
  500.  
  501.     End Sub
  502.  
  503.     '********************************************************************************
  504.     ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  505.     '********************************************************************************
  506.     Sub Calculate
  507.  
  508.         Rdivider = 1                                        'initialise r
  509.         Outdivider = 900000000 \ Gfreq                      'and outdivider
  510.       While Outdivider > 900                                '900
  511.         Rdivider = 2 * Rdivider
  512.         Outdivider = Outdivider \ 2
  513.       Wend
  514.         Fvco = Outdivider Mod 2                             'check outdivider is an even number
  515.  
  516.       If Fvco <> 0 Then Outdivider = Outdivider - 1         'using fvco as a temporary register
  517.         Fvco = Outdivider * Rdivider
  518.         Fvco = Fvco * Gfreq                                 'determine PLL frequency
  519.      Select Case Rdivider                                   'determine value of R44 bits [6:4]
  520.         Case 1 : Rbyte = 0                                  '000 0000
  521.         Case 2 : Rbyte = 16                                 '001 0000
  522.         Case 4 : Rbyte = 32                                 '010 0000
  523.         Case 8 : Rbyte = 48                                 '011 0000
  524.         Case 16 : Rbyte = 64                                '100 0000
  525.         Case 32 : Rbyte = 80                                '101 0000
  526.         Case 64 : Rbyte = 96                                '110 0000
  527.         Case 128 : Rbyte = 112                              '111 0000
  528.      End Select
  529.        Afactor = Fvco \ Xtal
  530.        Fvalue = Afactor * Xtal                              'fvalue = fvco -afactor * xtal
  531.        Fvalue = Fvco - Fvalue                               'a+b/c
  532.        Fvalue = Fvalue * Cfactor
  533.        Fvalue = Fvalue \ Xtal
  534.        Bfactor = Fvalue
  535.        Ms0p1 = 128 * Outdivider
  536.        Ms0p1 = Ms0p1 - 512
  537.        Fvalue = 128 * Bfactor
  538.        Fvalue = Fvalue \ Cfactor
  539.        Finteger = Fvalue
  540.        Msnap1 = 128 * Afactor
  541.        Msnap1 = Msnap1 + Finteger                           'finteger used instead of fvalue for variable matching
  542.        Msnap1 = Msnap1 - 512
  543.        Msnap3 = Finteger * Cfactor                          'using msnap3 as temp result buffer
  544.        Msnap2 = 128 * Bfactor
  545.        Msnap2 = Msnap2 - Msnap3
  546.        Msnap3 = Cfactor
  547.      'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  548.     End Sub
  549.  
  550.     '**********************************************************************
  551.     ' send converted freq data to si5351 for CLK0 output
  552.     '**********************************************************************
  553.     Sub Sendfreq
  554.  
  555.           Regaddr = Siaddr1
  556.      Call Siout(regaddr , Ms32)                             'R26=msnap3[15:8]
  557.      Incr Regaddr
  558.      Call Siout(regaddr , Ms31)                             'R27=msnap3[7:0]
  559.      Incr Regaddr
  560.      Call Siout(regaddr , Ms13)                             'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  561.      Incr Regaddr
  562.      Call Siout(regaddr , Ms12)                             'R29=msnap1[15:8]
  563.      Incr Regaddr
  564.      Call Siout(regaddr , Ms11)                             'R30=msnap1[7:0]
  565.           Temp = Ms33                                       'temp[3:0]=msnap3[19:16]
  566.      Swap Temp                                              'temp[7:4]=msnap3[19:16]
  567.           Temp = Temp Or Ms23                               'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  568.      Incr Regaddr
  569.      Call Siout(regaddr , Temp)                             'R31=(msnap3[19:16],msnap2[19:16])
  570.      Incr Regaddr
  571.      Call Siout(regaddr , Ms22)                             'R32=msnap2[15:8]
  572.      Incr Regaddr
  573.      Call Siout(regaddr , Ms21)                             'R33=msnap2[7:0]
  574.  
  575.  
  576.           Regaddr = Siaddr2
  577.           Regdata = 0
  578.      Call Siout(regaddr , Regdata)                          'R42=MS0_P3[15:8]
  579.      Incr Regaddr
  580.           Regdata = 1
  581.      Call Siout(regaddr , Regdata)                          'R43=MS0_P3[7:0]
  582.           Temp = Rbyte
  583.           Temp = Temp Or M0p13
  584.      Incr Regaddr
  585.      Call Siout(regaddr , Temp)                             'R44=(0,R[7:4],MS0_P1[17:16])
  586.      Incr Regaddr
  587.      Call Siout(regaddr , M0p12)                            'R45=MS0_P1[15:8]
  588.      Incr Regaddr
  589.      Call Siout(regaddr , M0p11)                            'R46=MS0_P1[7:0]
  590.      Incr Regaddr
  591.           Regdata = 0
  592.      Call Siout(regaddr , Regdata)                          'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  593.      Incr Regaddr
  594.           Regdata = 0
  595.      Call Siout(regaddr , Regdata)                          'R48=MS0_P2[15:8]=0 always
  596.      Incr Regaddr
  597.           Regdata = 0
  598.      Call Siout(regaddr , Regdata)                          'R49=MS0_P2[7:0]=0 always
  599.  
  600.  
  601.     End Sub
  602.     '=================================================================================
  603.     '   obsluga klawiatury       wpisujemy czestotliwość w Hz   150000000
  604.     '      Użycie klawiszy Hz + , Hz - , step , wybor_clk wpisze do ciągu znakow " 0 "
  605.     '=================================================================================
  606.     Sub Zapis
  607.          Skok1:
  608.         Cursor On
  609.         Cursor Blink
  610.         Wartosc = Space(0)
  611.         Pozycja = 0
  612.         Locate 4 , 1 : Lcd "Nowa Hz "
  613.        Do
  614.  
  615.             Klw = Getkbd()
  616.  
  617.           If Pozycja = 10 Then
  618.                 Frequency = Val(wartosc)
  619.              If Frequency < 10000 Then
  620.                   Locate 4 , 1 : Lcd " MIN Hz 10.000 khz "
  621.                    Waitms 1000
  622.                   Locate 4 , 1 : Lcd "Nowa Hz             "
  623.                   Goto Skok1
  624.              End If
  625.              If Frequency > 150000000 Then
  626.                Locate 4 , 1 : Lcd " MAX Hz 150.000 Mhz "
  627.                 Waitms 1000
  628.                Locate 4 , 1 : Lcd "Nowa Hz             "
  629.                  Goto Skok1
  630.              End If
  631.               Update = 1
  632.                Cursor Off
  633.                  Cursor Noblink
  634.                   Locate 4 , 1 : Lcd "                    "
  635.                    Goto Skok
  636.           End If
  637.              Waitms 300
  638.           If Klw = 14 Then
  639.               Wartosc = Space(0)
  640.                Pozycja = 0
  641.           End If
  642.           If Klw <> 16 Then
  643.              Znak = Lookupstr(klw , Dta)
  644.                Insertchar Wartosc , Pozycja , Znak
  645.                  Locate 4 , 9 : Lcd Wartosc
  646.                   Pozycja = Pozycja + 1
  647.           End If
  648.  
  649.        Loop
  650.     End Sub
  651.  
  652.  
  653. Dta:
  654. Data "1" , "2" , "3" , "0" , "4" , "5" , "6" , "0" , "7" , "8" , "9" , "0" , "0" , "0" , "0" , "0"
  655.  
  656.  
  657.  
  658.     '**********************************************************************
  659.     ' i2c transmission to si5351
  660.     '**********************************************************************
  661.     Sub Siout(sireg As Byte , Sidata As Byte)
  662.      'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  663.      'Write a single byte (slave address 192, register sireg, value sibyte)
  664.      I2cstart
  665.      I2cwbyte 192                                           'i2c address of si5351a
  666.      Waitus 1                                               'suggested delay from forum
  667.      I2cwbyte Sireg
  668.      Waitus 1
  669.      I2cwbyte Sidata
  670.      Waitus 1
  671.      I2cstop
  672.  
  673.     End Sub
Pozdrawiam Henryk .
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 01 kwie 2023, 15:54

Hurrrra ! jupi :D pokonałem " dziada" :P

Śmiga generator od 10 kHz do 160 MHz .
IMG_20230401_154246.jpg
Tu kod poprawiony ;)
  1.    $regfile = "m8def.dat"
  2.     $crystal = 8000000                                      '8MHz internal RC clock
  3.  
  4.     $hwstack = 128
  5.     $swstack = 64
  6.     $framesize = 128
  7.  
  8.   '-------------------------------------------------------------------------------
  9.     Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
  10.     Config Lcd = 20 * 4
  11.  
  12.     Config Portb.1 = Output                                 'dds
  13.     Config Portb.2 = Output                                 'dds
  14.     Config Sda = Portb.1
  15.     Config Scl = Portb.2
  16.     Config Kbd = Portd                                      'klawiatura 4x4
  17.     Set Portb.1
  18.     Set Portb.2
  19.  
  20.         ' Declare Variables
  21.  
  22.     Dim Mhz As String * 2                                   'display subroutine variables
  23.     Dim Khz As String * 3
  24.     Dim Hz As String * 3
  25.     Dim Lastftext As String * 6                             'for display of freqb khz & Hz digits
  26.     Dim Freqtxt As String * 9
  27.     Dim Tekst1 As String * 9
  28.     Dim Mem_hz(3) As Dword                                  ' pamieć częstotliwości
  29.     Dim Miliamp(3) As Byte                                  ' pamięć prądu wyjściowego
  30.     Dim Fcnt As Byte
  31.     Dim Temp As Byte                                        'temporary variable used in sendfreq and sbarplot routines
  32.     Dim Temp1 As Byte                                       ' temp dla pamiec czestotliwosci
  33.     Dim Temp2 As Byte                                       ' temp dla wyboru pośredniej częstotliwości
  34.     Dim Temp3 As Byte
  35.     Dim Powiel As Byte                                      ' zmienna mnoznik powielacza
  36.     Dim Frequency As Dword                                  'four byte unsigned variable
  37.     Dim Hz_temp As Dword
  38.     Dim Gfreq As Dword                                      'calculates si5351 VFO output frequency
  39.     Dim Stepsize As Byte
  40.     Dim Delta As Dword
  41.     Dim Update As Bit                                       'bit is set (1) if a switch or encoder has changed
  42.     Dim Fvco As Dword                                       'si5351 vco frequency
  43.     Dim Outdivider As Dword                                 '4,6,8-900
  44.     Dim Rdivider As Byte                                    'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  45.     Dim Rbyte As Byte                                       'used as temp store before final data load to si5351
  46.     Dim Afactor As Dword
  47.     Dim Bfactor As Dword
  48.     Dim Fvalue As Single                                    'used to determine accuracy of fractional calculation
  49.     Dim Posrednia As Dword                                  'częstotliwość pośrednia
  50.     Dim Finteger As Dword
  51.     Dim Klw As Byte , Pozycja As Byte                       'klawiatura
  52.     Dim Znak As String * 1 , Wartosc As String * 9          ' klawiatura
  53.  
  54.  
  55.     Dim Ms0p1 As Dword                                      '18-bit MS0_P1 si5351 parameters for Output 0
  56.     Dim M0p11 As Byte At Ms0p1 Overlay                      'mirrored variables for dds calculation
  57.     Dim M0p12 As Byte At Ms0p1 + 1 Overlay
  58.     Dim M0p13 As Byte At Ms0p1 + 2 Overlay
  59.     Dim M0p14 As Byte At Ms0p1 + 3 Overlay                  'most significant byte for ms0p1
  60.  
  61.     'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  62.                                                           'si5351 parameters for PLLA
  63.     Dim Msnap1 As Dword                                     '18-bit variable for MSNA_P1
  64.     Dim Ms11 As Byte At Msnap1 Overlay                      'mirrored variables for dds calculation
  65.     Dim Ms12 As Byte At Msnap1 + 1 Overlay
  66.     Dim Ms13 As Byte At Msnap1 + 2 Overlay
  67.     Dim Ms14 As Byte At Msnap1 + 3 Overlay                  'most significant byte
  68.  
  69.     Dim Msnap2 As Dword                                     '20-bit variable for MSNA_P2
  70.     Dim Ms21 As Byte At Msnap2 Overlay                      'mirrored variables for dds calculation
  71.     Dim Ms22 As Byte At Msnap2 + 1 Overlay
  72.     Dim Ms23 As Byte At Msnap2 + 2 Overlay
  73.     Dim Ms24 As Byte At Msnap2 + 3 Overlay                  'most significant byte
  74.  
  75.     Dim Msnap3 As Dword                                     '20-bit variable for MSNA_P3
  76.     Dim Ms31 As Byte At Msnap3 Overlay                      'mirrored variables for dds calculation
  77.     Dim Ms32 As Byte At Msnap3 + 1 Overlay
  78.     Dim Ms33 As Byte At Msnap3 + 2 Overlay
  79.     Dim Ms34 As Byte At Msnap3 + 3 Overlay                  'most significant byte
  80.  
  81.     Dim Regaddr As Byte , Regdata As Byte                   'for i2c calls
  82.     Dim Siaddr1 As Byte , Siaddr2 As Byte                   'for writing to si5351 CLK0 and CLK1
  83.  
  84.         '    Declare Constants
  85.     Const Startfreq = 10000                                 'xxx                          '40m starting frequency
  86.     Const Xtal = 25001400                                   ' xxx 25000000   '**NOTE: Value may be adjusted during alignment ***
  87.     Const Cfactor = 1048575                                 'xxx 1048575
  88.  
  89.  
  90.  
  91.     Powiel = 1
  92.     Temp1 = 0
  93.     Temp2 = 1
  94.     Temp3 = 0
  95.     Posrednia = 0
  96.     Frequency = Startfreq                                   'initialise frequency (20m for now)
  97.     Stepsize = 3
  98.     Delta = 1000
  99.  
  100.     Mem_hz(1) = 30000                                       ' Częstotliwości startowe pamięci
  101.     Mem_hz(2) = 20000
  102.     Mem_hz(3) = 10000
  103.     Miliamp(1) = 8
  104.     Miliamp(2) = 8
  105.     Miliamp(3) = 8
  106.  
  107.     '     Declare Subroutines
  108.     Declare Sub Si5351init                                  'initialises si5351
  109.     Declare Sub Displaylcd                                  'displays current oscillator frequency
  110.     Declare Sub Calculate                                   'converts current VFO or BFO freq to data for si5351
  111.     Declare Sub Sendfreq                                    'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  112.     Declare Sub Siout(sireg As Byte , Sidata As Byte)       'for i2c write to si5351
  113.     Declare Sub Wybor_clk
  114.     Declare Sub Zapis
  115.     Declare Sub Ma_out
  116.  
  117.     '***************************** Program *****************************************
  118.  
  119.     '      initialise i2c here...
  120.     I2cinit
  121.     Waitms 50                                               'for i2c to settle and for lcd RC reset time
  122.     Cursor Off                                              'LCD cursor of
  123.     Cls
  124.     Update = 0                                              'clear the flags
  125.  
  126.     Si5351init                                              'initialises si5351
  127.     Gfreq = Frequency
  128.      Calculate
  129.     Siaddr1 = 26
  130.     Siaddr2 = 42
  131.      Sendfreq
  132.     Regaddr = 16
  133.     Regdata = 79
  134.      Call Siout(regaddr , Regdata)
  135.     Siaddr1 = 34
  136.     Siaddr2 = 50
  137.      Sendfreq
  138.     Siaddr1 = 34
  139.     Siaddr2 = 58
  140.      Sendfreq
  141.     Regaddr = 17
  142.     Regdata = 111
  143.       Call Siout(regaddr , Regdata)
  144.     Regaddr = 18
  145.     Regdata = 111
  146.       Call Siout(regaddr , Regdata)
  147.      Wybor_clk
  148.      Displaylcd                                             'then display frequency and status on lcd
  149.  
  150.  
  151.     Do                                                      'Start of main program
  152.       Skok:
  153.        If Temp1 = 0 Then
  154.           Locate 2 , 15 : Lcd "mA " ; Miliamp(3)
  155.          Elseif Temp1 > 0 Then
  156.           Locate 2 , 15 : Lcd "mA " ; Miliamp(temp1)
  157.        End If
  158.       Locate 4 , 1 : Lcd "Pcz " ; Posrednia
  159.       Locate 3 , 15 : Lcd " x " ; Powiel
  160.        If Klw < 15 Then : Ma_out : End If
  161.      If Klw = 11 Then
  162.           Incr Stepsize
  163.           Waitms 200                                        ' xxx
  164.        If Stepsize = 8 Then                                 'xxx
  165.           Stepsize = 1
  166.        End If
  167.        If Stepsize = 1 Then Delta = 5                       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  168.        If Stepsize = 2 Then Delta = 100                     '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  169.        If Stepsize = 3 Then Delta = 1000
  170.        If Stepsize = 4 Then Delta = 10000
  171.        If Stepsize = 5 Then Delta = 100000                  'xxx
  172.        If Stepsize = 6 Then Delta = 1000000                 ' xxx
  173.        If Stepsize = 7 Then Delta = 10000000                ' xxx
  174.         Update = 1
  175.          Displaylcd                                         'to flag this change
  176.      End If
  177.       If Klw = 3 Then                                       ' Hz +
  178.           Frequency = Frequency + Delta
  179.            If Frequency > 160000000 Then
  180.               Frequency = 160000000
  181.  
  182.            End If
  183.            Update = 1
  184.           Displaylcd
  185.  
  186.       End If
  187.  
  188.       If Klw = 7 Then                                       ' Hz -
  189.         Frequency = Frequency - Delta
  190.  
  191.          If Frequency > 160000000 Then
  192.             Frequency = 10000
  193.          End If
  194.          If Frequency < 10000 Then
  195.              Frequency = 10000
  196.          End If
  197.            Update = 1
  198.           Displaylcd
  199.  
  200.       End If
  201.  
  202.        '=============================================================================
  203.        ' wybór częstotliwości pośredniej
  204.        '=============================================================================
  205.        If Klw = 14 Then
  206.              Incr Temp2
  207.             Waitms 300
  208.           If Temp2 = 1 Then
  209.             Posrednia = 0
  210.             Elseif Temp2 = 2 Then
  211.              Posrednia = 10700000
  212.             Elseif Temp2 = 3 Then
  213.              Posrednia = 21400000
  214.             Elseif Temp2 = 4 Then
  215.              Posrednia = 45000000
  216.             Elseif Temp2 > 4 Then
  217.              Posrednia = 0
  218.              Temp2 = 0
  219.              Locate 4 , 5 : Lcd Posrednia ; "        "
  220.  
  221.           End If
  222.           Displaylcd
  223.        End If
  224.      '======================================================================
  225.               ' mnoznik powielacza
  226.      '================================================================
  227.         If Klw = 0 Then
  228.              Incr Temp3
  229.             Waitms 300
  230.           If Temp3 = 1 Then
  231.             Powiel = 1
  232.             Elseif Temp3 = 2 Then
  233.              Powiel = 2
  234.             Elseif Temp3 = 3 Then
  235.              Powiel = 3
  236.             Elseif Temp3 = 4 Then
  237.              Powiel = 4
  238.             Elseif Temp3 > 4 Then
  239.              Powiel = 1
  240.              Temp3 = 0
  241.  
  242.           End If
  243.             Displaylcd
  244.         End If
  245.  
  246.         If Klw = 15 Then : Wybor_clk : End If               ' Wybor_clk
  247.  
  248.      If Update = 1 Then                                     'encoder or buttons changed so update display and si5351
  249.                                                             'show new frequency and status
  250.        Gfreq = Frequency
  251.          Displaylcd                                         'gfreq holds value used for si5351
  252.          Calculate                                          'calculate new VFO data
  253.          Sendfreq                                           'and send it to the si5351
  254.          Call Siout(regaddr , Regdata)                      'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  255.          Update = 0
  256.                                                             'and update flag
  257.      End If
  258.  
  259.       Waitms 100
  260.        Klw = Getkbd()
  261.        If Klw = 12 Then                                     '   Przejście do Sub zapis nowej Hz
  262.          Locate 4 , 1 : Lcd "                    "
  263.            Zapis
  264.        End If
  265.  
  266.     Loop                                                    'End of main program
  267.    End
  268.  
  269.     '**********************************************************************
  270.     'Subroutines...
  271.     '=====================================================================
  272.  
  273.  
  274.     '===============================================================================
  275.       ' blok ustawień prądu wyjściowego clk0 , clk1 , clk2
  276.       '================================================================================
  277.      Sub Ma_out
  278.  
  279.        If Temp1 = 1 Then
  280.  
  281.          If Klw = 1 Then
  282.             Regaddr = 16
  283.             Regdata = 76
  284.             Miliamp(1) = 2
  285.           Elseif Klw = 4 Then
  286.             Regaddr = 16
  287.             Regdata = 77
  288.             Miliamp(1) = 4
  289.           Elseif Klw = 6 Then
  290.             Regaddr = 16
  291.             Regdata = 78
  292.             Miliamp(1) = 6
  293.           Elseif Klw = 9 Then
  294.             Regaddr = 16
  295.             Regdata = 79
  296.             Miliamp(1) = 8
  297.          End If
  298.            Call Siout(regaddr , Regdata)
  299.          Waitms 100
  300.           Update = 1
  301.           Regaddr = 49
  302.  
  303.        End If
  304.  
  305.        If Temp1 = 2 Then
  306.  
  307.          If Klw = 1 Then
  308.             Regaddr = 17
  309.             Regdata = 108
  310.             Miliamp(2) = 2
  311.           Elseif Klw = 4 Then
  312.             Regdata = 109
  313.             Miliamp(2) = 4
  314.             Regaddr = 17
  315.           Elseif Klw = 6 Then
  316.             Regaddr = 17
  317.             Regdata = 110
  318.             Miliamp(2) = 6
  319.           Elseif Klw = 9 Then
  320.             Regaddr = 17
  321.             Regdata = 111
  322.             Miliamp(2) = 8
  323.          End If
  324.            Call Siout(regaddr , Regdata)
  325.             Waitms 100
  326.              Update = 1
  327.              Regaddr = 57
  328.        End If
  329.  
  330.        If Temp1 = 3 Then
  331.  
  332.          If Klw = 1 Then
  333.             Regaddr = 18
  334.             Regdata = 108
  335.             Miliamp(3) = 2
  336.           Elseif Klw = 4 Then
  337.              Regaddr = 18
  338.              Regdata = 109
  339.              Miliamp(3) = 4
  340.           Elseif Klw = 6 Then
  341.             Regaddr = 18
  342.             Regdata = 110
  343.             Miliamp(3) = 6
  344.           Elseif Klw = 9 Then
  345.             Regaddr = 18
  346.             Regdata = 111
  347.             Miliamp(3) = 8
  348.          End If
  349.             Call Siout(regaddr , Regdata)
  350.             Waitms 100
  351.             Update = 1
  352.             Regaddr = 65
  353.        End If
  354.  
  355.      End Sub
  356.  
  357.     '==============================================================================================
  358.               ' wybór wyjścia clk0 , clk1 , clk2
  359.     '==============================================================================================
  360.       Sub Wybor_clk
  361.  
  362.            Waitms 300
  363.            Incr Temp1
  364.         If Temp1 = 1 Then
  365.            Mem_hz(3) = Frequency                            'pamięć hz clk2
  366.            Frequency = Mem_hz(1)                            ' odczyt hz clk0
  367.            Siaddr1 = 26                                     'adres początkowy PLLA
  368.            Siaddr2 = 42                                     'adres początkowy CLK0
  369.            Update = 1
  370.           Elseif Temp1 = 2 Then
  371.            Mem_hz(1) = Frequency                            'pamięć hz clk0
  372.            Frequency = Mem_hz(2)                            ' odczyt hz clk1
  373.            Siaddr1 = 34                                     'adres początkowy PLLB
  374.            Siaddr2 = 50                                     'adres początkowy CLK1
  375.            Update = 1
  376.           Elseif Temp1 = 3 Then
  377.            Mem_hz(2) = Frequency                            'pamięć hz clk1
  378.            Frequency = Mem_hz(3)                            ' odczyt hz clk2
  379.            Siaddr1 = 34                                     'adres początkowy PLLB
  380.            Siaddr2 = 58                                     'adres początkowy CLK2
  381.            Update = 1
  382.  
  383.         End If
  384.  
  385.           If Temp1 > 3 Then
  386.              Temp1 = 0
  387.           End If
  388.  
  389.       End Sub
  390.  
  391.     '========================================================================
  392.  
  393.     '========================================================================
  394.     Sub Displaylcd
  395.           Hz_temp = Frequency                               '
  396.           Hz_temp = Hz_temp * Powiel                        '
  397.           Hz_temp = Hz_temp + Posrednia                     '
  398.          Tekst1 = "000000000"
  399.        Freqtxt = Str(frequency)                             ' (frequency)
  400.        Fcnt = Len(freqtxt)
  401.      If Fcnt = 1 Then
  402.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    ' 9
  403.            Elseif Fcnt = 2 Then
  404.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    ' 8
  405.            Elseif Fcnt = 3 Then
  406.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    ' 7
  407.            Elseif Fcnt = 4 Then
  408.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    ' 6
  409.            Elseif Fcnt = 5 Then
  410.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    ' 5
  411.            Elseif Fcnt = 6 Then
  412.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    ' 5
  413.            Elseif Fcnt = 7 Then
  414.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    ' 3
  415.            Elseif Fcnt = 8 Then
  416.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    ' 2
  417.            Elseif Fcnt = 9 Then
  418.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    ' 1
  419.      End If
  420.  
  421.           Locate 1 , 1
  422.            Lcd Mid(tekst1 , 1 , 3)
  423.            Lcd "."
  424.          Lcd Mid(tekst1 , 4 , 3)
  425.           Lcd "."
  426.          Lcd Mid(tekst1 , 7 , 3)
  427.           Lcd " Hz"
  428.           Locate 2 , 1                                      'second line
  429.      Select Case Stepsize
  430.        Case 1 : Lcd "5 Hz  "
  431.        Case 2 : Lcd "100 Hz"
  432.        Case 3 : Lcd "1 kHz "
  433.        Case 4 : Lcd "10 kHz"
  434.        Case 5 : Lcd "100kHz"
  435.        Case 6 : Lcd "1 MHz "
  436.        Case 7 : Lcd "10 MHz"
  437.      End Select
  438.  
  439.         Locate 2 , 9                                        'second line
  440.      Select Case Temp1
  441.        Case 1 : Lcd "CLK0"
  442.        Case 2 : Lcd "CLK1"
  443.        Case 3 : Lcd "CLK2"
  444.  
  445.  
  446.  
  447.      End Select
  448.        Freqtxt = Str(hz_temp)                               ' (frequency)
  449.        Fcnt = Len(freqtxt)
  450.      If Fcnt = 1 Then
  451.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    ' 9
  452.            Elseif Fcnt = 2 Then
  453.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    ' 8
  454.            Elseif Fcnt = 3 Then
  455.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    ' 7
  456.            Elseif Fcnt = 4 Then
  457.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    ' 6
  458.            Elseif Fcnt = 5 Then
  459.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    ' 5
  460.            Elseif Fcnt = 6 Then
  461.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    ' 5
  462.            Elseif Fcnt = 7 Then
  463.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    ' 3
  464.            Elseif Fcnt = 8 Then
  465.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    ' 2
  466.            Elseif Fcnt = 9 Then
  467.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    ' 1
  468.      End If
  469.  
  470.           Locate 3 , 1
  471.          Lcd Mid(tekst1 , 1 , 3)
  472.           Lcd "."
  473.          Lcd Mid(tekst1 , 4 , 3)
  474.            Lcd "."
  475.          Lcd Mid(tekst1 , 7 , 3)
  476.           Lcd " Hz"
  477.  
  478.  
  479.     End Sub
  480.  
  481.     '**********************************************************************
  482.     ' subroutine to initialise the si5351 chip via I2C
  483.     '**********************************************************************
  484.  
  485.     Sub Si5351init
  486.  
  487.         Regaddr = 183
  488.         Regdata = 192
  489.      Call Siout(regaddr , Regdata)                          'set xtal load cap to 10pF
  490.         Regaddr = 3
  491.         Regdata = 0
  492.      Call Siout(regaddr , Regdata)                          'enable all outputs
  493.         Regaddr = 15
  494.         Regdata = 0
  495.      Call Siout(regaddr , Regdata)                          'select xtal as PLL input source
  496.         Regaddr = 16
  497.         Regdata = 15                                        'PLLA is source, 8mA output
  498.      Call Siout(regaddr , Regdata)                          'configure clock 0 control register
  499.       Waitms 10                                             'wait 10ms just in case
  500.  
  501.     End Sub
  502.  
  503.     '********************************************************************************
  504.     ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  505.     '********************************************************************************
  506.     Sub Calculate
  507.  
  508.         Rdivider = 1                                        'initialise r
  509.         Outdivider = 1000000000 \ Gfreq                      'and outdivider
  510.       While Outdivider > 1000                                '900
  511.         Rdivider = 2 * Rdivider
  512.         Outdivider = Outdivider \ 2
  513.       Wend
  514.         Fvco = Outdivider Mod 2                             'check outdivider is an even number
  515.  
  516.       If Fvco <> 0 Then Outdivider = Outdivider - 1         'using fvco as a temporary register
  517.         Fvco = Outdivider * Rdivider
  518.         Fvco = Fvco * Gfreq                                 'determine PLL frequency
  519.      Select Case Rdivider                                   'determine value of R44 bits [6:4]
  520.         Case 1 : Rbyte = 0                                  '000 0000
  521.         Case 2 : Rbyte = 16                                 '001 0000
  522.         Case 4 : Rbyte = 32                                 '010 0000
  523.         Case 8 : Rbyte = 48                                 '011 0000
  524.         Case 16 : Rbyte = 64                                '100 0000
  525.         Case 32 : Rbyte = 80                                '101 0000
  526.         Case 64 : Rbyte = 96                                '110 0000
  527.         Case 128 : Rbyte = 112                              '111 0000
  528.      End Select
  529.        Afactor = Fvco \ Xtal
  530.        Fvalue = Afactor * Xtal                              'fvalue = fvco -afactor * xtal
  531.        Fvalue = Fvco - Fvalue                               'a+b/c
  532.        Fvalue = Fvalue * Cfactor
  533.        Fvalue = Fvalue \ Xtal
  534.        Bfactor = Fvalue
  535.        Ms0p1 = 128 * Outdivider
  536.        Ms0p1 = Ms0p1 - 512
  537.        Fvalue = 128 * Bfactor
  538.        Fvalue = Fvalue \ Cfactor
  539.        Finteger = Fvalue
  540.        Msnap1 = 128 * Afactor
  541.        Msnap1 = Msnap1 + Finteger                           'finteger used instead of fvalue for variable matching
  542.        Msnap1 = Msnap1 - 512
  543.        Msnap3 = Finteger * Cfactor                          'using msnap3 as temp result buffer
  544.        Msnap2 = 128 * Bfactor
  545.        Msnap2 = Msnap2 - Msnap3
  546.        Msnap3 = Cfactor
  547.      'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  548.     End Sub
  549.  
  550.     '**********************************************************************
  551.     ' send converted freq data to si5351 for CLK0 output
  552.     '**********************************************************************
  553.     Sub Sendfreq
  554.  
  555.           Regaddr = Siaddr1
  556.      Call Siout(regaddr , Ms32)                             'R26=msnap3[15:8]
  557.      Incr Regaddr
  558.      Call Siout(regaddr , Ms31)                             'R27=msnap3[7:0]
  559.      Incr Regaddr
  560.      Call Siout(regaddr , Ms13)                             'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  561.      Incr Regaddr
  562.      Call Siout(regaddr , Ms12)                             'R29=msnap1[15:8]
  563.      Incr Regaddr
  564.      Call Siout(regaddr , Ms11)                             'R30=msnap1[7:0]
  565.           Temp = Ms33                                       'temp[3:0]=msnap3[19:16]
  566.      Swap Temp                                              'temp[7:4]=msnap3[19:16]
  567.           Temp = Temp Or Ms23                               'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  568.      Incr Regaddr
  569.      Call Siout(regaddr , Temp)                             'R31=(msnap3[19:16],msnap2[19:16])
  570.      Incr Regaddr
  571.      Call Siout(regaddr , Ms22)                             'R32=msnap2[15:8]
  572.      Incr Regaddr
  573.      Call Siout(regaddr , Ms21)                             'R33=msnap2[7:0]
  574.  
  575.  
  576.           Regaddr = Siaddr2
  577.           Regdata = 0
  578.      Call Siout(regaddr , Regdata)                          'R42=MS0_P3[15:8]
  579.      Incr Regaddr
  580.           Regdata = 1
  581.      Call Siout(regaddr , Regdata)                          'R43=MS0_P3[7:0]
  582.           Temp = Rbyte
  583.           Temp = Temp Or M0p13
  584.      Incr Regaddr
  585.      Call Siout(regaddr , Temp)                             'R44=(0,R[7:4],MS0_P1[17:16])
  586.      Incr Regaddr
  587.      Call Siout(regaddr , M0p12)                            'R45=MS0_P1[15:8]
  588.      Incr Regaddr
  589.      Call Siout(regaddr , M0p11)                            'R46=MS0_P1[7:0]
  590.      Incr Regaddr
  591.           Regdata = 0
  592.      Call Siout(regaddr , Regdata)                          'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  593.      Incr Regaddr
  594.           Regdata = 0
  595.      Call Siout(regaddr , Regdata)                          'R48=MS0_P2[15:8]=0 always
  596.      Incr Regaddr
  597.           Regdata = 0
  598.      Call Siout(regaddr , Regdata)                          'R49=MS0_P2[7:0]=0 always
  599.  
  600.  
  601.     End Sub
  602.     '=================================================================================
  603.     '   obsluga klawiatury       wpisujemy czestotliwość w Hz   150000000
  604.     '      Użycie klawiszy Hz + , Hz - , step , wybor_clk wpisze do ciągu znakow " 0 "
  605.     '=================================================================================
  606.     Sub Zapis
  607.          Skok1:
  608.         Cursor On
  609.         Cursor Blink
  610.         Wartosc = Space(0)
  611.         Pozycja = 0
  612.         Locate 4 , 1 : Lcd "Nowa Hz "
  613.        Do
  614.  
  615.             Klw = Getkbd()
  616.  
  617.           If Pozycja = 10 Then
  618.                 Frequency = Val(wartosc)
  619.              If Frequency < 1000 Then
  620.                   Locate 4 , 1 : Lcd " MIN Hz 10.000 khz "
  621.                    Waitms 1000
  622.                   Locate 4 , 1 : Lcd "Nowa Hz             "
  623.                   Goto Skok1
  624.              End If
  625.              If Frequency > 155000000 Then
  626.                Locate 4 , 1 : Lcd " MAX Hz 160.000 Mhz "
  627.                 Waitms 1000
  628.                Locate 4 , 1 : Lcd "Nowa Hz             "
  629.                  Goto Skok1
  630.              End If
  631.               Update = 1
  632.                Cursor Off
  633.                  Cursor Noblink
  634.                   Locate 4 , 1 : Lcd "                    "
  635.                    Goto Skok
  636.           End If
  637.              Waitms 300
  638.           If Klw = 14 Then
  639.               Wartosc = Space(0)
  640.                Pozycja = 0
  641.           End If
  642.           If Klw <> 16 Then
  643.              Znak = Lookupstr(klw , Dta)
  644.                Insertchar Wartosc , Pozycja , Znak
  645.                  Locate 4 , 9 : Lcd Wartosc
  646.                   Pozycja = Pozycja + 1
  647.           End If
  648.  
  649.        Loop
  650.     End Sub
  651.  
  652.  
  653. Dta:
  654. Data "1" , "2" , "3" , "0" , "4" , "5" , "6" , "0" , "7" , "8" , "9" , "0" , "0" , "0" , "0" , "0"
  655.  
  656.  
  657.  
  658.     '**********************************************************************
  659.     ' i2c transmission to si5351
  660.     '**********************************************************************
  661.     Sub Siout(sireg As Byte , Sidata As Byte)
  662.      'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  663.      'Write a single byte (slave address 192, register sireg, value sibyte)
  664.      I2cstart
  665.      I2cwbyte 192                                           'i2c address of si5351a
  666.      Waitus 1                                               'suggested delay from forum
  667.      I2cwbyte Sireg
  668.      Waitus 1
  669.      I2cwbyte Sidata
  670.      Waitus 1
  671.      I2cstop
  672.  
  673.     End Sub
Nie będzie mną rządził jakiś zakichany generatorek .

Miłej zabawy , Henryk :D
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Generator Si5351

Post autor: Jacek » 02 kwie 2023, 9:41

gratulacje Pan Henryk.
pozdrawiam Jacek.
ODPOWIEDZ