;========================================================================================== ; Fast Huff Puff VFO Stabiliser ; ; (c) Cumbria Designs ; ; This software is provided free of charge for non commercial use. The software is provided ; without warranty or licence and no liability is accepted by the author or Cumbria Designs ; for any loss, injury, mishap, inconvenience or misdemeanor arising from the use of the ; software in whole or part. In using this software and the code compiled from it, you agree ; to these terms. ; ; We ask that in return for downloading and/or using this software in any way, you make a ; donation to a charity of your choice. How much is up to you! ; ; Ron Taylor, Cumbria Designs ; ;========================================================================================== ; ; Revision History ; ; December 2006 Version 1.0 ; ; ; ; ;========================================================================================== ; ; Pin Out ; ; PORT A ; ; Not Used ; ; ; PORT B ; ; 0 Output to Integrator ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 Input ; 7 ; ;========================================================================================== list p=16F88 ; list directive to define processor #include ; processor specific variable definitions ;========================================================================== ; ; Configuration Bits ; ;========================================================================== ;_CONFIG1 EQU H'2007' ;_CONFIG2 EQU H'2008' ;Configuration Byte 1 Options ;_CP_ALL EQU H'1FFF' ;_CP_OFF EQU H'3FFF' ;_CCP1_RB0 EQU H'3FFF' ;_CCP1_RB3 EQU H'2FFF' ;_DEBUG_OFF EQU H'3FFF' ;_DEBUG_ON EQU H'37FF' ;_WRT_PROTECT_OFF EQU H'3FFF' ;No program memory write protection ;_WRT_PROTECT_256 EQU H'3DFF' ;First 256 program memory protected ;_WRT_PROTECT_2048 EQU H'3BFF' ;First 2048 program memory protected ;_WRT_PROTECT_ALL EQU H'39FF' ;All of program memory protected ;_CPD_ON EQU H'3EFF' ;_CPD_OFF EQU H'3FFF' ;_LVP_ON EQU H'3FFF' ;_LVP_OFF EQU H'3F7F' ;_BODEN_ON EQU H'3FFF' ;_BODEN_OFF EQU H'3FBF' ;_MCLR_ON EQU H'3FFF' ;_MCLR_OFF EQU H'3FDF' ;_PWRTE_OFF EQU H'3FFF' ;_PWRTE_ON EQU H'3FF7' ;_WDT_ON EQU H'3FFF' ;_WDT_OFF EQU H'3FFB' ;_EXTRC_CLKOUT EQU H'3FFF' ;_EXTRC_IO EQU H'3FFE' ;_INTRC_CLKOUT EQU H'3FFD' ;_INTRC_IO EQU H'3FFC' ;_EXTCLK EQU H'3FEF' ;_HS_OSC EQU H'3FEE' ;_XT_OSC EQU H'3FED' ;_LP_OSC EQU H'3FEC' ;Configuration Byte 2 Options ;_IESO_ON EQU H'3FFF' ;_IESO_OFF EQU H'3FFD' ;_FCMEN_ON EQU H'3FFF' ;_FCMEN_OFF EQU H'3FFE' ;Program Configuration Register 1 __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC ;Program Configuration Register 2 __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;========================================================================================== ; ; File Register Definitions ; ; ;========================================================================================== CBLOCK 0x20 ; Start of Program Variables Memory ; temp ; Used in detect routine delay ; Delay counter SR8 ; 2000 Bit Shift Register SR16 ; SR24 ; Digit in register name represents higher order bit number of register SR32 ; Registers must occupy consective memory addresses for the "shift through SR40 ; carry bit" action to function SR48 SR56 SR64 SR72 SR80 SR88 SR96 SR104 SR112 SR120 SR128 SR136 SR144 SR152 SR160 SR168 SR176 SR184 SR192 SR200 SR208 SR216 SR224 SR232 SR240 SR248 SR256 SR264 SR272 SR280 SR288 SR296 SR304 SR312 SR320 SR328 SR336 SR344 SR352 SR360 SR368 SR376 SR384 SR392 SR400 SR408 SR416 SR424 SR432 SR440 SR448 SR456 SR464 SR472 SR480 SR488 SR496 SR504 SR512 SR520 SR528 SR536 SR544 SR552 SR560 SR568 SR576 SR584 SR592 SR600 SR608 SR616 SR624 SR632 SR640 SR648 SR656 SR664 SR672 SR680 SR688 SR696 SR704 SR712 SR720 SR728 SR736 SR744 SR752 ENDC CBLOCK 0xA0 ; Map into next Memory Block SR760 SR768 SR776 SR784 SR792 SR800 SR808 SR816 SR824 SR832 SR840 SR848 SR856 SR864 SR872 SR880 SR888 SR896 SR904 SR912 SR920 SR928 SR936 SR944 SR952 SR960 SR968 SR976 SR984 SR992 SR1000 SR1008 SR1016 SR1024 SR1032 SR1040 SR1048 SR1056 SR1064 SR1072 SR1080 SR1088 SR1096 SR1104 SR1112 SR1120 SR1128 SR1136 SR1144 SR1152 SR1160 SR1168 SR1176 SR1184 SR1192 SR1200 SR1208 SR1216 SR1224 SR1232 SR1240 SR1248 SR1256 SR1264 SR1272 SR1280 SR1288 SR1296 SR1304 SR1312 SR1320 SR1328 SR1336 SR1344 SR1352 SR1360 SR1368 SR1376 SR1384 ENDC CBLOCK 0x110 ; Map into next Memory Block SR1392 SR1400 SR1408 SR1416 SR1424 SR1432 SR1440 SR1448 SR1456 SR1464 SR1472 SR1480 SR1488 SR1496 SR1504 SR1512 SR1520 SR1528 SR1536 SR1544 SR1552 SR1560 SR1568 SR1576 SR1584 SR1592 SR1600 SR1608 SR1616 SR1624 SR1632 SR1640 SR1648 SR1656 SR1664 SR1672 SR1680 SR1688 SR1696 SR1704 SR1712 SR1720 SR1728 SR1736 SR1744 SR1752 SR1760 SR1768 SR1776 SR1784 SR1792 SR1800 SR1808 SR1816 SR1824 SR1832 SR1840 SR1848 SR1856 SR1864 SR1872 SR1880 SR1888 SR1896 SR1904 SR1912 SR1920 SR1928 SR1936 SR1944 SR1952 SR1960 SR1968 SR1976 SR1984 SR1992 SR2000 SR2008 ENDC ;========================================================================================== ; ; MACRO AREA ; ;========================================================================================== ; Bank Select Macros to simplify bank changes Bank0 MACRO bcf STATUS,RP0 ; Select Bank 0 bcf STATUS,RP1 ; ENDM Bank1 MACRO bsf STATUS,RP0 ; Select Bank 1 bcf STATUS,RP1 ; ENDM Bank2 MACRO bcf STATUS,RP0 ; Select Bank 2 bsf STATUS,RP1 ; ENDM Bank3 MACRO bsf STATUS,RP0 ; Select Bank 3 bsf STATUS,RP1 ; ENDM ;================================================================================================ ; ; Start of Program ; ; Initialisation of peripherals and ports. ; ;================================================================================================ ORG 0x0000 goto Start Start ; Initialise ports, modules and variables clrf INTCON ; No interrupts for now Bank1 movlw 0x00 ; Digital I/O on PORTS A&B movwf ANSEL bcf OPTION_REG,NOT_RBPU ; No weak pull ups movlw b'11111110' ; PORT B bits 0 and 2 set to outputs, 6 set to input for VFO movwf TRISB Bank0 movlw b'00000111' ; Set TMR1ON, TMR1CS and T1SYNC movwf T1CON ; Timer 1 ON, External Clock, Async Operation, Prescale=1 ;================================================================================================ ; ; Main ; ; Cyclic loop from which all routines are called. Instruction times are given in machines cycles. ; These are used to form the overall cycle time and hence sampling time. ; ; The program is arranged as a main routine with subroutine calls. This architecture makes the ; program structure easy to follow as the expense of a small amount of additional execution time ; associated with the subroutine calls. ; ;================================================================================================ Main ; Endless loop bsf SR8,0 ; 1 Set input to shift register btfss TMR1L,0 ; 2 Test least significant byte of running count bcf SR8,0 ; 3 Input sample was zero, clear shift register input bit call Detect ; 17 (2+12) call Shift ; 279(2+260) call Sample_Delay ; 281+T (2+T) goto Main ; 283+T Back round again ;================================================================================================ ; ; Detect Routine ; ; The Detect routine compares the input state of the shift register with the output state by ; an XOR function. Unlike a traditional phase detector the XOR will always produce an output ; irrespective of whether one is needed or not. When an "unecessary" decision is made it is ; corrected on the next sample. The very long time constant of the integrator averages out ; the relatively high frequency changes of the XOR to produce a clean, slow changing control ; voltage which is used to drive the drift correction varactor. ; ;================================================================================================ Detect ; Generate Correction Signal movf SR8,w ; 1 Get input to shift register andlw 0x01 ; 2 Mask tap 1 ,the shift register input movwf temp ; 3 Save result Bank2 ; 5 Point to memory bank holding SR2008 movf SR2008,w ; 6 Move contents of register into w Bank0 ; 8 Back to Bank 0 xorwf temp,w ; 9 XOR input and output and save result in temp movwf PORTB ; 10 Put output onto PORTB pin 0 return ; 12 Back to calling routine ;================================================================================================ ; ; Delay Routine ; ; The main process times are padded out with an additional delay to produce the required ; sampling rate and hence lock point spacing and correction signal refresh rate. The total ; cyclical process time is chosen such that the total time taken for a bit to traverse the ; shift register and undergo detection produces a gate period that will give the required ; frequency resolution (lock point spacing). ; ; For a 20MHz clock the machine cycle time is 200nSec, the sampling period is the sum of ; all of the process times (Ptot) plus the delay duration. The Sampling Delay period required ; to pad out the process time for a given sampling rate is calculated as follows; ; ; For a 10kHz sampling rate the required clock period is 100uSec ; ; Lock Point Spacing = 2fs/tap number, therefore 2000 shift register taps required ; ; Ptot = Main duration + Shift duration + Detect duration ; = 11*200nSec + 260*200nSEc + 12*200nSec ; = 56600nSec (283 machine cycles) ; Clock period = Ptot + Delay ; Delay = Clock Rate - Ptot ; Delay = 100uSec - 283*200nSec ; Delay = 43400nSec ; Delay = 217 Machine Cycles ; ; Therefore, the additional delay to produce the required sampling rate is 217 machine cycles ; ;================================================================================================ Sample_Delay ; 217 machine cycle delay movlw 0x15 ; 1 Load Outer counter with 21d movwf delay ; 2 Delay1 nop ; 1 10 Machine Cycle loop nop ; 2 x21 = 210 + 2 from initialisation -1 from exit nop ; 3 = 211 nop ; 4 nop ; 5 nop ; 6 nop ; 7 decfsz delay,f ; 8 211 goto Delay1 ; 10 nop ; 212 nop ; 213 nop ; 214 Pad out with Machine cycles to make up to 217 nop ; 215 return ; 217 ;================================================================================================ ; ; Shift Register ; ; The 2000 tap shift register is formed in General Purpose Memory using 251 registers arranged ; in consecutive memory addresses. Where a memory bank change is required, the bank change macros ; are called ro point to the next bank. The timing associated with these macro comands must be ; accounted for in the total shift regsiter "end to end" time. For programming convenience the ; input and output sample points are taken from bit 0 of the first register (SR8) and the last ; register (SR2008). The rlf command shifts the content of a register palcing any overflow into ; the STATUS register C (Carry) flag. The next register to be shifted receives the Carry flag flag ; bit as it's input. ; ;================================================================================================ Shift ; Move shift register contents left one bit through carry flag bcf STATUS,C ; 1 ; Clear Carry bit to prevent any unwanted carry-in rlf SR8,f ; 2 ; Start of 2000 Bit Shift Register rlf SR16,f ; 3 ; rlf SR24,f ; 4 ; Digit in register name represents higher order bit number of register rlf SR32,f ; 5 ; Registers must occupy consective memory addresses for the "shift through rlf SR40,f ; carry bit" action to function rlf SR48,f rlf SR56,f rlf SR64,f rlf SR72,f rlf SR80,f rlf SR88,f rlf SR96,f rlf SR104,f rlf SR112,f rlf SR120,f rlf SR128,f rlf SR136,f rlf SR144,f rlf SR152,f rlf SR160,f rlf SR168,f rlf SR176,f rlf SR184,f rlf SR192,f rlf SR200,f rlf SR208,f rlf SR216,f rlf SR224,f rlf SR232,f rlf SR240,f rlf SR248,f rlf SR256,f rlf SR264,f rlf SR272,f rlf SR280,f rlf SR288,f rlf SR296,f rlf SR304,f rlf SR312,f rlf SR320,f rlf SR328,f rlf SR336,f rlf SR344,f rlf SR352,f rlf SR360,f rlf SR368,f rlf SR376,f rlf SR384,f rlf SR392,f rlf SR400,f rlf SR408,f rlf SR416,f rlf SR424,f rlf SR432,f rlf SR440,f rlf SR448,f rlf SR456,f rlf SR464,f rlf SR472,f rlf SR480,f rlf SR488,f rlf SR496,f rlf SR504,f rlf SR512,f rlf SR520,f rlf SR528,f rlf SR536,f rlf SR544,f rlf SR552,f rlf SR560,f rlf SR568,f rlf SR576,f rlf SR584,f rlf SR592,f rlf SR600,f rlf SR608,f rlf SR616,f rlf SR624,f rlf SR632,f rlf SR640,f rlf SR648,f rlf SR656,f rlf SR664,f rlf SR672,f rlf SR680,f rlf SR688,f rlf SR696,f rlf SR704,f rlf SR712,f rlf SR720,f rlf SR728,f rlf SR736,f rlf SR744,f rlf SR752,f Bank1 ; Change to Bank 1 rlf SR760,f rlf SR768,f rlf SR776,f rlf SR784,f rlf SR792,f rlf SR800,f rlf SR808,f rlf SR816,f rlf SR824,f rlf SR832,f rlf SR840,f rlf SR848,f rlf SR856,f rlf SR864,f rlf SR872,f rlf SR880,f rlf SR888,f rlf SR896,f rlf SR904,f rlf SR912,f rlf SR920,f rlf SR928,f rlf SR936,f rlf SR944,f rlf SR952,f rlf SR960,f rlf SR968,f rlf SR976,f rlf SR984,f rlf SR992,f rlf SR1000,f rlf SR1008,f rlf SR1016,f rlf SR1024,f rlf SR1032,f rlf SR1040,f rlf SR1048,f rlf SR1056,f rlf SR1064,f rlf SR1072,f rlf SR1080,f rlf SR1088,f rlf SR1096,f rlf SR1104,f rlf SR1112,f rlf SR1120,f rlf SR1128,f rlf SR1136,f rlf SR1144,f rlf SR1152,f rlf SR1160,f rlf SR1168,f rlf SR1176,f rlf SR1184,f rlf SR1192,f rlf SR1200,f rlf SR1208,f rlf SR1216,f rlf SR1224,f rlf SR1232,f rlf SR1240,f rlf SR1248,f rlf SR1256,f rlf SR1264,f rlf SR1272,f rlf SR1280,f rlf SR1288,f rlf SR1296,f rlf SR1304,f rlf SR1312,f rlf SR1320,f rlf SR1328,f rlf SR1336,f rlf SR1344,f rlf SR1352,f rlf SR1360,f rlf SR1368,f rlf SR1376,f rlf SR1384,f Bank2 ; Change to Bank 2 rlf SR1392,f rlf SR1400,f rlf SR1408,f rlf SR1416,f rlf SR1424,f rlf SR1432,f rlf SR1440,f rlf SR1448,f rlf SR1456,f rlf SR1464,f rlf SR1472,f rlf SR1480,f rlf SR1488,f rlf SR1496,f rlf SR1504,f rlf SR1512,f rlf SR1520,f rlf SR1528,f rlf SR1536,f rlf SR1544,f rlf SR1552,f rlf SR1560,f rlf SR1568,f rlf SR1576,f rlf SR1584,f rlf SR1592,f rlf SR1600,f rlf SR1608,f rlf SR1616,f rlf SR1624,f rlf SR1632,f rlf SR1640,f rlf SR1648,f rlf SR1656,f rlf SR1664,f rlf SR1672,f rlf SR1680,f rlf SR1688,f rlf SR1696,f rlf SR1704,f rlf SR1712,f rlf SR1720,f rlf SR1728,f rlf SR1736,f rlf SR1744,f rlf SR1752,f rlf SR1760,f rlf SR1768,f rlf SR1776,f rlf SR1784,f rlf SR1792,f rlf SR1800,f rlf SR1808,f rlf SR1816,f rlf SR1824,f rlf SR1832,f rlf SR1840,f rlf SR1848,f rlf SR1856,f rlf SR1864,f rlf SR1872,f rlf SR1880,f rlf SR1888,f rlf SR1896,f rlf SR1904,f rlf SR1912,f rlf SR1920,f rlf SR1928,f rlf SR1936,f rlf SR1944,f rlf SR1952,f rlf SR1960,f rlf SR1968,f rlf SR1976,f rlf SR1984,f rlf SR1992,f rlf SR2000,f ; 255 rlf SR2008,f ; 256 Bank0 ; 258 Rest to Bank 0 return ; 260 Back to calling routine END