How to tune your crystal oscillator to get the best possible frequency accuracy

In our previous post How to compute crystal load capacitors using Python we investigated how to use UliEngineering to compute the appropriate load capacitor for your crystal oscillator.

Once you have manufactured your board, you should go one step further and tune your crystal oscillator.

Note that in this post we’re not talking about specialized compensated or heated crystals like TCXOs, DCXOs or OCXOs, but about your normal crystal which you use to clock your RTC, your microcontroller, your Ethernet PHY, your ADC, …

Also, this post is not made primarly for ppm hunters who desire to get below-±5ppm accuracy. While you certainly need to apply the techniques outlined here very carefully to get below your magic ppm number, they will likely not be sufficient.

Tuning the load capacitor

Note that for new PCBs, the stray PCB capacitance is just an educated guess – so your load capacitance will be slightly off.

First, you need to remember: Too low a load capacitance will result in higher frequency – too high a load capacitance will result in lower frequency.

I do not recommend to measure the PCB capacitance directly, because capacitances in the single picofarads are hard to measure accurately. Additionally, you can’t just measure them on a spare board without all the components (since the components, for example the case of the crystal, will affect the stray capacitance) but you also can’t just measure it on a fully populated board since the crystal itself will strongly influence your measurement.

Instead, just measure the  frequency of the crystal oscillator by measuring a reference clock output. The most appropriate instrument for that is a frequency counter with a sufficiently stable frequency source. Oscilloscopes typically don’t have the resolution required to measure a frequency down to the ppms. But if you have a microcontroller board with a sufficiently stable crystal.

Note that by attaching your probe to the crystal, you will load the crystal with additional capacitance from your probe, hence you won’t measure its actual frequency accurately. Do not probe your crystal directly but configure your RTC so that it generates a clock output on a separate pin and measure that.

Typically, your initially calculated load capacitor value will be within ±50% of the final value. Hence, you should buy approximately 5-20 standard values of capacitors within that range. Nowadays, buying 10 ceramic capacitors costs only around 0.15€ so just buying a buch of them is not really worth any consideration and you should just order them – or alternatively order a kit of capacitors. Note that standard capacitor values like 10pF or 6.2pF are often much cheaper than very specific values, so take care when selecting the values you buy.

For example, if you have a calculated load capacitor value of 7pF, you could order the following capacitors:

  • 3.5 pF
  • 4 pF
  • 5 pF
  • 6.2 pF
  • 7 pF
  • 8.2 pF
  • 10 pF

How accurately should you tune?

My recommendation on how accurately you should tune depends on whether exchanging components is the only type of tuning you can do or if your oscillator IC supports digital tuning. Since nowadays digital tuning is so easy and much more reproducible than changing components (due to tolerances etc)

If your RTC/controller does NOT support digital tuning: My recommendation is to tune no more than 2.5 times the specified accuracy of the crystal. So if your crystal has specified tolance of ±20ppm, in most applications you should tune to ±50ppm

If your controller supports digital tuning but not autotuning: My recommendation is to tune no more than 4 times the specified accuracy of the crystal. So if your crystal has specified tolance of ±20ppm, in most applications you should tune to ±80ppm

If your controller supports digital autotuning: My recommendation is to tune to Digital adjustment range / 1.5

In any case, remember that it’s a tradeoff between your time improving the product and slight inaccuracies that might

Digitally tuning the frequency

Many controllers and RTCs nowadays feature a circuit to digitally tune the frequency to up to sub-ppm levels using e.g. I2C access. Internally, this works by omitting or adding pulses to an internal clock every now and then, effectively decreasing or increasing the average frequency of the clock.

Note that you can’t just infinitely adjust using digital adjustment, a typical adjustment range will be ±100ppm to ±500ppm.

The most primitive variant is to just use the register where you enter how many PPMs up or down the frequency should be adjusted, do it once for your prototype and hope that your production run won’t be significantly different. In this case, you have little choice but to take your frequency counter, measure the frequency. Note that digital adjustment does not change the frequency of the crystal at all, but typically the reference output is digitally adjusted. Note however, that the adjustment might only happen every few minutes (read your RTC datasheet or reference manual for more info). The only way to reliably check if the change is effective is by letting the board run for a few days and observe how much it drifted compared to a reference clock.

A more advanced, albeit much harder to implement variant is to use a different (more accurate) reference clock source like an accurate oscillator or even OCXO, or a clock derived from USB (which some STM32 microcontrollers can do) or the power grid (which is not very accurate over short time spans but is very accurate over long time spans), implement a frequency counter in your MCU and automatically adjust the digital tuning parameters. The implementation of this highly depends on which MCU you are using and would exceed the scope of this post.