Freq Counter v2
Freq Counter v2
Freq Counter v2
;
; "Digital" Frequency display
;
; Crystal freq. = 4.000MHz +/- a bit
;
;*******************************************************************
;
; First, let us choose our weapon - 16F84 or 16F628
;
; Comment out the next line [;#define F84] if using a 16F628
; #define F84
#ifndef F84
#define F628
#endif
;*******************************************************************
;
; Some Testing Stuff(tm)
;
;#define testing 1 ; Comment out when testing finished
;#define Two_Line 1 ; Un-comment for two line displays
;************************ REVISION HISTORY *************************
;
; FM1.000 Originally from FM3/4 9:39pm 14 May 2002
; As implemented in experimental 3.5MHz receiver
;
;*******************************************************************
;
; FM1.003 Fixed? major silliness in LO-IF code
; Re-wrote USB/LSB suffix code
; Added #defines for crook displays
; Added #defines for two line displays
; Wrapped #ifdef ... endif around debugging code
;
;*******************************************************************
;
; FM1.004 Added code to allow user to fix crook display
; Deleted #defines for crook displays
; Pin 18 is now input. 1 = good display, 0 = crook
;
;*******************************************************************
;
; FM2.000 New Hardware! Deleted external counter & gating
; Now uses the same scheme as the LC Meter, with the
; third byte of the count implemented in the PIC.
; Basically, the "output" of the timer register is
; counted within the gate timing loop.
;
;*******************************************************************
;
; FM2.001 Discovered that I don't need to use RA0 as a gate
; cos RA4 can be used as a timer input, even when
; defined as an output - all that is required is to
; set it high to count or low to inhibit.
; Jeez, Microchip are smart arses.
; I dunno why I didn't spot this long ago.
; (Can't be used on the LC Meter, cos its oscillator
; needs to be clamped HIGH, not low as in this case).
;
;*******************************************************************
;
; FM2.002 Added 9600 baud serial output via RA0
;
;*******************************************************************
;
; FM2.003 Rewrote RollOver subroutine to use INTCON,T0IF bit.
; Incorporated two bits from OvrFlow counter
; to extend range to over 80MHz.
;
;*******************************************************************
;
; FM2.004 Changed to 32 bit counting.
;
;*******************************************************************
;
; FM2.005 Added "Calibrate" mode.
;
;*******************************************************************
;
; FM2.006 Moved "divide by 4" to increase resolution of
; the stored IF offsets
;
;*******************************************************************
;
; FM2.007 Moved "check for rollover" out of the inner MS400
; timing loop and adjusted loop count appropriately
; The aim - to improve the resolution of the software
; calibration by a factor of around 13 to 15 times.
;
;*******************************************************************
;
; fm2b.007 Ported to 16F628
; FM2c.007 Introduced macros
; fm2.008 Renumbered
;
;*******************************************************************
;
; fm2.009 Cleaned up AM IF Offset calculation
; Converted some inline code to subroutines
; Created new 32 bit "copy" macro
; Adjusted calibration slightly
; Added a "Processor =" message
;
;*******************************************************************
;o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o
;*******************************************************************
;
; Some frequently used code fragments
; Use macros to make mistreaks consistently.
;
;-------------------------------------------------------------------
; Select Register Bank 0
bank0 macro
errorlevel +302 ; Re-enable bank warning
bcf STATUS,RP0 ; Select Bank 0
endm
;-------------------------------------------------------------------
; Select Register Bank 1
bank1 macro
bsf STATUS,RP0 ; Select Bank 1
errorlevel -302 ; disable warning
endm
;-------------------------------------------------------------------
; Copy a 32 bit thing from one place to another
copy macro from,to
movf from+0,W
movwf to+0
movf from+1,W
movwf to+1
movf from+2,W
movwf to+2
movf from+3,W
movwf to+3
endm
;*******************************************************************
;
; CPU configuration
;
#ifdef F84
MESSG "Processor = 16F84"
#define RAMStart 0x0C ; by VK3BHR
processor 16f84
include <p16f84.inc>
__config _HS_OSC & _PWRTE_ON & _WDT_OFF
#endif
#ifdef F628
MESSG "Processor = 16F628"
#define RAMStart 0x20
processor 16f628
include <p16f628.inc>
__config _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF & _BODEN_ON & _LVP_OFF
#endif
;*******************************************************************
;
; I/O configuration
;
#define S_out PORTA,0x00 ; 9600 baud serial out
#define PUFF PORTA,0x00 ; Testing counter out
#define FIXIT PORTA,0x01 ; 1 = "good display"
; 0 = do CRLF at "chr 8"
endc
#ifdef F84
Part2 equ D_hex+1 ; Just tack on end
#endif
#ifdef F628
Part2 equ 0x70 ; $70-7F Visible from all banks
#endif
cblock Part2
COUNT1 ; Used by delay routines
COUNT2 ; Timing (100ms)
COUNT3 ; Timing (100ms)
COUNT4 ; Timing (400ms)
AccA:4 ; Binary, MSByte first
AccB:4 ; Intermediate frequency
Hold:4 ; Used in "cal" mode
endc
;**********************************************************
;
; Begin Executable Stuff(tm)
;
org 0
GO clrwdt ; 0 << Reset
clrf INTCON ; 1 No interrupts
#ifdef F628
movlw 0x07 ; 2 Comparator off
movwf CMCON ; 3
#endif
goto START ; 4 << Interrupt.
;**********************************************************
;
; Part of string printer
;
pmsub movwf PCL ; Goto W
nop ; Just in case
pm_end return
;**********************************************************
;
; Text Strings (stored in RETLWs)
;
mhz dt " MHz ",0
Spaces dt " ",0
USB dt " USB",0
LSB dt " LSB",0
Prog dt " PRG",0
Cal dt " CAL",0
adv1 dt "Freq. Counter ",0
adv2 dt " DOM13C",0
ovr1 dt " Over ",0
ovr2 dt "Range ",0
Blanks16 dt " ",0;LEDTESTER from EEVBlog modified this.
#ifdef Two_Line
adv3 dt "1234567890ABCDEF",0
#endif
;**********************************************************
;
; Main Program
;
START call InitIO ; INITIALISE PORTS
CLRF PORTA
CLRF PORTB
bsf S_out ; Serial output to idle
MOVLW 0x03 ; 1
call PB_dly
;********************************************************************
; Read EEPROM into "AccB" (AccB must be visible in both
; W -> memory to read memory banks 0 & 1)
;********************************************************************
EE_RD
#ifdef F628
bank1
#endif
MOVWF EEADR ; Address to read
#ifdef F628
bank0
#endif
;********************************************************************
; Write EEPROM from "AccB" (AccB must be visible in both
; W -> memory to write memory banks 0 & 1)
;********************************************************************
#ifdef F84
EE_WR MOVWF EEADR ; Address to write
MOVF AccB+0,W ; Data byte #0
CALL EE_W
MOVF AccB+1,W ; Data byte #1
CALL EE_Winc
MOVF AccB+2,W ; Data byte #2
CALL EE_Winc
MOVF AccB+3,W ; Data byte #3
CALL EE_Winc
RETURN
EE_Winc INCF EEADR,F ; bump address
movlw 0x57 ; W=
call putchr
movlw 0x3d
call putchr
movf D_Wtemp,w
call hex_2
return
;***********************************************************************
;
; Print CRLF to serial
;
crlf movlw 0x0d ; CRLF
call putchr
movlw 0x0a
goto putchr
;***********************************************************************
;
; Print W as 2 Hex digits
;
hex_2 movwf D_hex
swapf D_hex,w ; Get big bit
call hex_3
movf D_hex,w ; Get little bit
hex_3 andlw 0x0f ; keep bottom 4 bits
addlw 0xF6
bcc hex_4
addlw 0x07 ; binary A -> ASCII A
hex_4 addlw 0x3A ; binary 0 -> ASCII 0
; goto putchr
;********************************************************
;
; Output Routines for PIC16F84
;
; Clock is 4.0 MHz.
; ie. 1.0 us per cycle = 4/Fosc.
;
; 9600 Baud = 104.17 us
; = 104.17 CPU cycles
;
;********************************************************
;
; Output the character in W. Assumes Mac is ready.
;
; Uses W
;
putchr movwf S_Wtemp ; Character being output
movlw 0x08 ; Bit count
movwf S_count
bcf S_out ; Send a 0 - Start bit
put_clp movlw 0xE7 ; Delay "104" cycles
txd_0 addlw 0x01
bne txd_0
rrf S_Wtemp,f ; Transmit a bit
bcs t_0
bcf S_out ; Send a 0
bra tx_1
t_0 bsf S_out ; Send a 1
tx_1 decfsz S_count,f ; Done all bits?
goto put_clp
movlw 0xE7 ; Delay for last data
txd_1 addlw 0x01
bne txd_1
bsf S_out ; Transmit two stop bit
movlw 0xCD
txd_9 addlw 0x01
bne txd_9
return
;********************************************************************
; Tail End Charlie
;********************************************************************
; initialize eeprom locations
ORG 0x2100
DE 0x00, 0x00, 0x00, 0x00 ; Unused (reserved for later)
DE 0x00, 0x00, 0x00, 0x00 ; IF Offset 1 Low BFO ????
DE 0x00, 0x00, 0x00, 0x00 ; IF Offset 2 High BFO ????
DE 0x00, 0x00, 0x00, 0x00 ; IF Offset 3 No BFO -AM-
DE 0xfd, 0xff, 0xc4, 0x00 ; 4.000 MHz initial calibration
END