; FLOGGER.ASM ; Current Version: 0.00 ; ; PIC based frequency recorder ; Usable up to 16 MHz ; ; Created by Wim de Vree, pe1grl@amsat.org ; based on sources of the "Weeder frequency counter" ; ; Brief overview: ; This programs counts incoming pulses during a 1 second gate ; time and transmits the measured frequency over a 4800 baud ; serial interface. Each measurement has the format ; "AAAA,BBBBBBBB" where AAAA is a running serial number ; and BBBBBBBB is the frequency in Herzt ; The program is configurable to send a measurement every second ; or every 10 seconds. ;----------------------------------------------------------------------------- ; 2005-10-23 Initial creation of this program ; 2005-10-24 Some cleanup if NO MAX2323 is used ; 2005-10-25 Baudrate changed to 9600Bd, support added for 10 MHz clock ; support added for 1 transmission per 1 or 10 seconds ;----------------------------------------------------------------------------- LIST P=PIC12F629, F=INHX8M __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON & _MCLRE_OFF ; 4MHz Xtal ; __CONFIG _CP_OFF & _WDT_OFF & _EC_OSC & _PWRTE_ON & _MCLRE_OFF ; 10 MHz ext. include ;***************************************************************************** ; Equates, I/O, vars ;***************************************************************************** RESET_V EQU 0x0000 ; Address of RESET Vector ISR_V EQU 0x0004 ; Address of Interrupt Vector CLOCKFREQ EQU .40000 ; 4 MHz X-tal used ;CLOCKFREQ EQU .100000 ; 10 Mhz X-tal used ; timing loop values ; must be from 1 to 255!!! if CLOCKFREQ == .40000 ;Values for 1. sec gate on 4Mhz T1 equ .251 ; first timing loop T2 equ .21 ; second timing loop T3 equ .21 ; third timing loop T4 equ .214 ; last timing loop else ; .100000 ;Values for 1. sec gate on 10Mhz T1 equ .251 ; first timing loop T2 equ .23 ; second timing loop T3 equ .48 ; third timing loop T4 equ .161 ; last timing loop endif ;***************************************************************************** ; Variable definitions ;***************************************************************************** CBLOCK 0x20 SCRATCH:.16 ; SCRATCH registers for sub usage TimerH ; the highest byte of SW counter LowB,MidB,HigB ; 24 bit resulting frequency R1,R2,R3 ; Timing Counters Count ; incremental register Help ; dummy register TEMP ; Another temporary register I_Hi,I_Lo ; Measurement Index (16bit) ENDC ;***************************************************************************** ; Program start ;***************************************************************************** ORG RESET_V ; RESET vector location RESET GOTO START ;***************************************************************************** ; This is the Periperal Interrupt routine. Should NOT get here ;***************************************************************************** ORG ISR_V ; Interrupt vector location INTERRUPT goto $ #define SERPORT GPIO ; Port used for serial output #define TXBIT 0 ; Bit used for serial output #define BDRATE .9600 ; requested Baud Rate #define MAXIM_USED 1 ; MAX232 level converter used include <../inc/serout.inc> #define B2A_RESULT (SCRATCH+.8) include <../inc/b242asc.inc> ;***************************************************************************** ; Initialize processor registers ;***************************************************************************** START ; POWER_ON Reset (Beginning of program) clrf STATUS ; Do initialization, Select bank 0 clrf INTCON ; Clear int-flags, Disable interrupts clrf PCLATH ; Keep in lower 2KByte clrf GPIO ; ALL PORT output should output Low. movlw 0x07 movwf CMCON ; Disable Comparator (switched off) bsf STATUS, RP0 ; Select bank 1 movlw b'10100111' ; Prescaler -> TMR0, movwf OPTION_REG ; 1:256, rising edge movlw b'1100' ; GP0-1 Output, GP2-3 input movwf TRISIO bcf STATUS, RP0 ; Select bank 0 call SERINIT ; Serial TX line idle clrf LowB ; 24 bit resulting frequency clrf MidB ; is stored in these tree clrf HigB clrf I_Hi ; Running counter (16bit) clrf I_Lo MainLoop movfw I_Lo ; Send serial number movwf B2A_Lo movfw I_Hi movwf B2A_Mi clrf B2A_Hi call B242ASC ; Call binary->ASCII conversion movfw B2A_d5 call SEROUT movfw B2A_d4 call SEROUT movfw B2A_d3 call SEROUT movfw B2A_d2 call SEROUT movfw B2A_d1 call SEROUT SNDCHAR ',' ; Separator movfw LowB ; First time we send 00000000 Hz movwf B2A_Lo ; then the actual measurements movfw MidB movwf B2A_Mi movfw HigB movwf B2A_Hi call B242ASC ; Call binary->ASCII conversion movfw B2A_d8 ; Send measured result over call SEROUT ; the serial line movfw B2A_d7 call SEROUT movfw B2A_d6 call SEROUT movfw B2A_d5 call SEROUT movfw B2A_d4 call SEROUT movfw B2A_d3 call SEROUT movfw B2A_d2 call SEROUT movfw B2A_d1 call SEROUT SNDCHAR .13 SNDCHAR .10 btfsc GPIO,3 ; 1 or 10 second measurements call M_Delay call Measure ; Do a new measurement incf I_Lo,F skpnz incf I_Hi,F goto MainLoop ;------------------------------------------------------------------------- ; It is time to prepare new measuring cycle ;------------------------------------------------------------------------- Measure clrf TimerH clrf TMR0 nop ; Suggested delay nop movlw T1 ; set initial counter values movwf R1 movlw T2 movwf R2 movlw T3 movwf R3 clrf INTCON ; global INT disable, TMR0 INT disable ; clear TMR0 overflow bit ; ------------------------------------------------------------------------ ; Start measurement: GP1 & GP2 set input ; ------------------------------------------------------------------------ #ifdef MAXIM_USED movlw b'101' ; GP2 Hi, GP1 Lo, GP0 RS-232 idle #else movlw b'100' ; GP2 Hi, GP1 Lo, GP0 RS-232 idle #endif movwf GPIO bsf STATUS,RP0 movlw b'1110' ; GPIO1..2 input movwf TRISIO ; STARTS THE COUNTING bcf STATUS,RP0 ; ------------------------------------------------------------------------- ; It is opened now... ; ------------------------------------------------------------------------- Cycle btfss INTCON,T0IF ; 1 Test for TMR0 overflow goto Nothing ; 3 incf TimerH,F ; 3 bcf INTCON,T0IF ; 4 goto Nxt ; 6 Nothing nop ; 4 nop ; 5 nop ; 6 Nxt decfsz R1,F ; 7 goto Cycle ; 9 movlw T1 ; 9*T1 movwf R1 ; 9*T1+1 decfsz R2,F ; 9*T1+2 goto Cycle ; 9*T1+4 movlw T2 ; (9*T1+4)*T2 movwf R2 ;(9*T1+4)*T2+1 decfsz R3,F ;(9*T1+4)*T2+2 goto Cycle ;(9*T1+4)*T2+4 ;((9*T1+4)*T2+4)*T3-1 ; ------------------------------------------------------------------------ ; Short fine tuning delay - enable it if needed..... ; ------------------------------------------------------------------------ ; movlw .1 ; movwf Help ;CCC ; decfsz Help,F ; goto CCC nop ;((9*T1+4)*T2+4)*T3 ; ------------------------------------------------------------------------ ; Final test for TMR0 overflow ; ------------------------------------------------------------------------ movlw T4 ;((9*T1+4)*T2+4)*T3 movwf Help ;((9*T1+4)*T2+4)*T3+1 ; N = 25 000 x fx = ((9*T1+4)*T2+4)*T3+1+(9+X)*T4+6 Cycle2 btfss INTCON,T0IF ; 1 goto Not2Do ; 3 incf TimerH,F ; 3 bcf INTCON,T0IF ; 4 goto Nx ; 6 Not2Do nop ; 4 nop ; 5 nop ; 6 Nx ; nop ; fine tuning nops ; nop ; nop decfsz Help,F ; 7+X goto Cycle2 ; 9+X ; ------------------------------------------------------------------------ ; Stop the measurement ; ------------------------------------------------------------------------ ; (9+X)*T4 #ifdef MAXIM_USED movlw b'101' ; 2 RA0..RA3 = 0 #else movlw b'100' ; GP2 Hi, GP1 Lo, GP0 RS-232 idle #endif movwf GPIO ; 3 W -> PORTA bsf STATUS,RP0 ; 4 movlw b'1100' ; 5 GP1 output movwf TRISIO ; 6 STOPS THE COUNTING bcf STATUS,RP0 ; ; ------------------------------------------------------------------------ ; Analyse precounter and store counted value in registers ; ------------------------------------------------------------------------ movf TMR0,W movwf MidB ; TMR0 -> MidB movf TimerH,W movwf HigB ; TimerH -> HigB clrf TEMP CountIt incf TEMP,F bsf GPIO,1 ; _| false impulse bcf GPIO,1 ; |_ bcf INTCON,T0IF movf TMR0,W ; actual TMR0 -> W bcf STATUS,Z subwf MidB,W btfsc STATUS,Z goto CountIt incf TEMP,F comf TEMP,F incf TEMP,F incf TEMP,W movwf LowB return ; Measurement completed ; ------------------------------------------------------------------------ ; 9 second delay ; ------------------------------------------------------------------------ M_Delay: movlw .9 addwf I_Lo,F ; Add 9 to running number skpnc incf I_Hi,F if CLOCKFREQ == .40000 movlw 0x51 ; 8999996 cycles movwf R1 ; 4 in call/return movlw 0x9F movwf R2 movlw 0x14 movwf R3 else ; == .100000 movlw 0xCD ;22500000 cycles movwf R1 movlw 0x0C movwf R2 movlw 0x32 movwf R3 endif _Delay decfsz R1, f goto $+2 decfsz R2, f goto $+2 decfsz R3, f goto _Delay return END