Basics of Design Research & Design Hub

A Look at Homemade TCXOs – Crystal Crafting

Written by Robert Lacoste

Robert has covered crystal oscillators (XOs) before in this column. In this article, he returns to the topic, this time exploring temperature-compensated XOs, with a look at, not only how they’re made, but also how you can build one inexpensively.

  • How build temperature compensated crystal oscillators
  • How do TCXOs (Temperature Compensated Crystal Oscillator) work
  • How temperature stabilization works in an XO
  • How to design the TCXO circuit
  • How to use the “Ready for PIC” development board as a prototype
  • QUCS circuit simulator
  • Microchip PIC16F1788 MCU
  • NXP BB156 varicap diode
  • TI LM35 precision temperature sensor
  • Ready for PIC (DIP28) development board from MikroE
  • Keysight 53230A frequency meter

Welcome back to “The Darker Side.” You may recall that in one of the first articles in this column, I talked about crystal oscillators (“Let’s Be Crystal Clear”, Circuit Cellar 215, June 2008). In particular, I explained that crystal oscillators are very stable, but that their output frequency is nevertheless temperature dependent.

This month, I propose to return to this topic: discussing how to improve the temperature stability of a crystal oscillator (XO for short). My specific objective is to explain what TCXOs (Temperature Compensated Crystal Oscillator) are, and how they are built. I will even show you how to actually transform a classic microcontroller (MCU) crystal into a TCXO for less than $2.

Let’s start with a short recap. A quartz crystal mechanically shrinks or inflates, depending on a voltage applied between its two faces, thanks to the piezoelectric effect. So, if you apply an AC signal rather than a continuous voltage between its legs, the crystal vibrates at the frequency of the signal. And then something interesting happens when the signal frequency is precisely equal to the mechanical resonance frequency of the crystal. Its electrical behavior changes. More exactly, it shows a very sharp change in impedance.

This property allows us to build precise oscillators, which are locked on this mechanical resonance frequency. That’s why crystals are commonly used as reference clocks for countless electronic devices. In particular, MCUs include a so-called Pierce CMOS oscillator circuit, built with a simple logic inverter gate. Figure 1 shows the typical configuration of such an oscillator. As a designer, all you have to do is connect a crystal between two dedicated pins of the MCU, and add two small capacitors (usually 20pF or so) between the crystal pins and the ground. But what are these capacitors for?

FIGURE 1 – A basic crystal oscillator built around a CMOS inverter gate

To understand that, you must know the electrical equivalent model of a crystal. Close to its resonant frequency, a crystal behaves as a serial RLC network in parallel with a capacitor. For example, the electrical model of a typical 10MHz crystal is represented in Figure 2 (top left). Here we have 0.025H + 0.01pF + 640Ω, in parallel with 2.5pF. The values of these components are quite unusual, but that’s how a crystal is modeled.

FIGURE 2 – A crystal can be electrically modeled as an RLC serial network. The frequency of the parallel-mode resonance (higher impedance so lower transfer ratio) varies when adding an external capacitor.

I entered this circuit in QUCS (QUCS is good circuit simulator…and free!) [2], added a sine source and a load resistor R2 and clicked on “run.” The result is shown in Figure 2 (top right): There is not one but two resonant frequencies. The first one is at 10.066MHz, and shows a minimum impedance. The second is a little higher in frequency, at 10.085MHz, and shows a maximum impedance. These two frequencies are, respectively, the serial resonance (lower impedance) and parallel resonance (higher impedance). Therefore, every crystal can be excited in either of these modes, depending on the schematic of the oscillator that surrounds it. These resonant frequencies are close but not exactly identical. That’s why crystal manufacturers sell “serial” and “parallel” crystals. Don’t be confused. They can all be used in either mode. But there will be a small frequency shift if you use it in mode that wasn’t specified.


Advertise Here

Now let’s focus on parallel mode, which is the one used by CMOS oscillators. What happens if you add an external small capacitor between the two legs of the crystal? Refer to Figure 2 (bottom), where I added 10pF and re-ran the simulation. The serial resonance frequency is unchanged, but the parallel resonance comes closer to the serial resonance, here at 10.007MHz. That’s a problem, isn’t it, because the XO frequency would be dependent on any external parasitic capacitance? With that in mind, crystal manufacturers specify for each “parallel” crystal what external capacitance must be added between its two legs to get the exact frequency written on the device. This capacitance is usually around 10pF.

And now you know the purpose of the two small 20pF capacitors that exist on every CMOS oscillator They are, in fact, serially connected through the ground, and 20pF + 20pF in series makes 10pF. Using two capacitors rather than one also helps to stabilize the oscillations. That’s why there are always two capacitors close to an MCU crystal (Figure 3).

FIGURE 3 – The 8MHz crystal and its two 22pF capacitors on the MikroE 24-pin PIC development board.

Now let’s look at temperature stability. The dimensions of a crystal are altered slightly when the temperature changes, and so are its resonant frequencies. Assume that your design must work outdoors, with a temperature of -20°C to +70°C. Depending on your budget, you may find 10MHz crystals with guaranteed temperature stability from ±10ppm to ±100ppm for the above temperature range. Is it enough? Well, 10ppm means 10 parts per million, so the very best 10MHz crystals will have a temperature-related frequency variation of 10MHz × 10/1,000,000 = ±100Hz.

The variation is small, but this may be too much for your project. If you build a clock, 10ppm means an error of ±5 minutes per year. And if the same crystal is driving an 868MHz wireless transmitter, that’s a variation of ±8.68kHz, which may jeopardize both communications and regulatory compliance, if you are using narrow channels. Don’t forget: This would be 10 times more when using low-cost crystals.

Last but not least, these examples are only related to temperature drift. In other words, a crystal will also have initial frequency error, and will drift over time even if the temperature is stable (“aging”). These errors will add to the temperature-related drifts.

So, how to improve the temperature stability of an XO? First, crystal manufacturers know how to reduce this variation for a given temperature range. They do so by cutting the crystal at precisely defined angles versus its crystallographic axis. For example, the standard AT cut, commonly used for low-frequency crystals, maximizes the stability around ambient temperature. So, a crystal cut at exactly the proper angle is more stable than others, and that’s why it will be more expensive.

However, two other techniques can markedly improve temperature stability. The best one is to avoid all crystal temperature variations using an Oven Controlled Crystal Oscillator (OCXO). Here, the crystal is enclosed in a small temperature-controlled chamber and heated to a stable temperature. Temperature stability better than 0.01ppm (10ppb) is commonly achieved, but the trade-off is increased energy consumption.

The second technique is less accurate but is far more energy saving. The idea is to measure the actual temperature, and then to compensate for the frequency of the oscillator based on this temperature. How is this possible? By knowing the temperature-to-frequency dependency of the crystal. Such oscillators are named Temperature Compensated Crystal Oscillators (TCXOs). Commercial TCXOs provide a temperature stability of ±0.1 to ±3ppm. That’s much worse than an OCXO, but far better than a plain XO.

Buying an off-the-shelf TCXO is probably the best solution for commercial projects. But why not try to build one from scratch? For example, how do you improve the temperature stability of the 8MHz crystal oscillator driving a Microchip PIC16F1788 MCU using as few as possible external parts? In fact, it can be done with less than $2 or extra parts. Figure 4 shows how I did it. All the modules included in the dashed box are internal to the PIC MCU. Let’s see how this works.


Advertise Here

FIGURE 4 – The full schematics of my experimental mock-up. All the blocks included in the dashed box are inside the PIC 16F1788 MCU.

First, there is the XO itself—made with a standard 8MHz quartz crystal (X1) wired to the OSC1 and OSC2 pins as usual. There are also the two classic loading capacitors C1 and C2, but with a trick. An extra component, D1, is connected between C1 and the ground. This is the only exotic part of the schematic: A varicap diode. Such a diode, when polarized with a reverse DC voltage, acts as a small capacitor. And its capacitance is a function of the DC voltage.

Here I used a BB156 from NXP Semiconductor, which has a capacitance going from 18pF down to 6pF when the voltage is increased from 0V to +5V. Remember that the frequency of a parallel mode XO is dependent on the value of the loading capacitor. So, adding a varicap on one leg of the crystal allows us to fine-tune its frequency by applying a varying DC voltage! This makes a Voltage-Controlled Crystal Oscillator (VCXO). The possible frequency variation is small (some ppm), but will still allow a TCXO to be built, as I will explain in a minute.

Going back to the schematic shown in Figure 4, you can see that the DC voltage comes from an 8-bit digital-to-analog converter (DAC). This DAC is built into the PIC. The DAC output voltage is applied to D1 through an inductor (L1), which block the 8MHz signal. I even used another built-in block of the PIC, an operational amplifier, to buffer the DAC output. With this configuration, the crystal frequency can be fine-tuned from the firmware running on the PIC, simply by changing the DAC value.

I also needed a way to measure the crystal temperature precisely. A precision LM35 analog temperature sensor from Texas Instruments (U1) does the job. This sensor generates a voltage of 10mV per °C, so from -0.2V to +0.7V for -20°C to +70°C its 0.5°C accuracy was good enough. I wanted to measure this temperature using the 12-bit ADC provided in the PIC, but how would I manage sensor output voltages that could be negative? A small trick helps. A diode (D2) is added between U1 and the ground, and adds a voltage drop of about 0.6V. As a result, the output of U1 is now always positive with respect to ground. Both this output voltage and the voltage on D2 are connected to two ADC inputs. Their difference is the temperature, and the voltage drop on D2 doesn’t affect the measurement. By the way, the PIC also has an internal 4.096V voltage reference (FVR), which sets the ADC full-range.

Finally, I wanted to measure the actual crystal oscillator frequency with a lab frequency meter to check if the design was working. It would be a very bad idea to connect the frequency meter directly to the crystal oscillator pins. And you know why. The meter connection would introduce a parasitic capacitance, which would change the oscillator frequency. Fortunately, this PIC has another built-in block, a clock divider module (CLKREF). This one takes the clock frequency, divides it by a given number (8 in this case), and routes the resulting clock on an external pin. Exactly what I needed! I added a 47Ω resistor (R1) to match the 50Ω input of the frequency meter—and that’s all folks.

Rather than designing a custom PCB, I ordered a “Ready for PIC” 28-pin development board from MikroE. I replaced the supplied MCU with a PIC16F1788, and soldered the few extra components on its prototyping area (Figure 5). But some specific care must be taken here.

FIGURE 5 – My assembled prototype. Very few parts indeed.

First, for good results, the temperature sensor must measure the temperature of the crystal, not the ambient air. Therefore, I tried to fix the LM35 directly onto the crystal body as shown in Figure 5. OK, this was probably far from perfect. Gluing the crystal and quartz together or even building a kind of small temperature chamber around these two components would have been far better.

Second, the assembly must minimize as much as possible the parasitic capacitance around the crystal and between the varicap diode D1 and the DC bias inductor L1. If not, the varicap variation will be far smaller than planned, since the parasitic capacitors will dominate. Also, the XO simply might not run.

Figure 6 shows how I did it. I soldered D1 and C1 in a “tent-shape” arrangement directly on the original capacitor pads. Then I connected them to an SMT inductor (L1), using a small thin wire routed as far as possible from the ground plane, to reduce capacitance. Playing with small SMT components is fun, as long as you have a good binocular lens and avoid strong coffee a few hours before picking up the soldering iron.

FIGURE 6 – A close-up view of the SMD assembly. Quite easy to solder as long as you have a good binocular lens.

The last job was to develop some firmware for the PIC, emulating a TCXO compensation loop. Fortunately, Microchip provides very efficient tools for that. I started by downloading from the latest version of MPLAB IDE and XC8 compiler. (It was more than 1.5GB of code, so I guess it was an order of magnitude thinner the last time I used MPLAB.) I then launched the MCC (MPLAB Code Configurator) plug-in, which allowed me to generate all the code needed for the PIC internal modules: ADC, DAC, CLKREF, FVR, OPA, EUSART and so on. This step took less than 10 minutes (Figure 7).

FIGURE 7 – Shown here is Microchip’s MPLAB Code Configurator in action

I coded the actual TCXO emulation routine in C. Because I just wanted to validate the concept, I implemented a simple UART-driven command set: read the temperature; manually set the DAC to a given value; download an 8-point temperature compensation table in RAM; and run the compensation algorithm. This allowed me to connect a laptop to the board and easily do all experiments using terminal emulation software.

The C code, freely downloadable from Circuit Cellar’s article code and files webpage, is more a starting point for an actual TCXO implementation than a bullet-proof implementation. I didn’t store the compensation table in non-volatile memory, but I guess you would be able to do this by yourself! Anyway, I encourage you to read this source code, which is just two pages long. The main compensation loop is given in Listing 1 and is straightforward: The DAC value is linearly interpolated, based on the current temperature and the two closest values of the compensation table. Figure 8 shows the firmware output while running, including my compensation table values.

LISTING 1 – These lines of code are implementing the TCXO main loop, including linear regression.

case 'R':
printf("\n\n RUN - any key to stop\n\r");
printf("ADC=%d -> ",v);

// linear regression
if (v<tabadc[0])
if (tabadc[i]==0)

FIGURE 8 – An example of the firmware output when the loop is active, shown here during a heat-up test.

Next, it was time to test if the concept was working, and to determine what stability improvement could be achieved. I didn’t have a proper temperature test chamber around, so I requisitioned the kitchen—the fridge and the oven (Figure 9) were enough to test from 0 to 100°C. I put the board at different temperatures, let it stabilize and manually changed the DAC setting until the frequency was the one I wanted.


Advertise Here

FIGURE 9 – Tests can be done without expensive temperature chambers. In fact, you just need a PC, a frequency meter and a kitchen.

For the frequency measurement, I used a nice Agilent (now Keysight) 53230A frequency meter. This test gave me the required values for the calibration table. I then launched the compensation loop routine, and gently heated the board through the full temperature range while measuring the clock frequency. The result is summarized in Figure 10. The Y-axis is the output frequency (8MHz clock divided by 8 by the REFCLK block), and the X-axis is the ADC value which is proportional to the temperature (1,000 = 0°C, 2,000 = 100°C). The dotted lines show the measured stability of the XO for various DAC settings, without the temperature compensation routine. I measured a variation around 20Hz (20ppm) for a 100°C temperature difference. The unbroken line shows that the stability was improved to about 4Hz (4ppm) with temperature compensation running.

FIGURE 10 – The dotted lines show the oscillator frequency dependence on temperature (6°C to 60°C) for five DAC settings. The plain line shows the oscillator stability when the TCXO firmware is running.

Because the Keysight 53230A frequency meter has a nice graph feature, it was possible to visualize the evolution of the output frequency when the board was quickly heated (Figure 11). The plot shows the behavior of the TCXO. The output frequency increases linearly over time, and jumps down when the DAC value is decremented by the firmware, trying to compensate for this variation.

FIGURE 11 – A close view on the output frequency across time during a heat-up test. The small vertical steps are the results of DAC value change while the firmware loop detected a temperature change.

Of course, a 4ppm stability is not as good as a precision, off-the-shelf TCXO, but this experiment shows you how a temperature compensation could be implemented around a standard low-cost crystal. I didn’t try to optimize the design, because my only objective was to show you the concept. I suspect that the first cause of the remaining frequency error in this experiment was the low-quality thermal contact between the crystal and the temperature sensor. This was clearly visible during my tests, because the frequency error was the other way around when the temperature was going up or down. One of the two components probably had a different thermal latency.

Anyway, I hope this gave you some ideas for your next project. As usual, don’t hesitate to try it for yourself. And if you succeed in building an ultra-precise TCXO, then just write how you did it, and send your article to Circuit Cellar for publication! 



[1] The Darker Side – “Let’s Be Crystal Clear”, Circuit Cellar 215, June 2008
[2] QUCS (Quite universal circuit simulator)

Crystal oscillators

“Design a Crystal Oscillator to Match Your Application”
Theron Jones, Maxim, tutorial 5265

“Quartz Crystals”
Electronic Notes

“Quartz crystal stability: how myths and misconceptions mask good value”

PIC16F1788 microcontroller

BB156 varicap diode

LM35 precision temperature sensor
Texas Instruments

Ready for PIC (DIP28) development board

53230A frequency meter

IQD Frequency Products |
Keysight Technologies |
Maxim Integrated |
Microchip Technology |
MikroE |
NXP Semiconductors |
Texas Instruments |


Don't miss out on upcoming issues of Circuit Cellar. Subscribe today!

Note: We’ve made the October 2017 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Become a Sponsor
Founder at Alciom | + posts

Robert Lacoste, France (Founder, Alciom; Columnist, Circuit Cellar)