; ------------------------------------------------------------------------ ; ; Title: ; ; PD85 -- PIC "4-pin" 15.36 MHz to 1PPS frequency divider, with sync ; ; Function: ; ; This PIC program implements a digital frequency divider: the external ; 15.36 MHz input clock is divided to 1 Hz (1PPS). ; ; The output is a narrow 10 millisecond pulse (not a 50% square wave). ; ; Diagram: ; ---__--- ; 5V (Vdd) +++++|1 8|===== Ground (Vss) ; 15.36 MHz clock in ---->|2 pD 7|----> 1PPS out (10 ms) ; *|3 85 6|* ; Arm o--->|4 5|<+--- Sync ; -------- ; Notes: ; ; Only 4 pins are required: power (2.0-5.5V), ground, input and output. ; Optional 1PPS synchronization uses 2 additional inputs: Arm and Sync. ; o External pull-up required on Arm input (pin4/GP3). ; + Sync input (pin5/GP2) has internal WPU. ; * For added drive power, pin3/GP4 and pin6/GP1 are also outputs. ; Output frequency accuracy is the same as clock input accuracy. ; Output drive current is 25 mA maximum per pin. ; Coded for Microchip 12F675 but any '609 '615 '629 '635 '675 '683 works. ; ; Version: ; ; 21-Aug-2022 Tom Van Baak (tvb) www.LeapSecond.com/pic ; ; ------------------------------------------------------------------------ ; Microchip MPLAB IDE assembler code (mpasm). list p=pic12f675 include p12f675.inc __config _EC_OSC & _MCLRE_OFF & _WDT_OFF ; Register definitions. cblock 0x20 ; define register base endc ; Define entry points. org 0 ; power-on entry goto init ; org 4 ; interrupt entry goto sync ; ; One-time PIC 12F675 initialization. init: bcf STATUS,RP0 ; bank 0 clrf GPIO ; set all pins low movlw 07h ; set mode to turn movwf CMCON ; comparator off errorlevel -302 bsf STATUS,RP0 ; bank 1 clrf ANSEL ; set digital IO (no analog A/D) movlw b'101100' ; set GP0,GP1,GP4 as output(0) and movwf TRISIO ; other pins are input(1) movlw 1< output pin(s) call Delay4 ; ( 4) sync alignment sync: call armed ; ( 5) check for Arm request movlw d'3' ; ( 1) call DelayW10k ; ( 30000) delay W*10000 movlw d'83' ; ( 1) call DelayW100 ; ( 8300) delay W*100 movlw d'84' ; ( 1) call DelayW1 ; ( 84) delay (15 <= W <= 255) goto fall ; ( 2) ; Set output low for 990 ms = 3,801,600 Tcy at 15.36 MHz. fall: movlw 0x00 ; ( 1) low output movwf GPIO ; ( 1) W -> output pin(s) movlw d'250' ; ( 1) call DelayW10k ; (2500000) delay W*10000 movlw d'130' ; ( 1) call DelayW10k ; (1300000) delay W*10000 movlw d'15' ; ( 1) call DelayW100 ; ( 1500) delay W*100 movlw d'92' ; ( 1) call DelayW1 ; ( 92) delay (15 <= W <= 255) goto rise ; ( 2) ; Implement two-pin 1PPS Arm-Sync synchronization protocol. ; - Caller checks Arm (low) request when output(s) are high. ; - Use GP2/INT interrupt to keep accuracy within 1 Tcy. ; - Divider resets and resumes on rising edge of Sync pin. ; - Re-enter main loop late to compensate for interrupt/code latency. armed: btfsc GPIO,GP3 ; Arm pin low? return ; no, continue running movlw 1<