;========================================================================================== ; F628HPL.ASM Fast Huff Puff VFO Stabiliser using looped code on 16F628. ;========================================================================================= ; ; Fast H&P de G3DXZ. ; ; The G7IXH shift register control logic for the H&P stabiliser was implemented in software ; by G4GXO, "Cumbria Designs". This software used TMR1 to divide down the incoming rf ; frequency for comparison with a crystal locked software loop produced by counting ; machine instructions. ; This version uses an alternative approach to timing. TMR0+prescaler is used to define ; the sample period and triggers an interupt routine to perform the shift and control ; function. A 32 byte (256 bit) SR is used. ; Running with a 5.24288 MHz crystal, an exact and constant 10 Hz step results. ; Initially written for 16F84, this code would not work on F628 due to what seems to ; be a difference in the XOR instruction. The 84 code tested OK on the 628 simulator ; (MPLAB SIM), but would not work on the PIC itself. Eventually, a written XOR ; function was used and cured the problem !!! The G4GXO code would also work as it does not ; use the Carry bit. ; The step frequency is Xtal Freq./4x TMR0+PreSc x SR Bits. Doubling the xtal freq. ; will double the step with no software changes. Also, the crystal frequency can be ; reduced below the 5 MHz value used here by reducing the counter division ratio. 256 ; bits of SR produces immediate lockup an the associated CMOS based vfo. ; The rf input to the PIC was taken directly from the vfo output. ; ; This implementation uses only 2 PORTA bits. PORTB flag functions are only for test purposes. ; As this leaves 74% processor time idle and all PORTB and two PORTA bits available there ; there is plenty oportunity for other functions to be added. ; When tested against the F628 using in-line code, no performance difference could be detected. ; However, the in-line code did leave 90% of processor time unused, which might be an ; advantage if other functions are included. ; ; With this configuration:- Xtal = 5.24288 MHz ; sample rate = 2560/sec ; step = 10Hz; ; NB The exact xtal frequency is largely irrelevant unless an exact step is needed. ; Original 070207 Code from working F84 routine. No output at Ra2 ; 0800207 Tidied code. Removed 16F84 nemonics. ; Added test flags. Ports OK but still no output. ; Configured CMCON !!!, output OK. Still wont work. ; 100207 Changed XOR routine to written XOR rather than the ; XOR instruction. Works. ; The ISR runs in 36% of available time. ; Pin assignments. ; ; Ra1 Vfo input ; Ra2 Varicap control output ; Rb4 Square wave output at half the sample rate ; Rb3 Timing pulse to show length of ISR routine. errorlevel -302 LIST P=PIC16F628 ; list directive to define processor INCLUDE "P16F628.inc" ; processor specific variable definitions __config (_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC & _MCLRE_OFF) ;========================================================================== ; ; Configuration Bits ; _BODEN_ON EQU H'3FFF' _BODEN_OFF EQU H'3FBF' _CP_ALL EQU H'03FF' _CP_75 EQU H'17FF' _CP_50 EQU H'2BFF' _CP_OFF EQU H'3FFF' _PWRTE_OFF EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _WDT_ON EQU H'3FFF' _WDT_OFF EQU H'3FFB' _LVP_ON EQU H'3FFF' _LVP_OFF EQU H'3F7F' _MCLRE_ON EQU H'3FFF' _MCLRE_OFF EQU H'3FDF' _ER_OSC_CLKOUT EQU H'3FFF' _ER_OSC_NOCLKOUT EQU H'3FFE' _INTRC_OSC_CLKOUT EQU H'3FFD' _INTRC_OSC_NOCLKOUT EQU H'3FFC' _EXTCLK_OSC EQU H'3FEF' _LP_OSC EQU H'3FEC' _XT_OSC EQU H'3FED' _HS_OSC EQU H'3FEE' ;================================================================================= ; RAM useage TEMP EQU 0x40 LOOP_COUNT EQU 0x41 ; 32 byte shift register starts at 0x20 SR0 EQU 0x20 ;32 BYTE Shift register. LASTSR EQU 0x3F SR_BYTES EQU 0x20 ;================================================================================= ; 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 ;================================================================================= ; Code begins here. ORG 0 GOTO START ; Common interupt jump point. ORG 4 GOTO ISR ORG 5 START: CALL SETUP ST2: GOTO ST2 ; Configure ports SETUP: CLRF PORTA ;Initialze port MOVLW 0X07 ;Disable comparators on PORTA and enable I/O MOVWF CMCON BANK1 CLRF VRCON ;Disable other uses of PortA movlw b'00010' ;Set Ra1 as input movwf TRISA movlw b'00000000' ;Rb all output movwf TRISB movlw b'10000000' ;Disable pull-ups, enable pre-sacler div by 2. movwf OPTION_REG movlw b'10100000' ;Set GIE, T0IE and clr T0IF flag movwf INTCON BANK0 RETURN ; Interupt Service Routine. ISR: CLRF INTCON ;Disable interupts while in ISR BSF PORTB,3 ;Bit 3 used to display duration of ISR. ; Now test and store the incoming signal btfss PORTA,1 ;Sample the rf input goto SET_0 goto SET_1 ; Temp store the incoming bit and shift it into register SET_0: bcf TEMP,0 ;Clear incoming bit store bcf STATUS,C ;Clear C bit as sample is 0. BCF PORTB,5 goto ISR2 SET_1: bsf STATUS,C bsf TEMP,0 ;Record input bit was 1 BSF PORTB,5 ; Now toggle the timing flag at Rb4 ; Rb4 shows a square wave at half the sample rate. ISR2: BTFSS PORTB,4 ;Check state of timing flag GOTO ISR4 ;and toggle flag bit 4 BCF PORTB,4 GOTO SHIFT ISR4: BSF PORTB,4 ; Looped shift register code. SHIFT: MOVLW SR0 ;Point to start of SR MOVWF FSR ;Prepare indirect address MOVLW SR_BYTES ;Get number if bytes to rotate MOVWF LOOP_COUNT LOOP: RLF INDF,F ;Now rotate and loop INCF FSR,F DECFSZ LOOP_COUNT,F ;Exit loop when end of SR GOTO LOOP ; Generate Correction Signal BTFSC LASTSR,7 ;Check last bit in SR GOTO LBS ;Last bit set GOTO LBC ;Last bit clear GOTO CTRL0 ;Two 0, send 0 LBS: BTFSC TEMP,0 GOTO CTRL0 ;Two 1, send 0 GOTO CTRL1 ;1 AND 0, send 1 LBC: BTFSC TEMP,0 GOTO CTRL1 CTRL0: BCF PORTA,2 GOTO DONE CTRL1: BSF PORTA,2 DONE: MOVLW B'10100000' ;Enable interupts MOVWF INTCON BCF PORTB,3 RETFIE END ; This code will not work on 16F628 but does work on 16F84. It ; also appears to work on the 628 simulator!!! ; CLRW ; BTFSC STATUS,C ;Get output of shift register ; INCF W,W ;Inc W if carry set ; XORWF TEMP,W ;XOR input and output and save result in W ; BTFSC STATUS,Z ;Check if result was zero or one ; GOTO SHIFT4 ; BSF PORTA,2 ;Output 1 if Z CLR ; GOTO SHIFT6 ;SHIFT4: BCF PORTA,2 ;Output 0 if Z set ;SHIFT6: MOVLW b'10100000' ;Enable interupts ; MOVWF INTCON ; RETFIE