;This code allows for the frequency of a Global Communications HSU-10 Upconvertor to be changed from 1Ghz to what you need
;This code is for the PIC16F84 chip from Microchip communicating with the LMX2325 PLL Oscillator
;While this code worked fine for changing the frequency to 1.2Ghz, there is no warranty that this code will work for you
;Written by VK5BD - Bevan Daniel
;The formula for determining the Oscillator frequency is given by
;Fosc = (( P x B ) + A) / Fref x R
;Where P is the Prescaler (in this case is 32)
; A is the 7 bit Swallow Counter (not my term, from the datasheet
; B is the 11 bit Programmable Counter
; Fref is the Reference Frequency which is 10Mhz for the HSU-10
; R is the 14 bit Reference Counter (20 is used in this code)
; Fref / R = 10Mhz / 20 = 0.5Mhz
;
;To determine the vaules for A and B in this example
; (( P x B ) + A ) = Fosc / 0.5 = 1200Mhz / 0.5 = 2400
; B = Integer of ( 2400 / 32) = 75
; A = 2400 - ( 32 x B ) = 2400 - ( 32 x 75 ) = 2400 - 2400 = 0
;
;The structure of the data sent to the LMX2325 is 18 Bits plus 1 control bit, giving a total of 19 bits long per message
;The Control bit identifies which counters the data will be loaded into, with control bit set data fills the R counter and Prescaler select,
;else the data goes into the Swallow and Programmable counters
;
;Prescaler and Divider Counter (R) Structure plus Control bit
;0001000000001001001
;Which is 000 (padding bits), 1 (Prescaler), 00000000100100 (Divider Counter R = 20), and 1 (Control bit set)
;To make this suitable Byte length we will use 3 Bytes or 24 bits and pad the structure with 5 appended to the end giving
;000100000000100100100000
;which then is broken into each byte (8 bits)
;00010000 or 0x10
;00001001 or 0x05
;00100000 or 0x20
;
;Programable counter (B) and Swallow counter (A) plus Control bit
;0000100101100000000
;Which is 00010001011 (Programable Counter B = 75), 0000000 (Swallow counter A = 0) and 0 (Control bit cleared)
;Then append the extra 5 Bits
;000010010110000000000000
;To make this suitable Byte length we will use 3 Bytes or 24 bits and pad the structure with 5 appended to the end giving
;000010010110000000000000
;00001001 or 0x09
;01100000 or 0x60
;00000000 or 0x00
;
;Hopefully that is as clear as mud
well I do hope I have explained it well enough that you can modify the code to suit your own frequency
;Good luck and 73
;VK5BD
#include <p16f84.inc>
; CONFIG
; __config 0x3FF9
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _CP_OFF
iDelay equ 0x10
iLoop equ 0x11
iBitsOut equ 0x12
iByteBits equ 0x13
iByte equ 0x14
;----------------------------------------------------------------------
org 0x000
start movlw 0x00 ; load W with 0x00 make port B output (p. 45)
BCF STATUS, 5 ; Select Bank 0
CLRF PORTA ; Initialize PORTA by clearing output data latches
BSF STATUS, 5 ; Select Bank 1
MOVLW 0x18 ; Value used to initialize data direction
MOVWF TRISA ; Set RA<2:0> as output, RA2 is LE, RA1 is Clock, RA0 is Data
bcf STATUS, 5 ; Select Bank 0
bsf PORTA,2 ; Raise the LE signal to High
call DELAY
call DELAY
bcf PORTA,2 ; Set LE low to indicate data is about to be sent to the LMX2325
movlw 0x13 ; Set the maximum number of bits to 19 for this message
movwf iBitsOut ; Store the bit count
movlw 0x10 ; Define the Bytes that set the Prescaler and Divider Counter in the LMX2325
movwf iByte ; Store the Byte
Call ClockOutByte ; Send out Byte
movlw 0x05
movwf iByte
Call ClockOutByte
movlw 0x20
movwf iByte
Call ClockOutByte
Call DELAY
bsf PORTA,2 ; Raise the LE signal to High to trigger loading of the data from buffer
call DELAY
bcf PORTA,2 ; Set LE low to recieve data into the Buffer
movlw 0x13 ; Reset maximum number of bits
movwf iBitsOut
movlw 0x09 ; Define the Byte to set the Programmable and Swallow counters in the LMX2325
movwf iByte
Call ClockOutByte
movlw 0x60
movwf iByte
Call ClockOutByte
movlw 0x00
movwf iByte
Call ClockOutByte
call DELAY
bsf PORTA,2 ; Set LE high to Load counters from buffer
Circle: goto Circle ; Sending data is done, now just sit here doing nothing
ClockOutByte: movlw 0x08 ; Set number of bits per Byte
movwf iByteBits
ClockOutBits: bcf STATUS,0 ; Clear the Carry Flag (This may not be neccessary but it worked so I have left it in)
rlf iByte , 1 ; Rotate the Byte contents into the Carry Flag
btfsc STATUS,0 ; If Carry flag is clear, skip the next line
bsf PORTA, 0 ; Set the Data pin high as the Carry must have been high
btfss STATUS,0 ; If Carry flag is Set, skip the next line
bcf PORTA,0 ; Set the Data pin low and the Carry flag is clear
NOP ; waste a little time
bsf PORTA,1 ; Set the Clock pin high
NOP ; waste another clock cycle
NOP ; and another just to shape the clock pulse
bcf PORTA,1 ; Set the Clock pin low
decfsz iBitsOut, 1 ; Check how many bits have been sent in this message
goto NotDone ; not enough bits sent yet
return ; 19 bits have been sent, therefore end of message
NotDone: decfsz iByteBits,1 ; have all the bits of the byte been sent
goto ClockOutBits ; more bits of the byte still to be sent
return ; The byte has been sent, go back and get the next
DELAY: movlw 0x02 ; Time Delay Subroutine (Thought was going to need to waste a fair bit of time but proved not to be the case)
movwf iDelay ; Outer Loop set to 2
PAUSE: movlw 0x01
movwf iLoop ; Inner Loop set to 1
DLOOP: decfsz iLoop,1 ; Count down Inner Loop
goto DLOOP ; Still in the Inner Loop?
decfsz iDelay,1 ; Count down Outer Loop
goto PAUSE ; Still in the Outer Loop?
return ; Time's up!
end