|A PIC 16F627 is used to lock a 2MHz crystal although other
frequencies can also be used. The internal T0 counter and the pulse-width
modulation (PWM) module of the PIC are
exploited. The technique is as follows:|
T0 is an 8-bit counter which, when enabled, increments at a rate set by the internal cpu clock frequency. T0 creates an interrupt each time the counter register overflows. The interrupt service routine (isr) preloads the counter with a fixed number (nominally 6, but see below for details) every time T0 overflows so that successive overflows occur every 250 counts (equivalent to cpu clock cycles). The cpu clock is derived from an external 2MHz VXO, which is tuned over a narrow range by a varactor diode. Inside the PIC, the external clock input is divided by 4 to provide the cpu clock. The result of this is that the internal clock is at 500kHz, and interrupts occur every 500us (2kHz). Because the T0 counter register runs continuously, its contents represent a running total of quarter-milliseconds, mod 250, and this is a continuous count of the VXO cycles, divided by 1,000.
loop filter of any
pll system is crucial to satisfactory operation. In this design
the filter consists of a 100uF tantalum capacitor with a 220kOhm
resistor in a first-order LPF configuration. A 10k resistor
in series with the cap (between the cap
and ground) to increase damping. Damping is not optimal, but is
adequate (see right; this shows the locking transient following a
completely cold start, including the capture time of the GPS receiver).|
An op-amp amplifier with a voltage gain of about 3 is included in the loop. In my implementation of the design, the op-amp is powered from a MAX232 chip which provides +/-9v supplies from a single 5v input. This allows a useful but only moderate increase in the range of the control voltage (from about 5v maximum from the PWM module, to about 8v). Under these conditions it is possible for the op-amp to saturate, so the average of the PWM output (i.e. its filtered, dc value) must always be in a rather low range, well below its maximum value of 5v. This means that if the high phase of the PWM signal is controlled by T0, there will be a rather coarse, low-resolution control, whereas if T0 controls the PWM period instead, T0 can range up to its maximum value (256) without causing the op-amp to saturate. This allows better resolution, and has therefore been adopted. The steady-state value of T0, and of the control voltage is adjusted by a trimmer in the VXO.
The software can be downloaded using this link. Astonishingly, the basic system uses just 49 bytes of assembled opcodes, but if the lock indicator is added this increases to 56 bytes. To my mind this system is amazingly simple and efficient.
The software is so simple that the explanation given above is
adequate. However, there is one subtlety that is
worth mentioning in case anyone feels inclined to meddle, or to apply
the principle in another context:-|
Ideally, when T0 reaches a value of 255 and overflows, it should be immediately reset to 6 so that the counting cycle repeats after 250 increments. However, the inherent interrupt latency, and the execution of the isr instructions prior to the write to T0 introduce a delay, so that it is impossible to reset T0 immediately. In this isr, the total delay amounts to 12 cpu clock cycles (including 2 NOPs). So T0 is pre-loaded with 18 instead of just 6. The NOPs are included to make the total latency an integral number of T0 increments when the T0 prescaler is used at its 2:1 or 4:1 settings. These were experimented with, but the 1:1 setting finally used. If the NOPs are deleted, the pre-load value must be reduced to 16.