please dont rip this site

Piclist Weedfreq 8DIGIT.ASM

The  Weeder Frequency Counter
Expanded by Brad Hernlem
3 byte count, 8 digits, 1Hz resolution below 16MHz
;******************************************************************************
;                           FREQUENCY COUNTER
;                           Model  : WTCNT
;                           Author : Terry J. Weeder
;                           Date   : November 18, 1993
;                           Version: 1.0
;
;                           WWW.WEEDTECH.COM
;
;                           Ported to 16f84 by
;                           Peter Cousens 
;                           October  1998
;
;                           Further revised,
;                           expanded and modified by
;                           Brad Hernlem
;                           October  2000
;******************************************************************************
; This version is changed to use the full capability to count to 3 byte
; quantities (16,777,215) and disables the overflow at 10,000,000 originally
; in Cousens' code. Also, 8 digits are used instead of seven and the gate
; times are set to 1 second to allow 1 Hz resolution on all ranges.
; When the frequency exceeds 16,777,215 Hz the gate period is 
; reduced to 0.1 second to keep the count within 3 bytes. When frequency is 
; again less than 16,777,216 Hz the gate period reverts to 1 second.
; Please also note that the register addresses are now designated in a 
; CBLOCK. This means that any changes to the CBLOCK MUST NOT affect the
; fixed addresses of the digs to digs+7 registers which SHOULD begin at
; 0C and increase from there. If these are changed, the FSR indirect 
; addressing will be munged.  
;
; Other changes:
;
; 1) the LCD control pins are reassigned to be compatible with Halicky's code
; 2) the display reads "0" when no pulses are inputted. Cousens' code included
;    an rtcc toggle of unknown use which gave an output of "1" without input.
; 3) display shows message "Counting" during initial 1 second count delay.
;
; [Brad Hernlem]
;
; FCounter.ASM
;***************************************************************************

        list    P=PIC16F84A
        INCLUDE <P16f84a.inc>						
	__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON

rtcc    equ     1h

c       equ     0h
z       equ     2h
o       equ     7h

rs      equ     0h	;This bits were changed for compatibility
rw      equ     1h	;with other counter
e       equ     2h	;routines (e.g. Halicky)

;Cousens had the following hard designated. CBLOCK makes them float
;but BEWARE that digs is addressed by FSR and MUST NOT be changed from
;the first position of this block

	CBLOCK	h'0C'
digs:8 			;the display digits registers digs to digs+7
count1  
count2  
addcnt  
gate    
cnt1    
cnt2    
cnt3    
calc1   
calc2   
calc3   
sum1    
sum2    
sum3    
rtcc2
temp1
temp2 
temp3
cnt4 
	ENDC
;
        org     0
        goto    start
                        
;
int_del movlw   0x05            ;delay 5.000 ms (4 MHz clock)
        movwf   count1
d1      movlw   0xA5
        movwf   count2
d2      decfsz  count2,f
        goto    d2
        decfsz  count1,f
        goto    d1
        retlw   0x00
;
lcd_out movwf   PORTB          ;load data into PORTB
        movlw   b'00000000'     ;define PORTB as output
        tris    PORTB
        bsf     PORTA,rs       ;rs = data
        bcf     PORTA,rw       ;r/w = write
        bsf     PORTA,e        ;toggle enable
        bcf     PORTA,e
        movlw   b'11111111'     ;define PORTB as input
        tris    PORTB
        bcf     PORTA,rs       ;rs = instruction
        bsf     PORTA,rw       ;r/w = read
        bsf     PORTA,e        ;enable high
        movf    PORTB,w        ;get address counter
        movwf   addcnt
        bsf     addcnt,7
        bcf     PORTA,e        ;enable low
out1    bsf     PORTA,e        ;enable high
        btfss   PORTB,7        ;test busy flag
        goto    out2
        bcf     PORTA,e        ;enable low
        goto    out1
out2    bcf     PORTA,e        ;enable low
        goto    shift
;
inst    movwf   PORTB          ;load instruction into PORTB
        movlw   b'00000000'    ;define PORTB as output
        tris    PORTB
        bcf     PORTA,rs       ;rs = instruction
        bcf     PORTA,rw       ;r/w = write
        bsf     PORTA,e        ;toggle enable
        bcf     PORTA,e
        movlw   b'11111111'    ;define PORTB as input
        tris    PORTB
        bsf     PORTA,rw       ;r/w = read
inst1   bsf     PORTA,e        ;enable high
        btfss   PORTB,7        ;test busy flag
        goto    inst2
        bcf     PORTA,e        ;enable low
        goto    inst1
inst2   bcf     PORTA,e        ;enable low
        retlw   0x00
;
shift   btfss   addcnt,0        ;shift to opposite side of display?
        retlw   0x00
        btfss   addcnt,1
        retlw   0x00
        btfss   addcnt,2
        retlw   0x00
        btfss   addcnt,3
        retlw   0x00
        movlw   0x39
        addwf   addcnt,f
        bsf     addcnt,7
        movf    addcnt,w
        goto    inst
;
sub     bcf     STATUS,o        ;clear overflow bit
        movf    calc1,w         ;subtract calc1 from cnt1 
        subwf   cnt1,f
        btfsc   STATUS,c
        goto    sb1
        movlw   0x01            ;borrow from cnt2 if overflow
        subwf   cnt2,f
        btfsc   STATUS,c
        goto    sb1
        subwf   cnt3,f          ;borrow from cnt3 if cnt2 overflow
        btfss   STATUS,c
        bsf     STATUS,o        ;set overflow bit if result is negative
sb1     movf    calc2,w         ;subtract calc2 from cnt2
        subwf   cnt2,f
        btfsc   STATUS,c
        goto    sb2
        movlw   0x01            ;borrow from cnt3 if cnt2 overflow
        subwf   cnt3,f
        btfss   STATUS,c
        bsf     STATUS,o        ;set overflow bit if result is negative
sb2     movf    calc3,w         ;subtract calc3 from cnt3
        subwf   cnt3,f
        btfss   STATUS,c
        bsf     STATUS,o        ;set overflow bit if result is negative
        retlw   0x00
;
add     movf    calc1,w         ;add calc1 to cnt1
        addwf   cnt1,f
        btfss   STATUS,c
        goto    ad1
        incfsz  cnt2,f          ;add to cnt2 if cnt1 overflow
        goto    ad1
        incf    cnt3,f          ;add to cnt3 if cnt2 overflow
ad1     movf    calc2,w         ;add calc2 to cnt2
        addwf   cnt2,f
        btfsc   STATUS,c
        incf    cnt3,f          ;add to cnt3 if cnt2 overflow
        movf    calc3,w         ;add calc3 to cnt3
        addwf   cnt3,f
        retlw   0x00
;
; The following has been modified to extract 8 digits
; and get 1 Hz accuracy up to the full 3 byte limit of 16,777,215
;
cnvt    movlw   0x08            ;8 digits in display
        movwf   count1
        movlw   0x0C            ;set fsr for MSB in display
        movwf   FSR
        movlw   0x2F            ;one less that ASCII "0"
cnvt0   movwf   INDF
        incf    FSR,f
        decfsz  count1,f
        goto    cnvt0
        movlw   0x98		;load "10,000,000" in calc1-3
	movwf	calc3
	movlw	0x96
	movwf	calc2
	movlw	0x80
	movwf	calc1
cnvt1	call	sub		;subtract 10 million from count
	incf	digs,f		;increment 10,000,000s register
	btfss	STATUS,o	;check if overflow
	goto	cnvt1
	call	add		;add back last number
        movlw   0x0F            ;load "1,000,000" in calc1-3
        movwf   calc3
        movlw   0x42
        movwf   calc2
        movlw   0x40
        movwf   calc1
cnvt2   call    sub             ;subtract number from count
        incf    digs+1,f        ;increment 1,000,000's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt2
        call    add             ;add back last number
        movlw   0x01            ;load "100,000" in calc1-3
        movwf   calc3
        movlw   0x86
        movwf   calc2
        movlw   0xA0
        movwf   calc1
cnvt3   call    sub             ;subtract number from count
        incf    digs+2,f        ;increment 100,000's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt3
        call    add             ;add back last number
        clrf    calc3           ;load "10,000" in calc1-3
        movlw   0x27
        movwf   calc2
        movlw   0x10
        movwf   calc1
cnvt4   call    sub             ;subtract number from count
        incf    digs+3,f        ;increment 10,000's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt4
        call    add             ;add back last number
        movlw   0x03            ;load "1,000" in calc1-3
        movwf   calc2
        movlw   0xE8
        movwf   calc1
cnvt5   call    sub             ;subtract number from count
        incf    digs+4,f        ;increment 1,000's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt5
        call    add             ;add back last number
        clrf    calc2           ;load "100" in calc1-3
        movlw   0x64
        movwf   calc1
cnvt6   call    sub             ;subtract number from count
        incf    digs+5,f        ;increment 100's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt6
        call    add             ;add back number
        movlw   0x0A            ;load "10" in calc1-3
        movwf   calc1
cnvt7   call    sub             ;subtract number from count
        incf    digs+6,f        ;increment 10's register
        btfss   STATUS,o        ;check if overflow
        goto    cnvt7
        call    add             ;add back last number
        movf    cnt1,w          ;put remainder in 1's register
        addwf   digs+7,f
        incf    digs+7,f
        retlw   0x00
;
; Count period is 25*count2*count1 clocks
; for 4MHz crystal with count2=200, count1=20 gives 0.1 s gate period
;                                   count1=200 gives 1 s gate period
;
count   movlw   b'00110111'     ;rtcc = ext, 1/256
        option
        movlw   b'00010000'     ;define PORTA as output 
        tris    PORTA
        bcf     PORTA,3
        bcf     PORTA,rs
        clrf    cnt3
	clrf	cnt4
	clrf	temp3
        clrf    rtcc
        clrf    rtcc2
;        bsf     PORTA,rs        ;toggle rtcc pin
;        bcf     PORTA,rs	 ;[these two lines were in Cousens' code. purpose unkown]
        movf    gate,w          ;get gate time
        movwf   count1
st1     bsf     PORTA,3         ;start count
fr4     movlw   0xC8		;1  count2 set to 200
        movwf   count2		;2
        goto    fr6		;4
fr5     nop			;24
        nop			;25
        nop			;01
        nop			;02
        nop			;03
        nop			;04
fr6     movf    rtcc,w          ;5   test for rtcc rollover (12)
        subwf   rtcc2,f		;6
        btfss   STATUS,z	;7
        goto    fr7		;9
        nop			;9
        goto    fr8		;11
fr7     btfsc   STATUS,c	;10
        incf    cnt3,f		;11
fr8     movwf   rtcc2		;12
	movf	cnt3,w		;13 test for cnt3 rollover
	subwf	temp3,f		;14
	btfss	STATUS,z	;15
	goto	br1		;17
	nop			;17
	goto	br2		;19
br1	btfsc	STATUS,c	;18
	incf	cnt4,f		;19 increment cnt4 if cnt3 rollover
br2	movwf	temp3		;20
        decfsz  count2,f	;21
        goto    fr5		;23
        decfsz  count1,f	;23+25(count2-1)
        goto    fr4		;25
        bcf     PORTA,3         ;25*count2*count1  stop count
st2     movf    rtcc,w          ;get rtcc count
        movwf   cnt2
        subwf   rtcc2,f         ;test for rtcc rollover
        btfss   STATUS,c
        goto    fr9
        btfss   STATUS,z
        incf    cnt3,f
fr9     clrf    cnt1            ;set to get prescaler count
fr10    decf    cnt1,f
        bsf     PORTA,rs        ;toggle rtcc pin
        bcf     PORTA,rs
        movf    rtcc,w          ;test if rtcc has changed
        xorwf   cnt2,w
        btfsc   STATUS,z
        goto    fr10
        retlw   0x00
;
;******************************************************************************
;                                   START
;******************************************************************************
;
start   clrf    PORTA          ;instruction, write, enable low
        movlw   b'00010000'
        tris    PORTA
        clrf    PORTB
        movlw   b'00000000'
        tris    PORTB
        call    int_del
        call    int_del
        call    int_del
        movlw   0x38            ;initialize display
        movwf   PORTB
        bsf     PORTA,e        ;toggle enable
        call    int_del
        bcf     PORTA,e
        bsf     PORTA,e        ;toggle enable
        call    int_del
        bcf     PORTA,e
        bsf     PORTA,e        ;toggle enable
        call    int_del
        bcf     PORTA,e
        movlw   0x38            ;function
        call    inst
        movlw   b'00001100'     ;display on, cursor off
        call    inst
        movlw   b'00000001'     ;clear display
        call    inst
        movlw   b'00000110'     ;entry mode
        call    inst
;  Intro message during initial count 
        movlw   0x20		;space
	call	lcd_out
        movlw   0x20		;space
	call	lcd_out
        movlw   0x20		;space
	call	lcd_out
        movlw   0x20		;space
	call	lcd_out
        movlw   0x43		;C
	call	lcd_out
        movlw   0x6F		;0
	call	lcd_out
        movlw   0x75		;u
	call	lcd_out
        movlw   0x6E		;n
	call	lcd_out
        movlw   0x74		;t
	call	lcd_out
        movlw   0x69		;i
	call	lcd_out
        movlw   0x6E		;n
	call	lcd_out
        movlw   0x67		;g
	call	lcd_out
;
mhz     movlw   0xC8            ;1 sec gate
        movwf   gate
        call    count
	clrw			;check whether cnt4 is zero
	xorwf	cnt4,w
	btfss	STATUS,z
	goto	shortg		;not zero - use shorter gate period
        call    cnvt            ;convert binary to BCD
        movlw   0x30            ;test if "0"
        xorwf   digs,w
        btfss   STATUS,z
        goto    mhz1
        movlw   0x30            ;test if "0"
        xorwf   digs+1,w
        btfsc   STATUS,z
        goto    khz1
mhz1    movlw   0x81            ;set display address
        call    inst
        movlw   0x02            ;output first 2 characters
        movwf   count1
        movlw   0x0C            ;MSD of freq, i.e. digs
        movwf   FSR
mhz2    movlw   0x30            ;test if "0"
        xorwf   INDF,w
        btfss   STATUS,z
        goto    mhz3
        movlw   0x20            ;change preceeding "0's" to "space"
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    mhz2
        goto    mhz4
mhz3    movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    mhz3
mhz4    movlw   0x2E            ;"."
        call    lcd_out
        movlw   0x06            ;output last 6 characters
        movwf   count1  
mhz5    movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    mhz5
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x4D            ;"M"
        call    lcd_out
        movlw   0x48            ;"H"
        call    lcd_out
        movlw   0x7A            ;"z"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        goto    mhz
;
khz     movlw   0xC8            ;1 sec gate
        movwf   gate
        call    count
        call    cnvt            ;convert binary to BCD
        movlw   0x30            ;test if 0
        xorwf   digs,w
        btfss   STATUS,z
        goto    mhz1
        movlw   0x32            ;test if < 2
        subwf   digs+1,w
        btfsc   STATUS,c
        goto    mhz1
        movlw   0x30            ;test if "0"
        xorwf   digs+1,w
        btfss   STATUS,z
        goto    khz1
        movlw   0x30            ;test if "0"
        xorwf   digs+2,w
        btfss   STATUS,z
        goto    khz1
        movlw   0x30            ;test if "0"
        xorwf   digs+3,w
        btfsc   STATUS,z
        goto    hz0
khz1    movlw   0x81            ;set display address
        call    inst
        movlw   0x05            ;output first 5 characters
        movwf   count1
        movlw   0x0C            ;MSD of freq, digs register
        movwf   FSR
khz2    movlw   0x30            ;test if "0"
        xorwf   INDF,w
        btfss   STATUS,z
        goto    khz3
        movlw   0x20            ;change preceeding "0's" to "space"
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    khz2
        goto    khz4
khz3    movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    khz3
khz4    movlw   0x2E            ;"."
        call    lcd_out
        movf    INDF,w           ;output last 3 characters
        call    lcd_out
        incf    FSR,f
        movf    INDF,w
        call    lcd_out
        incf    FSR,f
        movf    INDF,w
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x4B            ;"K"
        call    lcd_out
        movlw   0x48            ;"H"
        call    lcd_out
        movlw   0x7A            ;"z"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        goto    khz
;
hz      movlw   0xC8            ;1 sec gate
        movwf   gate
        call    count
        call    cnvt            ;convert binary to BCD
        movlw   0x30            ;test if "0"
        xorwf   digs,w
        btfss   STATUS,z
        goto    mhz1
        movlw   0x32            ;test if < 2
        subwf   digs+1,w
        btfsc   STATUS,c
        goto    mhz1
        movlw   0x30            ;test if "0"
        xorwf   digs+1,w
        btfss   STATUS,z
        goto    khz1
        movlw   0x30            ;test if "0"
        xorwf   digs+2,w
        btfss   STATUS,z
        goto    khz1
        movlw   0x30            ;test if "0"
        xorwf   digs+3,w
        btfss   STATUS,z
        goto    khz1
hz0     movlw   0x81            ;set display address
        call    inst
        movlw   0x07            ;output first 7 characters
        movwf   count1
        movlw   0x0C            ;MSD of freq, digs register
        movwf   FSR
hz1     movlw   0x30            ;test if "0"
        xorwf   INDF,w
        btfss   STATUS,z
        goto    hz2
        movlw   0x20            ;change preceeding "0's" to "space"
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    hz1
        goto    hz3
hz2     movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    hz2
hz3	movf	INDF,w
	call	lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x48            ;"H"
        call    lcd_out
        movlw   0x7A            ;"z"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        goto    hz
;
shortg  movlw   0x14            ;0.1 sec gate
        movwf   gate
        call    count
	call	tenx		;multiply count by ten
	clrw			;check whether cnt4 is zero
	xorwf	cnt4,w
	btfsc	STATUS,z
	goto	mhz		;was zero - use longer gate period
        call    cnvt            ;convert binary to BCD
        movlw   0x30            ;test if "0"
        xorwf   digs,w
        btfss   STATUS,z
        goto    shg1
        movlw   0x30            ;test if "0"
        xorwf   digs+1,w
        btfsc   STATUS,z
        goto    mhz
shg1    movlw   0x81            ;set display address
        call    inst
        movlw   0x03            ;output first 3 characters
        movwf   count1
        movlw   0x0C            ;MSD of freq, i.e. digs
        movwf   FSR
shg2    movlw   0x30            ;test if "0"
        xorwf   INDF,w
        btfss   STATUS,z
        goto    shg3
        movlw   0x20            ;change preceeding "0's" to "space"
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    shg2
        goto    shg4
shg3    movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    shg3
shg4    movlw   0x2E            ;"."
        call    lcd_out
        movlw   0x05            ;output last 5 characters
        movwf   count1  
shg5    movf    INDF,w
        call    lcd_out
        incf    FSR,f
        decfsz  count1,f
        goto    shg5
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x4D            ;"M"
        call    lcd_out
        movlw   0x48            ;"H"
        call    lcd_out
        movlw   0x7A            ;"z"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        movlw   0x20            ;"space"
        call    lcd_out
        goto    shortg
;
; This subroutine multiplies the count in cnt1-3 by 10 (called from the 0.1 sec
; gate routine) and puts any overflow into cnt4. This is to check whether the frequency
; has gone back under 16,777,216 and whether the gate period should be increased to 1 sec.
;
tenx	clrf	cnt4		;clear the overflow register and
	movf	cnt1,w		;fill calc1-3 with current cnt1-3 values
	movwf	calc1		;it is assumed that cnt4 cannot be non-zero
	movf	cnt2,w		;when the gate period is only 0.1 sec
	movwf	calc2		;
	movf	cnt3,w		;
	movwf	calc3		;
	bcf	STATUS,c
	rlf	calc1,f		;multiply by 2 and carry through
	rlf	calc2,f
	rlf	calc3,f
	btfsc	STATUS,c
	incf	cnt4,f		
	movf	calc1,w		;temporarily store the times 2 value
	movwf	temp1
	movf	calc2,w
	movwf	temp2
	movf	calc3,w
	movwf	temp3
	bcf	STATUS,c
	rlf	calc1,f		;multiply by 2 twice and check for carry each time
	rlf	calc2,f
	rlf	calc3,f
	btfsc	STATUS,c
	incf	cnt4,f
	bcf	STATUS,c
	rlf	calc1,f
	rlf	calc2,f
	rlf	calc3,f
	btfsc	STATUS,c
	incf	cnt4,f
	movf	temp1,w		;now add the x2 and x8 values for x10 total
	addwf	calc1,f
	btfsc	STATUS,c
	incf	calc2, f
	btfsc	STATUS,z
	incf	calc3,f
	btfsc	STATUS,z
	incf	cnt4,f
	movf	temp2,w
	addwf	calc2,f
	btfsc	STATUS,c
	incf	calc3,f
	btfsc	STATUS,z
	incf	cnt4,f
	movf	temp3,w
	addwf	calc3,f
	btfsc	STATUS,c
	incf	cnt4,f
	return
;
        end



file: /Techref/piclist/weedfreq/8digit.asm, 22KB, , updated: 2006/4/7 13:43, local time: 2024/11/19 06:07,
TOP NEW HELP FIND: 
3.142.201.91:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/techref/piclist/weedfreq/8digit.asm"> piclist weedfreq 8digit</A>

Did you find what you needed?