Generator Si5351

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

Generator Si5351

Post autor: Henryk » 05 mar 2023, 11:53

Witam .
Już nie pamiętam jak długo walczę z tym ustrojstwem ;) ilość rejestrów do ustawienia troszkę mnie przerosła i musiałem szukać pomocy w sieci .
Znalazłem program napisany pod procka Tiny85 a że takiego na składzie nie mam zacząłem go adoptować dla Atmegi8 .
poniżej kod oryginalny bez mojego dłubania .
  1. '------------------------------------------------------------------
  2. ' si5351a DDS Oscillator with I2C LCD display
  3. ' Author: Andrew Woodfield ZL2PD
  4. ' Date: March 2016
  5. ' File Name: si85vfoxx.bas     (where xx is version number)
  6. '
  7. ' Released under the terms and conditions of the
  8. ' Creative Commons Public License ("CCPL")
  9. ' See creativecommons.org for details
  10. '
  11. ' Commercial use is prohibited without written permission
  12. ' from the author
  13. '
  14. '------------------------------------------------------------------
  15. ' Adapted from boardtest11.bas:
  16. '
  17. ' V01: initial code
  18. '
  19. '------------------------------------------------------------------
  20. ' Credits:
  21. '
  22. ' I2C LCD code adapted from www.ne.jp/asahi/shared/o-family/ElecRoom/ElecMAIN.htm
  23. ' si5351 code is adapted from OE1CGS and Jason Milldrum C code
  24. '
  25. ' Rotary encoder software is adapted from:
  26. ' http://dl6gl.de/software/drehencoder-mit-bascom
  27. '
  28. '------------------------------------------------------------------
  29. ' Program Description:
  30.  
  31. ' An ATtiny85 is used to control a Silicon Labs si5351a 3-output
  32. ' PLL/divider oscillator and I2C 16x2 alphanumeric LCD display with
  33. ' rotary encoder and some pushbuttons.
  34. '
  35. '------------------------------------------------------------------
  36. ' Fuse settings
  37. '
  38. ' LOCK Byte: 0ffh (No locks)
  39. ' EXTd Byte: 0ffh (BOD disabled)
  40. '
  41. ' HIGH Byte: 05fh
  42. '   RSTDISBL 0 DISABLED
  43. '       DWEN 1 DW not enabled
  44. '      SPIEN 0 SPI programming enabled
  45. '      WDTON 1 Watchdog timer off
  46. '     EESAVE 1 EEPROM not preserved in erase
  47. '  BODLEVEL2 1 Boot ROM size
  48. '  BODLEVEL1 1
  49. '  BODLEVEL0 1 No boot vector at startup
  50. '
  51. ' LOW Byte:  0e2h
  52. '     CKDIV8 1 NOT divided by 8
  53. '      CKOUT 1 Not enabled
  54. '       SUT1 1 Slow rising power
  55. '       SUT0 0
  56. '     CKSEL3 0 8 MHz internal RC clock
  57. '     CKSEL2 0
  58. '     CKSEL1 1
  59. '     CKSEL0 0
  60. '
  61. '------------------------------------------------------------------
  62. ' Compiler Directives (some fundamental hardware issues)
  63.  
  64. $regfile = "attiny85.dat"
  65. $crystal = 8000000            '8MHz internal RC clock
  66.  
  67. $hwstack = 128
  68. $swstack = 64
  69. $framesize = 128
  70.  
  71. '-------------------------------------------------------------------------------
  72. ' Declare Variables
  73.  
  74. Dim MHz As String * 2         'display subroutine variables
  75. Dim kHz as string * 3
  76. Dim Hz as string * 3
  77. dim lastftext as string * 6   'for display of freqb khz & Hz digits
  78. dim freqtxt as string * 8
  79. dim fcnt as Byte
  80.  
  81. dim temp as byte              'temporary variable used in sendfreq and sbarplot routines
  82.  
  83.  
  84. Dim Frequency As Dword        'four byte unsigned variable
  85. dim gfreq as dword            'calculates si5351 VFO output frequency
  86.  
  87. Dim Stepsize As Byte
  88.  
  89. Dim spin As Byte              'Encoder rotation (encoder incr = 2, decr = 1, no change = 0)
  90. Dim Delta As Dword
  91.  
  92. Dim Encval As Byte            'current rotary encoder value
  93. Dim Lastencoder As Byte       'previous rotary encoder value
  94.  
  95. Dim Update As Bit             'bit is set (1) if a switch or encoder has changed
  96. dim upwards as bit            'direction of band change
  97.  
  98. dim bandup as bit , banddown as bit , modekey as bit       'key flags (0=pressed and 1=not pressed)
  99.  
  100. Dim Vadc As Word              'for adc read routine
  101. Dim Vadcl As Byte At Vadc Overlay
  102. Dim Vadch As Byte At Vadc + 1 Overlay
  103.  
  104. dim bandpointer as byte       'identifies currently selected amateur band
  105.  
  106. dim modetype as byte          'holds mode (1=LSB, 2=USB, 3=CW)
  107. dim ptt as bit                'set by adc routine
  108.  
  109. dim fvco as dword             'si5351 vco frequency
  110. dim outdivider as dword       '4,6,8-900
  111. dim rdivider as byte          'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  112. dim rbyte as byte             'used as temp store before final data load to si5351
  113. dim afactor as dword
  114. dim bfactor as Dword
  115. dim fvalue as single          'used to determine accuracy of fractional calculation
  116. dim finteger as Dword
  117.  
  118. dim ms0p1 as Dword            '18-bit MS0_P1 si5351 parameters for Output 0
  119. dim m0p11 as byte at ms0p1 overlay       'mirrored variables for dds calculation
  120. dim m0p12 as byte at ms0p1 + 1 overlay
  121. dim m0p13 as byte at ms0p1 + 2 overlay
  122. dim m0p14 as byte at ms0p1 + 3 overlay       'most significant byte for ms0p1
  123.  
  124. 'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  125.  
  126.                                                               'si5351 parameters for PLLA
  127. dim msnap1 as Dword           '18-bit variable for MSNA_P1
  128. dim ms11 as byte at msnap1 overlay       'mirrored variables for dds calculation
  129. dim ms12 as byte at msnap1 + 1 overlay
  130. dim ms13 as byte at msnap1 + 2 overlay
  131. dim ms14 as byte at msnap1 + 3 overlay       'most significant byte
  132.  
  133. dim msnap2 as Dword           '20-bit variable for MSNA_P2
  134. dim ms21 as byte at msnap2 overlay       'mirrored variables for dds calculation
  135. dim ms22 as byte at msnap2 + 1 overlay
  136. dim ms23 as byte at msnap2 + 2 overlay
  137. dim ms24 as byte at msnap2 + 3 overlay       'most significant byte
  138.  
  139. dim msnap3 as Dword           '20-bit variable for MSNA_P3
  140. dim ms31 as byte at msnap3 overlay       'mirrored variables for dds calculation
  141. dim ms32 as byte at msnap3 + 1 overlay
  142. dim ms33 as byte at msnap3 + 2 overlay
  143. dim ms34 as byte at msnap3 + 3 overlay       'most significant byte
  144.  
  145. dim regaddr as byte , regdata as byte       'for i2c calls
  146. dim siaddr1 as byte , siaddr2 as byte , siaddr3 as byte       'for writing to si5351 CLK0 and CLK1
  147.  
  148.  
  149. ' Declare Constants
  150. const startfreq = 7100000     '40m starting frequency
  151. const xtal = 25002900         '**NOTE: Value may be adjusted during alignment ***
  152. const cfactor = 1048575
  153. const ifoffset = 8867000      'ifoffset=0 if no offset e.g. VFO used in SDR or DC receiver
  154. const bfofreq = 8870000       'bfo/cio frequencies but not currently supported in this version
  155.  
  156. Const Midas_vdd = 3           'LCD display is powered from 3V rail
  157.  
  158.  
  159. ' Declare Subroutines
  160. declare sub si5351init        'initialises si5351
  161. Declare Sub Displaylcd        'displays current oscillator frequency
  162. Declare Sub Calculate         'converts current VFO or BFO freq to data for si5351
  163. Declare Sub Sendfreq          'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  164. declare sub siout(sireg as byte , sidata as byte)       'for i2c write to si5351
  165. declare sub barplot           'plots current s-meter input voltage
  166.  
  167. '------------------------------------------------------------------------------------
  168. ' Hardware Setup
  169. '
  170. ' See schematic for details
  171. '
  172. ' Hardware Aliases:
  173.  
  174. StepKey alias pinb.0          'step key on encoder
  175. EncA alias pinb.3             'rotary encoder input A
  176. EncB alias pinb.4             'rotary encoder input B
  177.  
  178.  
  179. ' Initialise I/O (LCD already done above)
  180. config portb = OUTPUT         'used for filter selection and i2c
  181.  
  182. config sda = PORTb.1
  183. config scl = PORTb.2
  184.  
  185. Config Pinb.0 = Input
  186. config PinB.3 = input
  187. config PinB.4 = input
  188. config pinb.5 = input         'adc
  189.  
  190. set portb.0                   'set pullups
  191. set portb.3
  192. set portb.4
  193.  
  194.  
  195. '***************************** Program *****************************************
  196.  
  197. 'initialise adc
  198. config adc = single , prescaler = auto , reference = avcc       'starts automatically
  199. admux = &b00100000            'left adjust result
  200.  
  201.  
  202. 'initialise i2c here...
  203. i2cinit
  204. waitms 50                     'for i2c to settle and for lcd RC reset time
  205.  
  206. Config Lcd = 16 * 2           'LCD has standard 2 x 16 display
  207. $lib "Lcd_Midas.lib"          'LCD library for serial LCD
  208. Initlcd                       'so now initialise the LCD
  209. Cursor Off                    'LCD cursor off
  210.  
  211. 'brief splash message to the LCD...
  212.  
  213. Locate 1 , 1                  'Show program version
  214. Lcd "ZL2PD Tiny85 VFO"
  215. Locate 2 , 1
  216. Lcd "Version 1.0 2016"
  217.  
  218. Wait 2
  219.  
  220. Deflcdchar 1 , 32 , 32 , 16 , 16 , 16 , 16 , 32 , 32       'define the bargraph characters
  221. Deflcdchar 2 , 32 , 32 , 24 , 24 , 24 , 24 , 32 , 32
  222. Deflcdchar 3 , 32 , 32 , 28 , 28 , 28 , 28 , 32 , 32
  223. Deflcdchar 4 , 32 , 32 , 30 , 30 , 30 , 30 , 32 , 32
  224. Deflcdchar 5 , 32 , 32 , 31 , 31 , 31 , 31 , 32 , 32
  225.  
  226. Cls
  227.  
  228.  
  229. 'initialise some variables
  230. Frequency = startfreq         'initialise frequency (20m for now)
  231. stepsize = 1
  232. delta = 5
  233. spin = 0
  234.  
  235. reset update                  'clear the flags
  236.  
  237. si5351init                    'initialises si5351
  238.  
  239. gfreq = frequency             'gfreq holds value used for si5351
  240.  
  241. 'frequency offset routine
  242. gfreq = gfreq + ifoffset      'high side injection
  243. 'gfreq = gfreq - ifoffset                                   'low-side injection required
  244.  
  245. Calculate                     'calculate the startup VFO value
  246.  
  247. siaddr1 = 26                  'point to CLK0 base register addresses
  248. siaddr2 = 42
  249. siaddr3 = 44
  250.  
  251. Sendfreq                      'and send it to the si5351 CLK0
  252.  
  253. regaddr = 16
  254. regdata = 79
  255. call siout(regaddr , regdata) 'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  256.  
  257. gfreq = bfofreq               'now load bfo frequency
  258.  
  259. Calculate                     'calculate startup bfo/cio
  260.  
  261. siaddr1 = 34                  'point to CLK1 base register addresses
  262. siaddr2 = 50
  263. siaddr3 = 52
  264.  
  265. sendfreq                      'and send data to si5351 CLK1
  266.  
  267. regaddr = 17
  268. regdata = 111
  269. call siout(regaddr , regdata) 'enable CLK1, source=crystal, PLLB=integer mode, power level=8mA i.e. 0dB
  270.  
  271.  
  272. Displaylcd                    'then display frequency and status on lcd
  273.  
  274. 'Configure the 8-bit Timer0 interrupt for encoder
  275. 'Overflow time = overflow counts * prescale / uP clock frequency
  276. '= 128 * 256 / 8,000,000 = 4mS = 244 Hz (8 MHz RC clock)
  277. 'Here prescale = 256 (Possible prescale factors: 8, 64, 256, 1024)
  278.  
  279. Config Timer0 = Timer , Prescale = 256
  280. Const PresetTimer0 = 192      'Timer preset value to initialize Timer0 i.e. 2mS)
  281. On Timer0 Timer0_isr          'Timer0 interrupt service routine on overflow
  282. Enable Timer0                 'interrupt encoder
  283. Enable Interrupts             'enable all interrupts
  284.  
  285.  
  286. Do                            'Start of main program
  287.  
  288.     Vadc = getadc(0)          'get current s-meter value
  289.     barplot                   'and plot result
  290.  
  291.  
  292.    'STEP
  293.     If Stepkey = 0 Then
  294.        Incr Stepsize
  295.        If Stepsize = 5 Then Stepsize = 1
  296.        If Stepsize = 1 Then Delta = 5       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  297.        If Stepsize = 2 Then Delta = 100       '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  298.        If Stepsize = 3 Then Delta = 1000
  299.        If Stepsize = 4 Then Delta = 10000
  300.        set update             'to flag this change
  301.     end if
  302.  
  303.     Keyup1:
  304.     If Stepkey = 0 Then Goto Keyup1       'and wait for button to be released
  305.  
  306.  
  307.     'Processing of rotary encoder
  308.     Disable Timer0            'Stop Timer0 interrupts
  309.  
  310.     Select Case spin
  311.         Case 1 : Frequency = Frequency - Delta
  312.         Case 2 : Frequency = Frequency + Delta
  313.     End Select
  314.  
  315.  
  316.     If spin > 0 or update = 1 Then       'encoder or buttons changed so update display and si5351
  317.  
  318.         displaylcd            'show new frequency and status
  319.  
  320.         gfreq = frequency     'gfreq holds value used for si5351
  321.  
  322.         'frequency offset routine
  323.         gfreq = gfreq + ifoffset       'high side injection
  324.         'gfreq = gfreq - ifoffset                           'if low-side injection required
  325.  
  326.         Calculate             'calculate new VFO data
  327.  
  328.         siaddr1 = 26          'point to CLK0 base register addresses
  329.         siaddr2 = 42
  330.         siaddr3 = 44
  331.  
  332.         Sendfreq              'and send it to the si5351
  333.  
  334.         regaddr = 16
  335.         regdata = 79
  336.         call siout(regaddr , regdata)       'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  337.  
  338.  
  339.         spin = 0              'Reset spin after processing
  340.         reset update          'and update flag
  341.  
  342.     End If
  343.  
  344.     Enable Timer0             'Restart Timer0
  345.  
  346.  
  347. Loop                          'End of main program
  348.  
  349.  
  350.  
  351. '**********************************************************************
  352. 'Subroutines...
  353.  
  354.  
  355. '**********************************************************************
  356. 'Interrupt service routine for Timer0 (encoder)
  357.  
  358. 'Encoder interrupt on timer0 overflow
  359. 'Timer0 should be stopped in main program while data is being displayed
  360. 'Output: spin = 2: increment or
  361. '             = 1: decrement if encoder has changed
  362. 'if no change then spin = 0
  363. '
  364. '**********************************************************************
  365. Timer0_isr:
  366.    Timer0 = PresetTimer0      'Initialize Timer0
  367.    encval = 0                 'clear variable
  368.  
  369.    encval.0 = enca            'input current encoder levels
  370.    encval.1 = encb            'so encval now holds current encoder state
  371.  
  372.    'Check if encoder encoder pattern is changed
  373.    'spin = 1: decremented (turned counter clockwise)
  374.    'spin = 2: incremented (turned clockwise)
  375.    If encval <> Lastencoder Then       'encoder is changed
  376.  
  377.       If encval = &B00000011 And Lastencoder = &B00000010 Then spin = 2
  378.       If encval = &B00000011 And Lastencoder = &B00000001 Then spin = 1
  379.  
  380. 'the following lines may be required to be ADDED to those above with some encoders
  381. 'which give an additional step between mechanical detent positions
  382. '      If encval = &B00000000 And Lastencoder = &B00000001 Then spin = 2
  383. '      If encval = &B00000000 And Lastencoder = &B00000010 Then spin = 1
  384.  
  385.       Lastencoder = encval    'update for next time
  386.    End If
  387. Return
  388.  
  389. '**********************************************************************
  390.  
  391.  
  392. '**********************************************************************
  393. ' Displays frequency on upper line of the 16*2 LCD to 1 Hz resolution
  394. ' and step size, band, PTT status and mode on the lower line
  395. ' *************************REDO SOFTWARE***********************
  396. '**********************************************************************
  397.  
  398. Sub Displaylcd
  399.  
  400.  'parse Frequency for display
  401.     freqtxt = str(frequency)  'convert frequency to text
  402.     Hz = right(freqtxt , 3)   'extract Hz text
  403.     freqtxt = str(frequency)  'do it again because for some reason !! freqtxt gets blown away by right()
  404.     fcnt = len(freqtxt) - 3   'nbr of remaining digits  (assumes lowest freq is 1000 Hz)
  405.  
  406.     while fcnt < 5
  407.       insertchar freqtxt , 1 , " "       'add spaces to start of text for formatting
  408.       fcnt = fcnt + 1
  409.     wend
  410.  
  411.     MHz = left(freqtxt , 2)   'now grab first two chars
  412.     kHz = mid(freqtxt , 3 , 3)       'and mid three chars
  413.  
  414.    Locate 1 , 1               'point to start of top line
  415.    lcd " " ; MHz ; "," ; kHz ; "." ; Hz ; " MHz "       'Format: _MM.kkk.hhh MHz_
  416.  
  417.    Locate 2 , 1               'second line
  418.    'Format: SSSSS_xxxxxxxxxx where SSS=step size, x..x=S-meter bargraph (50 dots wide)
  419.  
  420.    select case stepsize
  421.       case 1 : Lcd " 5Hz "
  422.       case 2 : Lcd "100Hz"
  423.       case 3 : Lcd " 1kHz"
  424.       case 4 : Lcd "10kHz"
  425.    end select
  426.  
  427. End Sub
  428.  
  429. '**********************************************************************
  430. ' subroutine to initialise the si5351 chip via I2C
  431. '**********************************************************************
  432.  
  433. Sub si5351init
  434.  
  435. regaddr = 183
  436. regdata = 192
  437. call siout(regaddr , regdata) 'set xtal load cap to 10pF
  438. regaddr = 3
  439. regdata = 0
  440. call siout(regaddr , regdata) 'enable all outputs
  441. regaddr = 15
  442. regdata = 0
  443. call siout(regaddr , regdata) 'select xtal as PLL input source
  444. regaddr = 16
  445. regdata = 15                  'PLLA is source, 8mA output
  446. call siout(regaddr , regdata) 'configure clock 0 control register
  447. regaddr = 17
  448. regdata = 47                  'PLLB is source, 8mA output
  449. call siout(regaddr , regdata) 'configure clock 1 control register
  450. regaddr = 18
  451. regdata = 47                  'PLLB is source, 8mA output
  452. call siout(regaddr , regdata) 'configure clock 2 control register
  453. regaddr = 177
  454. waitms 10                     'wait 10ms just in case
  455.  
  456.  
  457. End Sub
  458.  
  459. '********************************************************************************
  460. ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  461. '********************************************************************************
  462. sub calculate
  463.  
  464. rdivider = 1                  'initialise r
  465.  
  466. outdivider = 900000000 \ gfreq       'and outdivider
  467.  
  468. while outdivider > 900
  469.    rdivider = 2 * rdivider
  470.    outdivider = outdivider \ 2
  471. wend
  472.  
  473. fvco = outdivider mod 2       'check outdivider is an even number
  474. if fvco <> 0 then outdivider = outdivider - 1       'using fvco as a temporary register
  475.  
  476. fvco = outdivider * rdivider
  477. fvco = fvco * gfreq           'determine PLL frequency
  478.  
  479. select case rdivider          'determine value of R44 bits [6:4]
  480.       case 1 : rbyte = 0      '000 0000
  481.       case 2 : rbyte = 16     '001 0000
  482.       case 4 : rbyte = 32     '010 0000
  483.       case 8 : rbyte = 48     '011 0000
  484.       case 16 : rbyte = 64    '100 0000
  485.       case 32 : rbyte = 80    '101 0000
  486.       case 64 : rbyte = 96    '110 0000
  487.       case 128 : rbyte = 112  '111 0000
  488. end select
  489.  
  490. afactor = fvco \ xtal
  491. fvalue = afactor * xtal       'fvalue = fvco -afactor * xtal
  492. fvalue = fvco - fvalue        'a+b/c
  493. fvalue = fvalue * cfactor
  494. fvalue = fvalue \ xtal
  495. bfactor = fvalue
  496.  
  497. ms0p1 = 128 * outdivider
  498. ms0p1 = ms0p1 - 512
  499. fvalue = 128 * bfactor
  500. fvalue = fvalue \ cfactor
  501. finteger = fvalue
  502. msnap1 = 128 * afactor
  503. msnap1 = msnap1 + finteger    'finteger used instead of fvalue for variable matching
  504. msnap1 = msnap1 - 512
  505. msnap3 = finteger * cfactor   'using msnap3 as temp result buffer
  506. msnap2 = 128 * bfactor
  507. msnap2 = msnap2 - msnap3
  508. msnap3 = cfactor
  509.  
  510. 'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  511.  
  512. end sub
  513.  
  514. '**********************************************************************
  515. ' send converted freq data to si5351 for CLK0 output
  516. '**********************************************************************
  517. sub sendfreq
  518.  
  519. regaddr = siaddr1
  520. call siout(regaddr , ms32)    'R26=msnap3[15:8]
  521. incr regaddr
  522. call siout(regaddr , ms31)    'R27=msnap3[7:0]
  523. incr regaddr
  524. call siout(regaddr , ms13)    'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  525. incr regaddr
  526. call siout(regaddr , ms12)    'R29=msnap1[15:8]
  527. incr regaddr
  528. call siout(regaddr , ms11)    'R30=msnap1[7:0]
  529. temp = ms33                   'temp[3:0]=msnap3[19:16]
  530. swap temp                     'temp[7:4]=msnap3[19:16]
  531. temp = temp or ms23           'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  532. incr regaddr
  533. call siout(regaddr , temp)    'R31=(msnap3[19:16],msnap2[19:16])
  534. incr regaddr
  535. call siout(regaddr , ms22)    'R32=msnap2[15:8]
  536. incr regaddr
  537. call siout(regaddr , ms21)    'R33=msnap2[7:0]
  538. regaddr = siaddr2
  539. regdata = 0
  540. call siout(regaddr , regdata) 'R42=MS0_P3[15:8]
  541. incr regaddr
  542. regdata = 1
  543. call siout(regaddr , regdata) 'R43=MS0_P3[7:0]
  544. temp = rbyte
  545. temp = temp or m0p13
  546. incr regaddr
  547. call siout(regaddr , temp)    'R44=(0,R[7:4],MS0_P1[17:16])
  548. incr regaddr
  549. call siout(regaddr , m0p12)   'R45=MS0_P1[15:8]
  550. incr regaddr
  551. call siout(regaddr , m0p11)   'R46=MS0_P1[7:0]
  552. incr regaddr
  553. regdata = 0
  554. call siout(regaddr , regdata) 'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  555. incr regaddr
  556. regdata = 0
  557. call siout(regaddr , regdata) 'R48=MS0_P2[15:8]=0 always
  558. incr regaddr
  559. regdata = 0
  560. call siout(regaddr , regdata) 'R49=MS0_P2[7:0]=0 always
  561. if outdivider = 4 then        'for output frequencies greater than 150MHz and less than 200MHz
  562.    regaddr = siaddr3
  563.    regdata = 12
  564.    call siout(regaddr , regdata)
  565.    incr regaddr
  566.    regdata = 0
  567.    call siout(regaddr , regdata)
  568.    incr regaddr
  569.    regdata = 0
  570.    call siout(regaddr , regdata)
  571. end if
  572. regaddr = 3
  573. regdata = 4
  574. call siout(regaddr , regdata) 'enable all outputs except CLK2
  575.  
  576. end sub
  577.  
  578. '**********************************************************************
  579. ' i2c transmission to si5351
  580. '**********************************************************************
  581. sub siout(sireg as byte , sidata as byte)
  582. 'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  583.  
  584.    'Write a single byte (slave address 192, register sireg, value sibyte)
  585.     I2cstart
  586.     I2cwbyte 192              'i2c address of si5351a
  587.     waitus 1                  'suggested delay from forum
  588.     I2cwbyte sireg
  589.     waitus 1
  590.     I2cwbyte sidata
  591.     waitus 1
  592.     I2cstop
  593.  
  594. end sub
  595.  
  596. '**********************************************************************
  597. ' s-meter display shows current adc value Vadc plotted on a 50 dot
  598. ' bargraph on lower line of LCD from (2,7) to end of the line
  599. '**********************************************************************
  600. sub barplot
  601.  
  602.    Local Col As Byte
  603.    Local Bar5 As Byte
  604.    Local Bar1 As Byte
  605.  
  606.    Bar5 = Vadch \ 25          'nbr of full bargraph blocks
  607.    Bar1 = Vadch Mod 25        'nbr of dots in remaining block
  608.    bar1 = bar1 \ 5
  609.  
  610.    Locate 2 , 7               'point cursor to start of graph
  611.  
  612.    For Col = 1 To Bar5        'plot the full blocks
  613.       Lcd Chr(5)
  614.    Next Col
  615.  
  616.    Select Case Bar1           'and last sub-block
  617.       case 0 : lcd " "
  618.       Case 1 : Lcd Chr(1)
  619.       Case 2 : Lcd Chr(2)
  620.       Case 3 : Lcd Chr(3)
  621.       Case 4 : Lcd Chr(4)
  622.    End Select
  623.  
  624.    bar5 = bar5 + 2            'point to next location
  625.    if bar5 < 11 then          'blank any previous dots
  626.       for col = bar5 to 10
  627.          lcd " "
  628.       next col
  629.    end if
  630.  
  631. end sub
  632.  
  633. '**********************************************************************
  634.  
  635.  
  636.  
  637. end
Docelowo generator będzie pracował w moim starym Radmorku :)
radmor.jpg
Tu kod ogołocony z wszystkiego co uznałem za zbędne do pracy jako pojedynczy generator .
Jeszcze wprowadzę kilka zmian by dostosować do moich potrzeb w radyjku .
  1.     '------------------------------------------------------------------
  2.   ' si5351a DDS Oscillator with I2C LCD display
  3.   ' Author: Andrew Woodfield ZL2PD
  4.   ' Date: March 2016
  5.   ' File Name: si85vfoxx.bas     (where xx is version number)
  6.   '
  7.   ' Released under the terms and conditions of the
  8.   ' Creative Commons Public License ("CCPL")
  9.   ' See creativecommons.org for details
  10.   '
  11.   ' Commercial use is prohibited without written permission
  12.   ' from the author
  13.   '
  14.   '------------------------------------------------------------------
  15.   ' Adapted from boardtest11.bas:
  16.   '
  17.   ' V01: initial code
  18.   '
  19.   '------------------------------------------------------------------
  20.   ' Credits:
  21.   '
  22.   ' I2C LCD code adapted from www.ne.jp/asahi/shared/o-family/ElecRoom/ElecMAIN.htm
  23.   ' si5351 code is adapted from OE1CGS and Jason Milldrum C code
  24.   '
  25.   ' Rotary encoder software is adapted from:
  26.   ' http://dl6gl.de/software/drehencoder-mit-bascom
  27.   '
  28.   '------------------------------------------------------------------
  29.   ' Program Description:
  30.  
  31.   ' An ATtiny85 is used to control a Silicon Labs si5351a 3-output
  32.   ' PLL/divider oscillator and I2C 16x2 alphanumeric LCD display with
  33.   ' rotary encoder and some pushbuttons.
  34.   '
  35.   '------------------------------------------------------------------
  36.   ' Fuse settings
  37.   '
  38.   ' LOCK Byte: 0ffh (No locks)
  39.   ' EXTd Byte: 0ffh (BOD disabled)
  40.   '
  41.   ' HIGH Byte: 05fh
  42.   '   RSTDISBL 0 DISABLED
  43.   '       DWEN 1 DW not enabled
  44.   '      SPIEN 0 SPI programming enabled
  45.   '      WDTON 1 Watchdog timer off
  46.   '     EESAVE 1 EEPROM not preserved in erase
  47.   '  BODLEVEL2 1 Boot ROM size
  48.   '  BODLEVEL1 1
  49.   '  BODLEVEL0 1 No boot vector at startup
  50.   '
  51.   ' LOW Byte:  0e2h
  52.   '     CKDIV8 1 NOT divided by 8
  53.   '      CKOUT 1 Not enabled
  54.   '       SUT1 1 Slow rising power
  55.   '       SUT0 0
  56.   '     CKSEL3 0 8 MHz internal RC clock
  57.   '     CKSEL2 0
  58.   '     CKSEL1 1
  59.   '     CKSEL0 0
  60.   '
  61.   '------------------------------------------------------------------
  62.   ' Compiler Directives (some fundamental hardware issues)
  63.   '$sim
  64.     $regfile = "m8def.dat"
  65.     $crystal = 8000000        '8MHz internal RC clock
  66.  
  67.     $hwstack = 128
  68.     $swstack = 64
  69.     $framesize = 128
  70.  
  71.   '-------------------------------------------------------------------------------
  72.     Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
  73.     Config Lcd = 20 * 2
  74.  
  75.     Config Portb.1 = Output   'dds
  76.     Config Portb.2 = Output   'dds
  77.     Config Sda = Portb.1
  78.     Config Scl = Portb.2
  79.     Config Pinb.0 = Input
  80.     Config Pinb.3 = Input
  81.     Config Pinb.4 = Input
  82.  
  83.     Set Portb.0               'set pullups
  84.     Set Portb.1
  85.     Set Portb.2
  86.     Set Portb.3
  87.     Set Portb.4
  88.     Stepkey Alias Pinb.0      'step key on encoder
  89.     Enca Alias Pinb.3         'rotary encoder input A
  90.     Encb Alias Pinb.4         'rotary encoder input B
  91.  
  92.  
  93.     ' Declare Variables
  94.  
  95.     Dim Mhz As String * 2     'display subroutine variables
  96.     Dim Khz As String * 3
  97.     Dim Hz As String * 3
  98.     Dim Lastftext As String * 6       'for display of freqb khz & Hz digits
  99.     Dim Freqtxt As String * 9
  100.     Dim Tekst1 As String * 9
  101.     Dim Fcnt As Byte
  102.     Dim Temp As Byte          'temporary variable used in sendfreq and sbarplot routines
  103.     Dim Frequency As Dword    'four byte unsigned variable
  104.     Dim Gfreq As Dword        'calculates si5351 VFO output frequency
  105.     Dim Stepsize As Byte
  106.     Dim Delta As Dword
  107.     Dim Update As Bit         'bit is set (1) if a switch or encoder has changed
  108.     Dim Fvco As Dword         'si5351 vco frequency
  109.     Dim Outdivider As Dword   '4,6,8-900
  110.     Dim Rdivider As Byte      'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  111.     Dim Rbyte As Byte         'used as temp store before final data load to si5351
  112.     Dim Afactor As Dword
  113.     Dim Bfactor As Dword
  114.     Dim Fvalue As Single      'used to determine accuracy of fractional calculation
  115.     Dim Finteger As Dword
  116.  
  117.     Dim Ms0p1 As Dword        '18-bit MS0_P1 si5351 parameters for Output 0
  118.     Dim M0p11 As Byte At Ms0p1 Overlay       'mirrored variables for dds calculation
  119.     Dim M0p12 As Byte At Ms0p1 + 1 Overlay
  120.     Dim M0p13 As Byte At Ms0p1 + 2 Overlay
  121.     Dim M0p14 As Byte At Ms0p1 + 3 Overlay       'most significant byte for ms0p1
  122.  
  123.     'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  124.                                                           'si5351 parameters for PLLA
  125.     Dim Msnap1 As Dword       '18-bit variable for MSNA_P1
  126.     Dim Ms11 As Byte At Msnap1 Overlay       'mirrored variables for dds calculation
  127.     Dim Ms12 As Byte At Msnap1 + 1 Overlay
  128.     Dim Ms13 As Byte At Msnap1 + 2 Overlay
  129.     Dim Ms14 As Byte At Msnap1 + 3 Overlay       'most significant byte
  130.  
  131.     Dim Msnap2 As Dword       '20-bit variable for MSNA_P2
  132.     Dim Ms21 As Byte At Msnap2 Overlay       'mirrored variables for dds calculation
  133.     Dim Ms22 As Byte At Msnap2 + 1 Overlay
  134.     Dim Ms23 As Byte At Msnap2 + 2 Overlay
  135.     Dim Ms24 As Byte At Msnap2 + 3 Overlay       'most significant byte
  136.  
  137.     Dim Msnap3 As Dword       '20-bit variable for MSNA_P3
  138.     Dim Ms31 As Byte At Msnap3 Overlay       'mirrored variables for dds calculation
  139.     Dim Ms32 As Byte At Msnap3 + 1 Overlay
  140.     Dim Ms33 As Byte At Msnap3 + 2 Overlay
  141.     Dim Ms34 As Byte At Msnap3 + 3 Overlay       'most significant byte
  142.  
  143.     Dim Regaddr As Byte , Regdata As Byte       'for i2c calls
  144.     Dim Siaddr1 As Byte , Siaddr2 As Byte       'for writing to si5351 CLK0 and CLK1
  145.  
  146.         '    Declare Constants
  147.     Const Startfreq = 10000   'xxx                          '40m starting frequency
  148.     Const Xtal = 25001000     ' xxx 25000000   '**NOTE: Value may be adjusted during alignment ***
  149.     Const Cfactor = 10000     'xxx 1048575
  150.  
  151.     Frequency = Startfreq     'initialise frequency (20m for now)
  152.     Stepsize = 1
  153.     Delta = 5
  154.  
  155.  
  156.  
  157.     '     Declare Subroutines
  158.     Declare Sub Si5351init    'initialises si5351
  159.     Declare Sub Displaylcd    'displays current oscillator frequency
  160.     Declare Sub Calculate     'converts current VFO or BFO freq to data for si5351
  161.     Declare Sub Sendfreq      'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  162.     Declare Sub Siout(sireg As Byte , Sidata As Byte)       'for i2c write to si5351
  163.     Declare Sub Plus
  164.     Declare Sub Minus
  165.  
  166.  
  167.     '***************************** Program *****************************************
  168.  
  169.     '      initialise i2c here...
  170.     I2cinit
  171.     Waitms 50                 'for i2c to settle and for lcd RC reset time
  172.     Cursor Off                'LCD cursor of
  173.     Cls
  174.     Update = 0                'clear the flags
  175.  
  176.  
  177.     Si5351init                'initialises si5351
  178.  
  179.     Gfreq = Frequency         'gfreq holds value used for si5351
  180.  
  181.      Calculate                'calculate the startup VFO value
  182.  
  183.     Siaddr1 = 26              'point to CLK0 base register addresses
  184.     Siaddr2 = 42
  185.  
  186.      Sendfreq                 'and send it to the si5351 CLK0
  187.  
  188.     Regaddr = 16
  189.     Regdata = 79
  190.     Call Siout(regaddr , Regdata)       'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  191.  
  192.        Displaylcd             'then display frequency and status on lcd
  193.  
  194.  
  195.     Do                        'Start of main program
  196.  
  197.      If Stepkey = 0 Then
  198.           Incr Stepsize
  199.           Waitms 500          ' xxx
  200.        If Stepsize = 8 Then   'xxx
  201.           Stepsize = 1
  202.        End If
  203.        If Stepsize = 1 Then Delta = 5       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  204.        If Stepsize = 2 Then Delta = 100       '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  205.        If Stepsize = 3 Then Delta = 1000
  206.        If Stepsize = 4 Then Delta = 10000
  207.        If Stepsize = 5 Then Delta = 100000       'xxx
  208.        If Stepsize = 6 Then Delta = 1000000       ' xxx
  209.        If Stepsize = 7 Then Delta = 10000000       ' xxx
  210.         Update = 1
  211.          Displaylcd           'to flag this change
  212.      End If
  213.  
  214.       Debounce Pinb.3 , 0 , Plus , Sub
  215.       Debounce Pinb.4 , 0 , Minus , Sub
  216.  
  217.      If Update = 1 Then       'encoder or buttons changed so update display and si5351
  218.                                                  'show new frequency and status
  219.        Gfreq = Frequency      'gfreq holds value used for si5351
  220.        Calculate              'calculate new VFO data
  221.        Siaddr1 = 26           'point to CLK0 base register addresses
  222.        Siaddr2 = 42
  223.        Sendfreq               'and send it to the si5351
  224.        Regaddr = 16
  225.        Regdata = 79
  226.        Call Siout(regaddr , Regdata)       'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  227.        Update = 0
  228.                                               'and update flag
  229.      End If
  230.  
  231.     Loop                      'End of main program
  232.    End
  233.  
  234.     '**********************************************************************
  235.     'Subroutines...
  236.     '=====================================================================
  237.     Sub Plus
  238.       Frequency = Frequency + Delta
  239.       If Frequency > 150000000 Then
  240.       Frequency = 150000000
  241.       End If
  242.       Update = 1
  243.       Displaylcd
  244.     End Sub
  245.  
  246.     Sub Minus
  247.       Frequency = Frequency - Delta
  248.       If Frequency < 10000 Then
  249.       Frequency = 10000
  250.       End If
  251.       If Frequency > 150000000 Then
  252.       Frequency = 10000
  253.       End If
  254.       Update = 1
  255.       Displaylcd
  256.     End Sub
  257.     '========================================================================
  258.  
  259.     '========================================================================
  260.     Sub Displaylcd
  261.          Tekst1 = "000000000"
  262.        Freqtxt = Str(frequency)
  263.        Fcnt = Len(freqtxt)
  264.      If Fcnt = 1 Then
  265.         Mid(tekst1 , 9 , Fcnt) = Freqtxt       '9
  266.            Elseif Fcnt = 2 Then
  267.         Mid(tekst1 , 8 , Fcnt) = Freqtxt       '8
  268.            Elseif Fcnt = 3 Then
  269.         Mid(tekst1 , 7 , Fcnt) = Freqtxt       '7
  270.            Elseif Fcnt = 4 Then
  271.         Mid(tekst1 , 6 , Fcnt) = Freqtxt       '6
  272.            Elseif Fcnt = 5 Then
  273.         Mid(tekst1 , 5 , Fcnt) = Freqtxt       '5
  274.            Elseif Fcnt = 6 Then
  275.         Mid(tekst1 , 4 , Fcnt) = Freqtxt       '5
  276.            Elseif Fcnt = 7 Then
  277.         Mid(tekst1 , 3 , Fcnt) = Freqtxt       '3
  278.            Elseif Fcnt = 8 Then
  279.         Mid(tekst1 , 2 , Fcnt) = Freqtxt       '2
  280.            Elseif Fcnt = 9 Then
  281.         Mid(tekst1 , 1 , Fcnt) = Freqtxt       '1
  282.      End If
  283.  
  284.         If Frequency < 1000000 Then
  285.  
  286.           Locate 1 , 1
  287.            Lcd "     "
  288.          Lcd Mid(tekst1 , 4 , 3)
  289.           Lcd "."
  290.          Lcd Mid(tekst1 , 7 , 3)
  291.           Lcd " kHz"
  292.          End If
  293.  
  294.        If Frequency => 1000000 Then
  295.          Locate 1 , 2
  296.          Lcd Mid(tekst1 , 1 , 3)
  297.           Lcd "."
  298.          Lcd Mid(tekst1 , 4 , 3)
  299.            Lcd "."
  300.          Lcd Mid(tekst1 , 7 , 3)
  301.           Lcd " MHz"
  302.         End If
  303.       Locate 2 , 1            'second line
  304.      Select Case Stepsize
  305.        Case 1 : Lcd " 5 Hz  "
  306.        Case 2 : Lcd " 100 Hz"
  307.        Case 3 : Lcd " 1 kHz "
  308.        Case 4 : Lcd " 10 kHz"
  309.        Case 5 : Lcd " 100kHz "
  310.        Case 6 : Lcd " 1 MHz "
  311.        Case 7 : Lcd " 10 MHz "
  312.      End Select
  313.  
  314.     End Sub
  315.  
  316.     '**********************************************************************
  317.     ' subroutine to initialise the si5351 chip via I2C
  318.     '**********************************************************************
  319.  
  320.     Sub Si5351init
  321.  
  322.         Regaddr = 183
  323.         Regdata = 192
  324.      Call Siout(regaddr , Regdata)       'set xtal load cap to 10pF
  325.         Regaddr = 3
  326.         Regdata = 0
  327.      Call Siout(regaddr , Regdata)       'enable all outputs
  328.         Regaddr = 15
  329.         Regdata = 0
  330.      Call Siout(regaddr , Regdata)       'select xtal as PLL input source
  331.         Regaddr = 16
  332.         Regdata = 15          'PLLA is source, 8mA output
  333.      Call Siout(regaddr , Regdata)       'configure clock 0 control register
  334.       Waitms 10               'wait 10ms just in case
  335.  
  336.     End Sub
  337.  
  338.     '********************************************************************************
  339.     ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  340.     '********************************************************************************
  341.     Sub Calculate
  342.  
  343.         Rdivider = 1          'initialise r
  344.         Outdivider = 900000000 \ Gfreq       'and outdivider
  345.       While Outdivider > 900  '900
  346.         Rdivider = 2 * Rdivider
  347.         Outdivider = Outdivider \ 2
  348.       Wend
  349.         Fvco = Outdivider Mod 2       'check outdivider is an even number
  350.  
  351.       If Fvco <> 0 Then Outdivider = Outdivider - 1       'using fvco as a temporary register
  352.         Fvco = Outdivider * Rdivider
  353.         Fvco = Fvco * Gfreq   'determine PLL frequency
  354.      Select Case Rdivider     'determine value of R44 bits [6:4]
  355.         Case 1 : Rbyte = 0    '000 0000
  356.         Case 2 : Rbyte = 16   '001 0000
  357.         Case 4 : Rbyte = 32   '010 0000
  358.         Case 8 : Rbyte = 48   '011 0000
  359.         Case 16 : Rbyte = 64  '100 0000
  360.         Case 32 : Rbyte = 80  '101 0000
  361.         Case 64 : Rbyte = 96  '110 0000
  362.         Case 128 : Rbyte = 112       '111 0000
  363.      End Select
  364.        Afactor = Fvco \ Xtal
  365.        Fvalue = Afactor * Xtal       'fvalue = fvco -afactor * xtal
  366.        Fvalue = Fvco - Fvalue 'a+b/c
  367.        Fvalue = Fvalue * Cfactor
  368.        Fvalue = Fvalue \ Xtal
  369.        Bfactor = Fvalue
  370.        Ms0p1 = 128 * Outdivider
  371.        Ms0p1 = Ms0p1 - 512
  372.        Fvalue = 128 * Bfactor
  373.        Fvalue = Fvalue \ Cfactor
  374.        Finteger = Fvalue
  375.        Msnap1 = 128 * Afactor
  376.        Msnap1 = Msnap1 + Finteger       'finteger used instead of fvalue for variable matching
  377.        Msnap1 = Msnap1 - 512
  378.        Msnap3 = Finteger * Cfactor       'using msnap3 as temp result buffer
  379.        Msnap2 = 128 * Bfactor
  380.        Msnap2 = Msnap2 - Msnap3
  381.        Msnap3 = Cfactor
  382.      'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  383.     End Sub
  384.  
  385.     '**********************************************************************
  386.     ' send converted freq data to si5351 for CLK0 output
  387.     '**********************************************************************
  388.     Sub Sendfreq
  389.  
  390.           Regaddr = Siaddr1
  391.      Call Siout(regaddr , Ms32)       'R26=msnap3[15:8]
  392.      Incr Regaddr
  393.      Call Siout(regaddr , Ms31)       'R27=msnap3[7:0]
  394.      Incr Regaddr
  395.      Call Siout(regaddr , Ms13)       'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  396.      Incr Regaddr
  397.      Call Siout(regaddr , Ms12)       'R29=msnap1[15:8]
  398.      Incr Regaddr
  399.      Call Siout(regaddr , Ms11)       'R30=msnap1[7:0]
  400.           Temp = Ms33         'temp[3:0]=msnap3[19:16]
  401.      Swap Temp                'temp[7:4]=msnap3[19:16]
  402.           Temp = Temp Or Ms23 'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  403.      Incr Regaddr
  404.      Call Siout(regaddr , Temp)       'R31=(msnap3[19:16],msnap2[19:16])
  405.      Incr Regaddr
  406.      Call Siout(regaddr , Ms22)       'R32=msnap2[15:8]
  407.      Incr Regaddr
  408.      Call Siout(regaddr , Ms21)       'R33=msnap2[7:0]
  409.  
  410.  
  411.           Regaddr = Siaddr2
  412.           Regdata = 0
  413.      Call Siout(regaddr , Regdata)       'R42=MS0_P3[15:8]
  414.      Incr Regaddr
  415.           Regdata = 1
  416.      Call Siout(regaddr , Regdata)       'R43=MS0_P3[7:0]
  417.           Temp = Rbyte
  418.           Temp = Temp Or M0p13
  419.      Incr Regaddr
  420.      Call Siout(regaddr , Temp)       'R44=(0,R[7:4],MS0_P1[17:16])
  421.      Incr Regaddr
  422.      Call Siout(regaddr , M0p12)       'R45=MS0_P1[15:8]
  423.      Incr Regaddr
  424.      Call Siout(regaddr , M0p11)       'R46=MS0_P1[7:0]
  425.      Incr Regaddr
  426.           Regdata = 0
  427.      Call Siout(regaddr , Regdata)       'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  428.      Incr Regaddr
  429.           Regdata = 0
  430.      Call Siout(regaddr , Regdata)       'R48=MS0_P2[15:8]=0 always
  431.      Incr Regaddr
  432.           Regdata = 0
  433.      Call Siout(regaddr , Regdata)       'R49=MS0_P2[7:0]=0 always
  434.  
  435.  
  436.     End Sub
  437.  
  438.     '**********************************************************************
  439.     ' i2c transmission to si5351
  440.     '**********************************************************************
  441.     Sub Siout(sireg As Byte , Sidata As Byte)
  442.      'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  443.      'Write a single byte (slave address 192, register sireg, value sibyte)
  444.      I2cstart
  445.      I2cwbyte 192             'i2c address of si5351a
  446.      Waitus 1                 'suggested delay from forum
  447.      I2cwbyte Sireg
  448.      Waitus 1
  449.      I2cwbyte Sidata
  450.      Waitus 1
  451.      I2cstop
  452.  
  453.     End Sub
Teraz to co mnie interesuje , można jakoś prościej sterować tym generatorem ?
Chciał bym mieć możliwość sterowania osobno każdym wyjściem ;)

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 » 06 mar 2023, 11:17

Halo Pan Henryk co to za model Radmora na jakie QRG.
pozdrawiam Jacek.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 06 mar 2023, 13:48

Witaj , Jacek
Zbieranina z kilku Radmorów ;) a będzie to tylko odbiornik nasłuchowy dla pasm 144-146 , 148 - 154 , 88 - 107 MHz .
Taki konstrukcyjny kaprys , głowice dla dwóch pierwszych pasm mam już dostrojone , z ostatnim w fazie dłubania .

Pozdrawiam Henryk .
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Generator Si5351

Post autor: Jacek » 06 mar 2023, 15:11

Witam to jest ten projekt https://www.zl2pd.com/9bandModularVFO.html ?
pozdrawiam Jacek.
P.S. a... to pewnie ten https://www.zl2pd.com/tiny85_si5351_VFO.html
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 06 mar 2023, 18:10

Tak Pinie Jacku , ten drugi projekt wziąłem na warsztat , dlaczego akurat ten ? sam nie wiem ;)

Ktoś kiedyś powiedział " jak coś nie wychodzi należy sie z tym przespać " .
To działa ! ale nie w moim przypadku , bo jak rano wstałem , to moja skleroza przysłoniła skutecznie cały wyśniony wątek :lol:
Potrzebna była cholernie mocna kawa by obudzić czerep do myślenia .
Teoretycznie wiem jak to ruszyć , teoretycznie , wiele razy przeglądałem mapę pamięci rejestrów i nie widziałem tego co istotne , do momentu zrobienia z mapy dziecięcej kolorowanki . Mapa została obcięta o rejestry dla wyjść 4,5,6 ,są take same tylko pod innym adresem .
mapa_si5351.JPG
Moja teoria :
Powiele razy trzy enkoder lub dodam przycisk wyboru CLK0,CLK1,CLK2 , gdzie będą zmieniane Siaddr1 ,Siaddr2 .
Te dwie zmienne przekazują początkowy adres dla PLLA , druga dla multisyntezera .
Podnosząc aderes o 8 bajtów wyślę dane tam gdzie powinny być przesłane , pamiętając o tym , że pętle PLL są tylko dwie .
Tyle mojej wyśnionej i z bólem odrestaurowanej teorii .Praktycznie sprawdzę to dopiero w piątek , bo mogę wtedy siedzieć do późnej nocy . :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 » 06 mar 2023, 18:39

Hi ale beka ale w innym temacie ostatni link w tym temacie przyszedł o 18:10 klikam w link a forum każe mi się na nowo logować a jak klikam link w powiadomieniu z godziny 13:48 to od razu jestem zalogowany na forum i strona otwiera się w tym temacie ... o co chodzi? :o :shock:
pozdrawiam Jacek.
Awatar użytkownika
niveasoft
Posty: 1207
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Generator Si5351

Post autor: niveasoft » 07 mar 2023, 13:42

To różnie bywa chyba ze względu na to jakie masz IP a niekoniecznie ma się zawsze to samo bo możesz logowac się przez WiFi w pracy i tym samym komputerem/telefonem przez WiFi w domu albo LTE przyznało jakieś inne. Nie wiem jak tam z ciasteczkami ;)

Zajrzyj do -> Twoje konto -> Profil -> Zarządzanie danymi logowania to się rozjaśni :D
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 07 mar 2023, 15:57

Dzień dobry/wieczór , nigdy nie wiadomo o jakiej porze będzie to ktoś czytał ;)

Panowie , teoria ze zmianą adresów działa , zrobiłam trzy próby wszystko jest jak powinno .

Niestety pojawił się problem z którym mam spory kłopot , a wygląda to tak .
Będąc np. w układzie sterowania CLK0 , chcąc przejść do układu CKL1 , muszę zapamiętać jaką częstotliwość ustawiłem w CLK0 , a wracają ją odtworzyć .
Jaśli tego nie zrobię częstotliwość ostatnio ustawiona będzie przypisana do kolejnego wybranego wyjścia .
Tak numer muszę zrobić dla każdego z wyjść CLK0 , CLK1 , CLK2 .
Coś mi podpowiada , że będzie konieczna wymiana procka na 32kb i brutalne powielenie trzy razy części programu :( .
Awatar użytkownika
niveasoft
Posty: 1207
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Generator Si5351

Post autor: niveasoft » 07 mar 2023, 16:26

Nie wiem jak przełączasz te źródła i czy tam się róznią adresy na I2C, ale z powielaniem programu to przesadzasz :D
Wszędzie można dać tablice(3) i potem subowi przekazywać do których zmiennych(1-3) ma to zapisywać.
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: Generator Si5351

Post autor: Henryk » 09 mar 2023, 18:24

niveasoft pisze:
07 mar 2023, 16:26
Nie wiem jak przełączasz te źródła i czy tam się róznią adresy na I2C, ale z powielaniem programu to przesadzasz :D
Wszędzie można dać tablice(3) i potem subowi przekazywać do których zmiennych(1-3) ma to zapisywać.
Panie Bartku , dla takiego amatora jak ja są dozwolone wszystkie sposoby które prowadzą do celu :D
Dziękuje za podpowiedź z tablicami , zastosowałem w programie .

Teraz co namieszałem w programie :
Zakres regulowanej częstotliwości 10 kHz do 150 MHz , jest jeszcze jakiś chochlik w subie Calculate , po przekroczeniu częstotliwości 150 MHz spada do ok. 80 MHz .
Dodałem przycisk wyboru wyjścia CLK które chcemy regulować i pamięć ostatnio ustawionej częstotliwości dla tegoż wyjścia .
Zmieniłem zakres kroków częstotliwości do 10MHz .
Sub Displaylcd został całkowicie zmieniony , oryginał wyświetlał bzdury po przekroczeniu zakresu .
Program jaszcze wymaga porządkowania , może jakiegoś uproszczenia , ale działa tak jak tego chciałem ;)
  1.    '------------------------------------------------------------------
  2.   ' si5351a DDS Oscillator with I2C LCD display
  3.   ' Author: Andrew Woodfield ZL2PD
  4.   ' Date: March 2016
  5.   ' File Name: si85vfoxx.bas     (where xx is version number)
  6.   '
  7.   ' Released under the terms and conditions of the
  8.   ' Creative Commons Public License ("CCPL")
  9.   ' See creativecommons.org for details
  10.   '
  11.   ' Commercial use is prohibited without written permission
  12.   ' from the author
  13.   '
  14.   '------------------------------------------------------------------
  15.   ' Adapted from boardtest11.bas:
  16.   '
  17.   ' V01: initial code
  18.   '
  19.   '------------------------------------------------------------------
  20.   ' Credits:
  21.   '
  22.   ' I2C LCD code adapted from www.ne.jp/asahi/shared/o-family/ElecRoom/ElecMAIN.htm
  23.   ' si5351 code is adapted from OE1CGS and Jason Milldrum C code
  24.   '
  25.   ' Rotary encoder software is adapted from:
  26.   ' http://dl6gl.de/software/drehencoder-mit-bascom
  27.   '
  28.   '------------------------------------------------------------------
  29.   ' Program Description:
  30.  
  31.   ' An ATtiny85 is used to control a Silicon Labs si5351a 3-output
  32.   ' PLL/divider oscillator and I2C 16x2 alphanumeric LCD display with
  33.   ' rotary encoder and some pushbuttons.
  34.   '
  35.   '------------------------------------------------------------------
  36.   ' Compiler Directives (some fundamental hardware issues)
  37.   '$sim
  38.     $regfile = "m8def.dat"
  39.     $crystal = 8000000                                      '8MHz internal RC clock
  40.  
  41.     $hwstack = 128
  42.     $swstack = 64
  43.     $framesize = 128
  44.  
  45.   '-------------------------------------------------------------------------------
  46.     Config Lcdpin = Pin , Db4 = Pinc.2 , Db5 = Pinc.3 , Db6 = Pinc.4 , Db7 = Pinc.5 , E = Pinc.1 , Rs = Pinc.0
  47.     Config Lcd = 20 * 2
  48.  
  49.     Config Portb.1 = Output                                 'dds
  50.     Config Portb.2 = Output                                 'dds
  51.     Config Sda = Portb.1
  52.     Config Scl = Portb.2
  53.     Config Pinb.0 = Input
  54.     Config Pinb.3 = Input
  55.     Config Pinb.4 = Input
  56.     Config Pinb.5 = Input
  57.  
  58.     Set Portb.0                                             'set pullups
  59.     Set Portb.1
  60.     Set Portb.2
  61.     Set Portb.3
  62.     Set Portb.4
  63.     Set Portb.5
  64.     Stepkey Alias Pinb.0                                    'step key on encoder
  65.     Enca Alias Pinb.3                                       'rotary encoder input A
  66.     Encb Alias Pinb.4                                       'rotary encoder input B
  67.     Wybor Alias Pinb.5
  68.  
  69.     ' Declare Variables
  70.  
  71.     Dim Mhz As String * 2                                   'display subroutine variables
  72.     Dim Khz As String * 3
  73.     Dim Hz As String * 3
  74.     Dim Lastftext As String * 6                             'for display of freqb khz & Hz digits
  75.     Dim Freqtxt As String * 9
  76.     Dim Tekst1 As String * 9
  77.     Dim Mem_hz(3) As Dword                                  ' pamieć częstotliwości
  78.     Dim Fcnt As Byte
  79.     Dim Temp As Byte                                        'temporary variable used in sendfreq and sbarplot routines
  80.     Dim Temp1 As Byte                                       ' temp dla pamiec czestotliwosci
  81.     Dim Frequency As Dword                                  'four byte unsigned variable
  82.     Dim Gfreq As Dword                                      'calculates si5351 VFO output frequency
  83.     Dim Stepsize As Byte
  84.     Dim Delta As Dword
  85.     Dim Update As Bit                                       'bit is set (1) if a switch or encoder has changed
  86.     Dim Fvco As Dword                                       'si5351 vco frequency
  87.     Dim Outdivider As Dword                                 '4,6,8-900
  88.     Dim Rdivider As Byte                                    'Normally 1 unless freqeuncy<1MHz then 1,2,4,8,16,32,64 or 128 only
  89.     Dim Rbyte As Byte                                       'used as temp store before final data load to si5351
  90.     Dim Afactor As Dword
  91.     Dim Bfactor As Dword
  92.     Dim Fvalue As Single                                    'used to determine accuracy of fractional calculation
  93.     Dim Finteger As Dword
  94.  
  95.     Dim Ms0p1 As Dword                                      '18-bit MS0_P1 si5351 parameters for Output 0
  96.     Dim M0p11 As Byte At Ms0p1 Overlay                      'mirrored variables for dds calculation
  97.     Dim M0p12 As Byte At Ms0p1 + 1 Overlay
  98.     Dim M0p13 As Byte At Ms0p1 + 2 Overlay
  99.     Dim M0p14 As Byte At Ms0p1 + 3 Overlay                  'most significant byte for ms0p1
  100.  
  101.     'Note: MS0_P2 and MS0_P3 are hard-coded as 0 and 1 respectively so ignored during dimensioning
  102.                                                           'si5351 parameters for PLLA
  103.     Dim Msnap1 As Dword                                     '18-bit variable for MSNA_P1
  104.     Dim Ms11 As Byte At Msnap1 Overlay                      'mirrored variables for dds calculation
  105.     Dim Ms12 As Byte At Msnap1 + 1 Overlay
  106.     Dim Ms13 As Byte At Msnap1 + 2 Overlay
  107.     Dim Ms14 As Byte At Msnap1 + 3 Overlay                  'most significant byte
  108.  
  109.     Dim Msnap2 As Dword                                     '20-bit variable for MSNA_P2
  110.     Dim Ms21 As Byte At Msnap2 Overlay                      'mirrored variables for dds calculation
  111.     Dim Ms22 As Byte At Msnap2 + 1 Overlay
  112.     Dim Ms23 As Byte At Msnap2 + 2 Overlay
  113.     Dim Ms24 As Byte At Msnap2 + 3 Overlay                  'most significant byte
  114.  
  115.     Dim Msnap3 As Dword                                     '20-bit variable for MSNA_P3
  116.     Dim Ms31 As Byte At Msnap3 Overlay                      'mirrored variables for dds calculation
  117.     Dim Ms32 As Byte At Msnap3 + 1 Overlay
  118.     Dim Ms33 As Byte At Msnap3 + 2 Overlay
  119.     Dim Ms34 As Byte At Msnap3 + 3 Overlay                  'most significant byte
  120.  
  121.     Dim Regaddr As Byte , Regdata As Byte                   'for i2c calls
  122.     Dim Siaddr1 As Byte , Siaddr2 As Byte                   'for writing to si5351 CLK0 and CLK1
  123.  
  124.         '    Declare Constants
  125.     Const Startfreq = 10000                                 'xxx                          '40m starting frequency
  126.     Const Xtal = 25001000                                   ' xxx 25000000   '**NOTE: Value may be adjusted during alignment ***
  127.     Const Cfactor = 1048575                                 'xxx 1048575
  128.  
  129.     Frequency = Startfreq                                   'initialise frequency (20m for now)
  130.     Stepsize = 3
  131.     Delta = 1000
  132.     Temp1 = 0
  133.     Mem_hz(1) = 30000                                       ' Częstotliwości startowe pamięci
  134.     Mem_hz(2) = 20000
  135.     Mem_hz(3) = 10000
  136.     '     Declare Subroutines
  137.     Declare Sub Si5351init                                  'initialises si5351
  138.     Declare Sub Displaylcd                                  'displays current oscillator frequency
  139.     Declare Sub Calculate                                   'converts current VFO or BFO freq to data for si5351
  140.     Declare Sub Sendfreq                                    'sends VFO or BFO/CIO freq data to si5351 CLK0 or CLK1 respectively
  141.     Declare Sub Siout(sireg As Byte , Sidata As Byte)       'for i2c write to si5351
  142.     Declare Sub Plus
  143.     Declare Sub Minus
  144.     Declare Sub Wybor_clk
  145.  
  146.     '***************************** Program *****************************************
  147.  
  148.     '      initialise i2c here...
  149.     I2cinit
  150.     Waitms 50                                               'for i2c to settle and for lcd RC reset time
  151.     Cursor Off                                              'LCD cursor of
  152.     Cls
  153.     Update = 0                                              'clear the flags
  154.  
  155.     Si5351init                                              'initialises si5351
  156.     Gfreq = Frequency
  157.      Calculate
  158.     Siaddr1 = 26
  159.     Siaddr2 = 42
  160.      Sendfreq
  161.     Regaddr = 16
  162.     Regdata = 79
  163.      Call Siout(regaddr , Regdata)
  164.     Siaddr1 = 34
  165.     Siaddr2 = 50
  166.      Sendfreq
  167.     Siaddr1 = 34
  168.     Siaddr2 = 58
  169.      Sendfreq
  170.     Regaddr = 17
  171.     Regdata = 111
  172.       Call Siout(regaddr , Regdata)
  173.     Regaddr = 18
  174.     Regdata = 111
  175.       Call Siout(regaddr , Regdata)
  176.      Wybor_clk
  177.     Displaylcd                                              'then display frequency and status on lcd
  178.  
  179.  
  180.     Do                                                      'Start of main program
  181.  
  182.      If Stepkey = 0 Then
  183.           Incr Stepsize
  184.           Waitms 500                                        ' xxx
  185.        If Stepsize = 8 Then                                 'xxx
  186.           Stepsize = 1
  187.        End If
  188.        If Stepsize = 1 Then Delta = 5                       'Delta value sets tuning rates of 5, 100, 1000 and 10000 Hz/step
  189.        If Stepsize = 2 Then Delta = 100                     '24 steps/turn encoder gives about 120Hz, 2.4, 24 and 240kHz/turn
  190.        If Stepsize = 3 Then Delta = 1000
  191.        If Stepsize = 4 Then Delta = 10000
  192.        If Stepsize = 5 Then Delta = 100000                  'xxx
  193.        If Stepsize = 6 Then Delta = 1000000                 ' xxx
  194.        If Stepsize = 7 Then Delta = 10000000                ' xxx
  195.         Update = 1
  196.          Displaylcd                                         'to flag this change
  197.      End If
  198.  
  199.       Debounce Pinb.3 , 0 , Plus , Sub
  200.       Debounce Pinb.4 , 0 , Minus , Sub
  201.       Debounce Pinb.5 , 0 , Wybor_clk , Sub
  202.  
  203.      If Update = 1 Then                                     'encoder or buttons changed so update display and si5351
  204.                                                             'show new frequency and status
  205.        Gfreq = Frequency
  206.          Displaylcd                                         'gfreq holds value used for si5351
  207.          Calculate                                          'calculate new VFO data
  208.          Sendfreq                                           'and send it to the si5351
  209.          Call Siout(regaddr , Regdata)                      'enable CLK0, source=crystal, PLLA=integer mode, power level=8mA i.e. 0dB
  210.          Update = 0
  211.                                                             'and update flag
  212.      End If
  213.  
  214.     Loop                                                    'End of main program
  215.    End
  216.  
  217.     '**********************************************************************
  218.     'Subroutines...
  219.     '=====================================================================
  220.     Sub Plus
  221.       Frequency = Frequency + Delta
  222.       If Frequency > 150000000 Then
  223.       Frequency = 150000000
  224.       End If
  225.       Update = 1
  226.       Displaylcd
  227.     End Sub
  228.  
  229.     Sub Minus
  230.       Frequency = Frequency - Delta
  231.       If Frequency < 10000 Then
  232.       Frequency = 10000
  233.       End If
  234.       If Frequency > 150000000 Then
  235.       Frequency = 10000
  236.       End If
  237.       Update = 1
  238.       Displaylcd
  239.     End Sub
  240.     '==============================================================================================
  241.               ' wybór wyjścia clk0 , clk1 , clk2
  242.     '==============================================================================================
  243.       Sub Wybor_clk
  244.            Incr Temp1
  245.            Waitms 500
  246.            If Temp1 = 1 Then
  247.            Mem_hz(3) = Frequency                            'pamięć hz clk2
  248.            Frequency = Mem_hz(1)                            ' odczyt hz clk0
  249.            Siaddr1 = 26                                     'adres początkowy PLLA
  250.            Siaddr2 = 42                                     'adres początkowy CLK0
  251.            Update = 1
  252.         Elseif Temp1 = 2 Then
  253.            Mem_hz(1) = Frequency                            'pamięć hz clk0
  254.            Frequency = Mem_hz(2)                            ' odczyt hz clk1
  255.            Siaddr1 = 34                                     'adres początkowy PLLB
  256.            Siaddr2 = 50                                     'adres początkowy CLK1
  257.            Update = 1
  258.         Elseif Temp1 = 3 Then
  259.            Mem_hz(2) = Frequency                            'pamięć hz clk1
  260.            Frequency = Mem_hz(3)                            ' odczyt hz clk2
  261.            Siaddr1 = 34                                     'adres początkowy PLLB
  262.            Siaddr2 = 58                                     'adres początkowy CLK2
  263.            Update = 1
  264.           End If
  265.           If Temp1 = 4 Then
  266.           Temp1 = 0
  267.           End If
  268.       End Sub
  269.  
  270.     '========================================================================
  271.  
  272.     '========================================================================
  273.     Sub Displaylcd
  274.          Tekst1 = "000000000"
  275.        Freqtxt = Str(frequency)
  276.        Fcnt = Len(freqtxt)
  277.      If Fcnt = 1 Then
  278.         Mid(tekst1 , 9 , Fcnt) = Freqtxt                    '9
  279.            Elseif Fcnt = 2 Then
  280.         Mid(tekst1 , 8 , Fcnt) = Freqtxt                    '8
  281.            Elseif Fcnt = 3 Then
  282.         Mid(tekst1 , 7 , Fcnt) = Freqtxt                    '7
  283.            Elseif Fcnt = 4 Then
  284.         Mid(tekst1 , 6 , Fcnt) = Freqtxt                    '6
  285.            Elseif Fcnt = 5 Then
  286.         Mid(tekst1 , 5 , Fcnt) = Freqtxt                    '5
  287.            Elseif Fcnt = 6 Then
  288.         Mid(tekst1 , 4 , Fcnt) = Freqtxt                    '5
  289.            Elseif Fcnt = 7 Then
  290.         Mid(tekst1 , 3 , Fcnt) = Freqtxt                    '3
  291.            Elseif Fcnt = 8 Then
  292.         Mid(tekst1 , 2 , Fcnt) = Freqtxt                    '2
  293.            Elseif Fcnt = 9 Then
  294.         Mid(tekst1 , 1 , Fcnt) = Freqtxt                    '1
  295.      End If
  296.  
  297.         If Frequency < 1000000 Then
  298.  
  299.           Locate 1 , 1
  300.            Lcd "     "
  301.          Lcd Mid(tekst1 , 4 , 3)
  302.           Lcd "."
  303.          Lcd Mid(tekst1 , 7 , 3)
  304.           Lcd " kHz"
  305.          End If
  306.  
  307.        If Frequency => 1000000 Then
  308.          Locate 1 , 2
  309.          Lcd Mid(tekst1 , 1 , 3)
  310.           Lcd "."
  311.          Lcd Mid(tekst1 , 4 , 3)
  312.            Lcd "."
  313.          Lcd Mid(tekst1 , 7 , 3)
  314.           Lcd " MHz"
  315.         End If
  316.       Locate 2 , 1                                          'second line
  317.      Select Case Stepsize
  318.        Case 1 : Lcd " 5 Hz  "
  319.        Case 2 : Lcd " 100 Hz"
  320.        Case 3 : Lcd " 1 kHz "
  321.        Case 4 : Lcd " 10 kHz"
  322.        Case 5 : Lcd " 100kHz "
  323.        Case 6 : Lcd " 1 MHz "
  324.        Case 7 : Lcd " 10 MHz "
  325.      End Select
  326.  
  327.         Locate 2 , 10                                       'second line
  328.      Select Case Temp1
  329.        Case 1 : Lcd "CLK0"
  330.        Case 2 : Lcd "CLK1"
  331.        Case 3 : Lcd "CLK2"
  332.  
  333.      End Select
  334.  
  335.     End Sub
  336.  
  337.     '**********************************************************************
  338.     ' subroutine to initialise the si5351 chip via I2C
  339.     '**********************************************************************
  340.  
  341.     Sub Si5351init
  342.  
  343.         Regaddr = 183
  344.         Regdata = 192
  345.      Call Siout(regaddr , Regdata)                          'set xtal load cap to 10pF
  346.         Regaddr = 3
  347.         Regdata = 0
  348.      Call Siout(regaddr , Regdata)                          'enable all outputs
  349.         Regaddr = 15
  350.         Regdata = 0
  351.      Call Siout(regaddr , Regdata)                          'select xtal as PLL input source
  352.         Regaddr = 16
  353.         Regdata = 15                                        'PLLA is source, 8mA output
  354.      Call Siout(regaddr , Regdata)                          'configure clock 0 control register
  355.       Waitms 10                                             'wait 10ms just in case
  356.  
  357.     End Sub
  358.  
  359.     '********************************************************************************
  360.     ' calculate data bytes for current VFO or BFO frequency to send to si5351a CLK0/1
  361.     '********************************************************************************
  362.     Sub Calculate
  363.  
  364.         Rdivider = 1                                        'initialise r
  365.         Outdivider = 900000000 \ Gfreq                      'and outdivider
  366.       While Outdivider > 900                                '900
  367.         Rdivider = 2 * Rdivider
  368.         Outdivider = Outdivider \ 2
  369.       Wend
  370.         Fvco = Outdivider Mod 2                             'check outdivider is an even number
  371.  
  372.       If Fvco <> 0 Then Outdivider = Outdivider - 1         'using fvco as a temporary register
  373.         Fvco = Outdivider * Rdivider
  374.         Fvco = Fvco * Gfreq                                 'determine PLL frequency
  375.      Select Case Rdivider                                   'determine value of R44 bits [6:4]
  376.         Case 1 : Rbyte = 0                                  '000 0000
  377.         Case 2 : Rbyte = 16                                 '001 0000
  378.         Case 4 : Rbyte = 32                                 '010 0000
  379.         Case 8 : Rbyte = 48                                 '011 0000
  380.         Case 16 : Rbyte = 64                                '100 0000
  381.         Case 32 : Rbyte = 80                                '101 0000
  382.         Case 64 : Rbyte = 96                                '110 0000
  383.         Case 128 : Rbyte = 112                              '111 0000
  384.      End Select
  385.        Afactor = Fvco \ Xtal
  386.        Fvalue = Afactor * Xtal                              'fvalue = fvco -afactor * xtal
  387.        Fvalue = Fvco - Fvalue                               'a+b/c
  388.        Fvalue = Fvalue * Cfactor
  389.        Fvalue = Fvalue \ Xtal
  390.        Bfactor = Fvalue
  391.        Ms0p1 = 128 * Outdivider
  392.        Ms0p1 = Ms0p1 - 512
  393.        Fvalue = 128 * Bfactor
  394.        Fvalue = Fvalue \ Cfactor
  395.        Finteger = Fvalue
  396.        Msnap1 = 128 * Afactor
  397.        Msnap1 = Msnap1 + Finteger                           'finteger used instead of fvalue for variable matching
  398.        Msnap1 = Msnap1 - 512
  399.        Msnap3 = Finteger * Cfactor                          'using msnap3 as temp result buffer
  400.        Msnap2 = 128 * Bfactor
  401.        Msnap2 = Msnap2 - Msnap3
  402.        Msnap3 = Cfactor
  403.      'calculations are complete so now build and send the required output data bytes by calling sendfreq  (About 20 bytes sent per frequency)
  404.     End Sub
  405.  
  406.     '**********************************************************************
  407.     ' send converted freq data to si5351 for CLK0 output
  408.     '**********************************************************************
  409.     Sub Sendfreq
  410.  
  411.           Regaddr = Siaddr1
  412.      Call Siout(regaddr , Ms32)                             'R26=msnap3[15:8]
  413.      Incr Regaddr
  414.      Call Siout(regaddr , Ms31)                             'R27=msnap3[7:0]
  415.      Incr Regaddr
  416.      Call Siout(regaddr , Ms13)                             'R28=msnap1[17:16] in R28[1:0] with R28[7:2]=0
  417.      Incr Regaddr
  418.      Call Siout(regaddr , Ms12)                             'R29=msnap1[15:8]
  419.      Incr Regaddr
  420.      Call Siout(regaddr , Ms11)                             'R30=msnap1[7:0]
  421.           Temp = Ms33                                       'temp[3:0]=msnap3[19:16]
  422.      Swap Temp                                              'temp[7:4]=msnap3[19:16]
  423.           Temp = Temp Or Ms23                               'temp[7:4]=msnap3[19:16] and temp[3:0]=msnap2[19:16]
  424.      Incr Regaddr
  425.      Call Siout(regaddr , Temp)                             'R31=(msnap3[19:16],msnap2[19:16])
  426.      Incr Regaddr
  427.      Call Siout(regaddr , Ms22)                             'R32=msnap2[15:8]
  428.      Incr Regaddr
  429.      Call Siout(regaddr , Ms21)                             'R33=msnap2[7:0]
  430.  
  431.  
  432.           Regaddr = Siaddr2
  433.           Regdata = 0
  434.      Call Siout(regaddr , Regdata)                          'R42=MS0_P3[15:8]
  435.      Incr Regaddr
  436.           Regdata = 1
  437.      Call Siout(regaddr , Regdata)                          'R43=MS0_P3[7:0]
  438.           Temp = Rbyte
  439.           Temp = Temp Or M0p13
  440.      Incr Regaddr
  441.      Call Siout(regaddr , Temp)                             'R44=(0,R[7:4],MS0_P1[17:16])
  442.      Incr Regaddr
  443.      Call Siout(regaddr , M0p12)                            'R45=MS0_P1[15:8]
  444.      Incr Regaddr
  445.      Call Siout(regaddr , M0p11)                            'R46=MS0_P1[7:0]
  446.      Incr Regaddr
  447.           Regdata = 0
  448.      Call Siout(regaddr , Regdata)                          'R47=(MS0_P3[19:16],MS0_P2[19:16]) and both are always 0
  449.      Incr Regaddr
  450.           Regdata = 0
  451.      Call Siout(regaddr , Regdata)                          'R48=MS0_P2[15:8]=0 always
  452.      Incr Regaddr
  453.           Regdata = 0
  454.      Call Siout(regaddr , Regdata)                          'R49=MS0_P2[7:0]=0 always
  455.  
  456.  
  457.     End Sub
  458.  
  459.     '**********************************************************************
  460.     ' i2c transmission to si5351
  461.     '**********************************************************************
  462.     Sub Siout(sireg As Byte , Sidata As Byte)
  463.      'subroutine sends databyte to register_nbr at i2c address 192 (si5351 register read is from address 194)
  464.      'Write a single byte (slave address 192, register sireg, value sibyte)
  465.      I2cstart
  466.      I2cwbyte 192                                           'i2c address of si5351a
  467.      Waitus 1                                               'suggested delay from forum
  468.      I2cwbyte Sireg
  469.      Waitus 1
  470.      I2cwbyte Sidata
  471.      Waitus 1
  472.      I2cstop
  473.  
  474.     End Sub
Teraz spadam dłubać w moim radyjku i testować si5351 .
ODPOWIEDZ