;****************************************************************************** ; DIGITAL FREQUENCY COUNTER ; ; Author : Vicsys ; ; Version: 1.0 ; ; Http://freki.atw.hu ; ; ; ; lines 337 to 453 are an example of where to add personal introductory ; lines and should be omitted or changed to your own ;****************************************************************************** ; ; list p=16f628a include p16f628a.inc __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_OFF & _BODEN_OFF& _LVP_OFF ;& _LVP_OFF & _CPD_OFF ; ; INDF equ 0h rtcc equ 1h pc equ 2h status equ 3h fsr equ 4h port_a equ 5h port_b equ 6h ;port_c equ 7h c equ 0h dc equ 1h z equ 2h pd equ 3h to equ 4h MSB equ 7h LSB equ 0h ; cnt equ 2h rs equ 2h rw equ 1h e equ 0h o equ 7h ; count1 equ 3Eh count2 equ 3Fh count3 equ 40h count4 equ 41h in_reg equ 42h addcnt equ 43h TEMP equ 44h gate equ 20h cnt1 equ 21h cnt2 equ 22h cnt3 equ 23h calc1 equ 24h calc2 equ 25h calc3 equ 26h sum1 equ 27h sum2 equ 28h sum3 equ 29h rtcc2 equ 2Ah ; 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 port_b ;load data into port_b bsf STATUS,RP0 ; select Register-Page 1************************** movlw b'00000000' ;define port_b as output tris port_b bcf STATUS,RP0 ; select Register-Page 0 ************************ bsf port_a,rs ;rs = data bcf port_a,rw ;r/w = write bsf port_a,e ;toggle enable bcf port_a,e bsf STATUS,RP0 ; select Register-Page 1************************** movlw b'11111111' ;define port_b as input tris port_b bcf STATUS,RP0 ; select Register-Page 0 ************************ bcf port_a,rs ;rs = instruction bsf port_a,rw ;r/w = read bsf port_a,e ;enable high movf port_b,w ;get address counter movwf addcnt bsf addcnt,7 bcf port_a,e ;enable low out1 bsf port_a,e ;enable high btfss port_b,7 ;test busy flag goto out2 bcf port_a,e ;enable low goto out1 out2 bcf port_a,e ;enable low goto shift ; inst movwf port_b ;load instruction into port_b bsf STATUS,RP0 ; select Register-Page 1************************** movlw b'00000000' ;define port_b as output tris port_b bcf STATUS,RP0 ; select Register-Page 0 ************************ bcf port_a,rs ;rs = instruction bcf port_a,rw ;r/w = write bsf port_a,e ;toggle enable bcf port_a,e bsf STATUS,RP0 ; select Register-Page 1************************** movlw b'11111111' ;define port_b as input tris port_b bcf STATUS,RP0 ; select Register-Page 0 ************************ bsf port_a,rw ;r/w = read inst1 bsf port_a,e ;enable high btfss port_b,7 ;test busy flag goto inst2 bcf port_a,e ;enable low goto inst1 inst2 bcf port_a,e ;enable low retlw 0x00 ; shift btfsc addcnt,0 ;shift to opposite side of display? retlw 0x00 btfsc addcnt,1 retlw 0x00 btfsc addcnt,2 retlw 0x00 btfss addcnt,3 retlw 0x00 movlw 0x38 addwf addcnt,f bsf addcnt,7 movf addcnt,w goto inst ; sub bcf TEMP,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 TEMP,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 TEMP,o ;set overflow bit if result is negative sb2 movf calc3,w ;subtract calc3 from cnt3 subwf cnt3 ,f btfss status,c bsf TEMP,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 ; cnvt movlw 0x07 ;7 digits in display movwf count1 movlw 0x2D ;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 0x0F ;load "1,000,000" in calc1-3 movwf calc3 movlw 0x42 movwf calc2 movlw 0x40 movwf calc1 cnvt1 call sub ;subtract number from count incf 2D ,f ;increment 1,000,000's register movlw 0x3A xorwf 2D,w btfsc status,z goto overflow btfss TEMP,o ;check if overflow goto cnvt1 call add ;add back last number movlw 0x01 ;load "100,000" in calc1-3 movwf calc3 movlw 0x86 movwf calc2 movlw 0xA0 movwf calc1 cnvt2 call sub ;subtract number from count incf 2E ,f ;increment 100,000's register btfss TEMP,o ;check if overflow goto cnvt2 call add ;add back last number clrf calc3 ;load "10,000" in calc1-3 movlw 0x27 movwf calc2 movlw 0x10 movwf calc1 cnvt3 call sub ;subtract number from count incf 2F ,f ;increment 10,000's register btfss TEMP,o ;check if overflow goto cnvt3 call add ;add back last number movlw 0x03 ;load "1,000" in calc1-3 movwf calc2 movlw 0xE8 movwf calc1 cnvt4 call sub ;subtract number from count incf 30 ,f ;increment 1,000's register btfss TEMP,o ;check if overflow goto cnvt4 call add ;add back last number clrf calc2 ;load "100" in calc1-3 movlw 0x64 movwf calc1 cnvt5 call sub ;subtract number from count incf 31 ,f ;increment 100's register btfss TEMP,o ;check if overflow goto cnvt5 call add ;add back number movlw 0x0A ;load "10" in calc1-3 movwf calc1 cnvt6 call sub ;subtract number from count incf 32 ,f ;increment 10's register btfss TEMP,o ;check if overflow goto cnvt6 call add ;add back last number movf cnt1,w ;put remainder in 1's register addwf 33,f incf 33,f retlw 0x00 ; count movlw b'00110111' ;rtcc = ext, 1/256 option ;************************ITT************ bsf STATUS,RP0 ; select Register-Page 1 ******************** movlw b'00010000' ;define port_a as output tris port_a bcf STATUS,RP0 ; select Register-Page 0 ******************** bcf port_a,3 bcf port_a,2 clrf cnt3 clrf rtcc clrf rtcc2 bsf port_a,2 ;toggle rtcc pin bcf port_a,2 movf gate,w ;get gate time movwf count1 bsf port_a,3 ;start count fr4 movlw 0xFA movwf count2 goto fr6 fr5 nop nop nop nop nop nop fr6 movf rtcc,w ;test for rtcc rollover (12) subwf rtcc2 ,f btfss status,z goto fr7 nop goto fr8 fr7 btfsc status,c incf cnt3 ,f fr8 movwf rtcc2 nop nop nop decfsz count2 ,f goto fr5 decfsz count1 ,f goto fr4 bcf port_a,3 ;stop count 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 port_a,2 ;toggle rtcc pin bcf port_a,2 movf rtcc,w ;test if rtcc has changed xorwf cnt2,w btfsc status,z goto fr10 retlw 0x00 ; ;****************************************************************************** ; START ;****************************************************************************** ; MOVLW 0X07 ;Turn comparators off and MOVWF CMCON ;enable pins for I/O start clrf port_a ;instruction, write, enable low bsf STATUS,RP0 ; select Register-Page 1 **************************** movlw b'00010000' tris port_a bcf STATUS,RP0 ; select Register-Page 0 **************************** MOVLW 7 MOVWF CMCON clrf port_b bsf STATUS,RP0 ; select Register-Page 1 movlw b'00000000' tris port_b bcf STATUS,RP0 ; select Register-Page 0 **************************** call int_del call int_del call int_del movlw 0x38 ;initialize display movwf port_b bsf port_a,e ;toggle enable call int_del bcf port_a,e bsf port_a,e ;toggle enable call int_del bcf port_a,e bsf port_a,e ;toggle enable call int_del bcf port_a,e bcf port_b,4 ;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 ; new lines here for intro movlw b'00000001' ;clear display call inst movlw b'00000110' ;entry mode call inst ; mhz movlw 0x14 ;0.1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if "0" xorwf 2D,w btfss status,z goto mhz1 movlw 0x30 ;test if "0" xorwf 2E,w btfsc status,z goto khz1 mhz1 movlw 0x82 ;set display address call inst movlw 0x02 ;output first 2 characters movwf count1 movlw 0x2D ;MSD of freq 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 0x05 ;output last 5 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 0x14 ;0.1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if 0 xorwf 2D,w btfss status,z goto mhz1 movlw 0x32 ;test if < 2 subwf 2E,w btfsc status,c goto mhz1 movlw 0x30 ;test if "0" xorwf 2E,w btfss status,z goto khz1 movlw 0x30 ;test if "0" xorwf 2F,w btfsc status,z goto xkhz khz1 movlw 0x82 ;set display address call inst movlw 0x05 ;output first 5 characters movwf count1 movlw 0x2D ;MSD of freq 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 2 characters 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 ; xkhz movlw 0xC8 ;1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if 0 xorwf 2D,w btfss status,z goto khz movlw 0x32 ;test if < 2 subwf 2E,w btfsc status,c goto khz movlw 0x30 ;test if 0 xorwf 2E,w btfss status,z goto xkhz1 movlw 0x30 ;test if 0 xorwf 2F,w btfsc status,z goto hz0 xkhz1 movlw 0x82 ;set display address call inst movlw 0x04 ;output first 4 characters movwf count1 movlw 0x2D ;MSD of freq movwf fsr xkhz2 movlw 0x30 ;test if "0" xorwf INDF,w btfss status,z goto xkhz3 movlw 0x20 ;change preceeding "0's" to "space" call lcd_out incf fsr ,f decfsz count1 ,f goto xkhz2 goto xkhz4 xkhz3 movf INDF,w call lcd_out incf fsr ,f decfsz count1 ,f goto xkhz3 xkhz4 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 xkhz ; hz movlw 0xC8 ;1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if "0" xorwf 2D,w btfss status,z goto xkhz1 movlw 0x30 ;test if "0" xorwf 2E,w btfss status,z goto xkhz1 movlw 0x32 ;test if < 2 subwf 2F,w btfsc status,c goto xkhz1 hz0 movlw 0x82 ;set display address call inst movlw 0x07 ;output first 7 characters movwf count1 movlw 0x2D ;MSD of freq 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 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 ; overflow movlw 0x01 ;clear display call inst movlw 0x84 ;display address call inst movlw 0x4F ;"O" call lcd_out movlw 0x76 ;"v" call lcd_out movlw 0x65 ;"e" call lcd_out movlw 0x72 ;"r" call lcd_out movlw 0x66 ;"f" call lcd_out movlw 0x6C ;"l" call lcd_out movlw 0x6F ;"o" call lcd_out movlw 0x77 ;"w" call lcd_out movlw 0x02 ;cursor at home call inst goto mhz ; end