Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

cap values for crystal

Status
Not open for further replies.

mactack

New Member
hello,

as mentioned in a previous post, I am building a digital clock with a pic. I got a 20 Mhz crystal and 20pF caps. Everything works but the clock gains about a second every 6 hours. Now, I read two things that seem to contradict each other, one source says that bigger caps would provide more accuracy at the cost of longer startup time while another says we should use the smallest possible values specified by the microcontroller datasheet (I've also read that cap values depend on the crystal, not the micro...).


So, does anyone have any thoughts on that? Should I go get bigger caps? Is 1 sec. every 6 hours what I should expect in terms of accuracy from the crystal? Should I try another crystal?


Thanks
 
A crystal wants to be loaded with whatever capacitance is specified in its data sheet, and doesn't directly depend on the oscillator circuit.

Keep in mind that the load capacitance also includes parasitic capacitances from the PIC pins and traces between the PIC. Putting the wrong load capacitance on a crystal will cause it to operate out of spec... Additionally, picking the wrong type of crystal (series resonant, or overtone) will also cause issues.

BTW, a bare 20MHz crystal is going to have relatively "lousy" accuracy. Better are 32.768KHz crystals meant for clocks, or just get a TCXO oscillator that is ~USD $10 and will keep 3ppm accuracy over a range of temperature changes.

Timing accuracy is specified in parts per million: 1 sec every 6 hours (21600) is 1/21600 = .000046 => 46ppm, which is within spec of a normal oscillator (100ppm is the usual round number). The 32.768KHz crystals are usually 20ppm or so, TCXO's are in the 3ppm range, and ovenized bricks that are used in telcom are in the .0x ppm range.

James
 
Software version of Xtal Oscillator Trimmer Capacitor

Normally I use a ceramic trimmer capacitor in the crystal oscillator circuit to 'tune' the oscillator frequency while listening to it on my Icom 756PROII receiver with its built-in 0.5-ppm time base. Last year I tried a "software" trimmer capacitor in a couple projects and so far it's proven very reliable and accurate for TMR2 driven RTC applications.

The "software" trimmer code for 20-MHz crystal oscillator consists of 8 instruction words in two locations within the ISR;
Code:
;
;  ISR_Trim routine is used to adjust the RTC 1-second period to
;  within plus or minus 200-nsecs to make up for a crystal which
;  may be slightly off frequency.  The routine adds or subtracts
;  one 200-nsec count (1 Tcyc) from Timer 2 for the first 'CCTR'
;  number of 1-msec interrupts each second. Theoretical accuracy
;  to within 6.3 secs/year, not including temperature drift and
;  crystal aging.
;
;   variables:  CCNT, correction count from EEPROM [00 to FF]
;               CVAL, correction value from EEPROM [FF or 01]
;               CCTR, correction counter reloaded from 'CCNT'
;                     variable each 1-second period
;
;       range:  ±255 200-nsec counts/second (±51.0 usecs/sec)
;
ISR_Trim
       movf    CCTR,W          ; correction counter 0?           |B0
       bz      ISR_Sw_Input    ; yes, branch, else               |B0
       decf    CCTR,f          ; decrement counter               |B0
       movf    CVAL,W          ; get correction value FF or 01   |B0
       addwf   TMR2,f          ; apply 1 Tcyc timer correction   |B0
;
ISR_Sw_Input
I reset the CCTR 'correction counter' var with the CCNT 'correction count' value after each 1-second RTC period a little further down in my ISR;
Code:
;
;  the Real Time Clock 1-second 'heartbeat' timer/counter code
;  counts 1,000 1-msec interrupts before performing all of the
;  once-per-second procedures and functions
;
ISR_RTC    
       decfsz  RTCL,f          ; RTC counter lo = 0?             |B0
       goto    ISR_Calibrate   ; no, branch, else                |B0
       movlw   d'250'          ;                                 |B0
       movwf   RTCL            ; reset RTCL for 250-msecs        |B0
       decfsz  RTCH,f          ; all four 250-msec periods?      |B0
       goto    ISR_Calibrate   ; no, branch, else                |B0
       bsf     RTCH,2          ; reset RTCH for 4 (x 250)        |B0
;
;  reload timer Trim correction counter
;
       movf    CCNT,W          ; reload correction counter var   |B0
       movwf   CCTR            ;                                 |B0
;
A couple caveats apply when using the code; (1) writing to TMR2 clears the prescaler and postscaler but I don't use the prescaler and the postscaler hasn't yet incremented when I write TMR2, (2) You can apply the correction to shorter overall periods (100-msecs, 200-msecs, etc.) as long as the correction to your particular crystal can be accomplished within the shorter period.

Adjusting the CVAL 'correction value' and CCNT 'correction count' values and saving them to EEPROM is entirely up to you. In one of my projects I use a PCB jumper to display the values, a rotary encoder to edit them, and then remove the PCB jumper to save the edited values back to EEPROM.

Have fun. Kind regards, Mike
 
Last edited:
Software compensation is a good way of getting rid of the static frequency error, but crystals are very sensitive to temperature - I think typical crystals will vary by ~1ppm/deg C, with 32KHz crystals varying less over temperature. The compensation curves also shaped differently.

If you were so inclined, you could mount a thermistor next to the crystal and have a table of compenstation values based on temperature. Obviously calibrating such an apparatus is a pain in the neck.

Alternatively build a oven around the crystal and maintain the temperature with a heater.
 
You're right. Temperature drift and crystal aging seem to keep the accuracy of my "software trimmer" projects to within plus or minus 1/2 second when I check them every two months.

If plus/minus 6 seconds per year isn't good enough for your application, spend the $15 for a 2-ppm 10-MHz TCXO.
 
From what I've heard, using a different capacitance than specified will always change the freq from its spec. Going one way makes it run too fast, the other way too slow, but I forgot whether a bigger cap was too fast or too slow.

Now don't forget that since the capacitance affects the xtal freq a bit, +/-20% caps and cap temp coefficients will affect the xtal accuracy.

But the software clock calibration works fine except for the temp coefficient. Just make the clock lose a sec every 6 hrs to compensate for the xtal being 1 sec off.
 
great, I thought software adjustments would be a lazy way to compensate but reading what you guys have to say about it makes it look alot better :)

Besides, I don't really feel like spending 10-15$ extra on it (the clock), and plus/minus 6 sec. a year is more than what I was aiming for.

I might change the crystal for a 3.768 though...
 
Just as a point of reference (and happen to be in the US), TCXO's meant for cellphone apps aren't that expensive compared to normal oscillators: 300-1100-1-ND, 13MHz, 2.8V operation, $7.50 qty 1, 1.5ppm accuracy at 25C, +2.5ppm over a -30C to 75C, and an adjustment that allows 8ppm worth of adjustment. And Massive overkill for a simple clock...
 
Could this be forgetting to count zero?

This maybe coincidence, but 1 second in 6 hours is very close to an error of 1 in 20,000. Are you perhaps generating a 1mS (20,000 clock cycles) interrupt and loading a register with 20,000 instead of 19,999 or vice versa?

Mike.
 
Pommie said:
This maybe coincidence, but 1 second in 6 hours is very close to an error of 1 in 20,000. Are you perhaps generating a 1mS (20,000 clock cycles) interrupt and loading a register with 20,000 instead of 19,999 or vice versa?

Mike.

Nope, but seeing that is quite a display of perspicacity!
 
There's a new word to add to my lexicon. I like the idea of being perspicacious.

TBH, it wasn't that insightful, I had the same error when designing some timing lights and the above turned out to be the problem.:D

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top