; Bat frequency heterodyne counter ; ; derived from a counter with 4 digits ; actually uses only 2 digits now ; redundant zero are kept ; ; last change: September 2, 1999 ; Bertrik Sikken CommonAnode equ 1 CommonCathode equ 2 DisplayType equ CommonCathode DebugMode equ 0 ; set to 0 in final version !!!! if DisplayType==CommonCathode messg "Compiling for common cathode" else messg "Compiling for common anode" endif if DebugMode==1 messg "Warning: compiling for debugging !" endif ; !!!! make sure to change the following lines when ; !!!! using the PIC16F84 instead of PIC16C84 list p=16c84, r=DEC include p16c84.inc __fuses _WDT_OFF & _XT_OSC & _PWRTE_ON ; definition of hardware connections #define pin_osc_in PORTA,4 ; RA0 = left digit common, RA1 = right digit common #define pin_dig_left PORTA,0 #define pin_dig_right PORTA,1 ; PORTB 1-7 is connected to segments a-g ; definition of variables cblock 12 count temp1 temp2 dig1 dig2 muxcount int16_a int16_b int16_c_hi int16_c_lo int16_count templed7 endc init bsf STATUS,RP0 ; set tristate registers movlw B'00000001' ; all outputs for PORTB bits 1-7 movwf PORTB movlw B'11111' ; all inputs movwf PORTA ; no prescaler, external, rising edge movlw B'10101000' movwf TMR0 bcf STATUS,RP0 ; program mainloop main call count_pulses call convert_digits goto main ;------------------------------------------ ; led conversion lookup table led7 ; in: number in W ; out: 7-seg code in W in format B'gfedcba0' ; movwf templed7 ; movlw HIGH led7 ; protect against wrong page ; movwf PCLATH ; movfw templed7 andlw 15 addwf PCL,f ; format B'abcdefg.' if DisplayType==CommonCathode retlw B'01111110' retlw B'00001100' retlw B'10110110' retlw B'10011110' retlw B'11001100' retlw B'11011010' retlw B'11111010' retlw B'00001110' retlw B'11111110' retlw B'11011110' retlw B'10000000' retlw B'10000000' retlw B'10000000' retlw B'10000000' retlw B'10000000' retlw B'00000000' ; empty character else retlw B'10000000' retlw B'11110010' retlw B'01001000' retlw B'01100000' retlw B'00110010' retlw B'00100100' retlw B'00000100' retlw B'11110000' retlw B'00000000' retlw B'00100000' retlw B'01111110' retlw B'01111110' retlw B'01111110' retlw B'01111110' retlw B'01111110' retlw B'11111110' ; empty character endif led7end if HIGH led7 != HIGH led7end error "Warning: page overflow in table lookup!" endif ;------------------------------------------ ; update digits ; each digit is lit for approx. 0.5 msec, so the total ; time spent is almost 1 msec display if DisplayType==CommonCathode bcf pin_dig_left else bsf pin_dig_left endif movfw dig1 call led7 movwf PORTB bsf STATUS,RP0 bcf pin_dig_left ; set pin as output bcf STATUS,RP0 call delay500u if DisplayType==CommonCathode bcf pin_dig_right else bsf pin_dig_right endif bsf STATUS,RP0 bsf pin_dig_left ; pin = input bcf pin_dig_right ; pin = output bcf STATUS,RP0 movfw dig2 call led7 movwf PORTB call delay500u bsf STATUS,RP0 bsf pin_dig_right bcf STATUS,RP0 nop ; timing adjustment return delay500u ; delay for approx. 0.5 msec movlw 159 movwf temp1 dis_loop3 decfsz temp1,f goto dis_loop3 return ;------------------------------------------ ; divides 15-bit number in int16_c by 7-bit int16_b into int16_a ; the remainder goes into int16_c_hi divide movlw 8 movwf int16_count div_loop rlf int16_c_lo,f rlf int16_c_hi,f movfw int16_b subwf int16_c_hi,w btfsc STATUS,C movwf int16_c_hi rlf int16_a,f decfsz int16_count,f goto div_loop return ;------------------------------------------ ; the following routine converts the 16-bit value ; in count_c_lo and count_c_hi into 2 decimal digits ; dig1 is the most significant digit convert_digits ; divide count by 10 movfw count movwf int16_c_lo clrf int16_c_hi movlw 10 movwf int16_b call divide movfw int16_a movwf dig1 movfw int16_c_hi movwf dig2 return ;------------------------------------------ ; count pulses in a 1 msec period, this ; corresponds to the frequency in multiples of 1 kHz count_pulses ; wait for first edge down if DebugMode==0 c2w1 btfss pin_osc_in goto c2w1 c2w2 btfsc pin_osc_in goto c2w2 endif ; reset timer & prescaler : start count clrf TMR0 ; refresh display during counting ... call display ; save count: movfw TMR0 movwf count return END