Getting an accurate clock with a crystal - Page 1
Forum section: electronics / projects

author: PCChazter
author_rank: Contributor
timestamp: May 14, 2017, 11:05:31 pm
content: Hello forum,I am trying to set up a TMS320F28027 C2000 microcontroller to act as an RTC for use in other functions on the chip. I have a crystal hooked up, and set up Timer2 to use the crystal. It seems to work, but I am not getting the accuracy that I am looking for.It uses a 12 Mhz crystal that is supposed to be 15ppm, and I calculated the load capacitors to be 6pF using the formula C = 2(CL - Cstray), assuming 5pF Cstray, CL is 8pF.The timer has a 11999 prescaler, which means the timer should count every 1ms * period, which means it should trigger every second, which just adds 1 to a 32 bit number. It seems that after 20 hours, it is 20 seconds out, which is 0.0556% or 556ppm, not even close to the expected 15ppm!This is the first time I have implemented a crystal in my design, so I'm not 100% sure I am doing it right, or really what accuracy I should be able to expect.Anyways, does anyone have any ideas or advice as to why I'm not getting the accuracy I need, or is my expectation unreal, and I should just get a dedicated clock chip? I would prefer to not have a separate chip if at all possible.The crystal:https://www.digikey.ca/product-detail/en/avx-corp-kyocera-corp/CX3225SB12000D0GZJC1/1253-1696-1-ND/5995243The Capacitors:https://www.digikey.ca/product-detail/en/tdk-corporation/C1608C0G1H060D080AA/445-5037-1-ND/2093652The (relevant) board layout:The code:Code:uint32_t clock_period = 1000; //in msuint32_t clock_time_s = 0; //in suint32_t clock_time_s_offset = 0;void initClockTimer(){myTimer2 = TIMER_init((void *)TIMER2_BASE_ADDR, (size_t)sizeof(TIMER_Obj));EALLOW;PIE_registerSystemIntHandler(myPie, PIE_SystemInterrupts_TINT2, (intVec_t) &clockInterrupt);EDIS;TIMER_stop(myTimer2);CLK_setTimer2Src(myClk, CLK_Timer2Src_ExtOsc);TIMER_setPeriod(myTimer2, clock_period);TIMER_setPreScaler(myTimer2, 11999);TIMER_reload(myTimer2);TIMER_setEmulationMode(myTimer2, TIMER_EmulationMode_RunFree);TIMER_enableInt(myTimer2);TIMER_start(myTimer2);CPU_enableInt(myCpu, CPU_IntNumber_14);Clock_setPosixTime(1447459200);}void Clock_setPosixTime(uint32_t t){clock_time_s_offset = t - clock_time_s;}#pragma CODE_SECTION(clockInterrupt, "ramfuncs");__interrupt void clockInterrupt(void){GPIO_toggle(myGpio, GPIO_Number_0);clock_time_s++;}

author: pigrew
author_rank: Frequent Contributor
timestamp: May 14, 2017, 11:16:49 pm
content: In designs I'd been doing, I've also had trouble having the crystals be in specification at first. I've been tweaking the capacitor values until the clock is correct. Usually a larger capacitor will make the clock run more slowly.5pF of stay capacitance sounds too high. I'd expect more like 1 or 2 pF.I measure the frequency using a frequency counter. I never probe the crystal directly, I program a PWM signal as a clock divider, and use that to measure the clock by proxy.I see that you have a acute angle in your layout. It's best to avoid them. Also, the ground layout doesn't look so great. I'd add some ground vias around the crystal and load caps to connect to the micro's ground more directly.I'm not sure about your micro, but make sure you are properly enabling the crystal, and not using an internal oscillator.Also, the high frequency clock is going to be power hungry. Generally people use a lower frequency oscillator for accurate timing, as they are lower power.

author: PCChazter
author_rank: Contributor
timestamp: May 14, 2017, 11:42:00 pm
content: I guess I should have mentioned, it is 20 seconds slow, so I don't think a larger cap would help. I have also tried taking the caps right off, as well as using a 10pF ,and a 10pF with a 6pF in parallel, none of it seemed seem to change much. I also had another crystal that specifies 18pF CL, and that did not seem to change it enough to get it to stop being slow.Unfortunately, I don't have an oscilloscope (yet, it's been on my list for alongtime), so the best way I have to check it is to let it run for 10+ hours and see how off my time is.Like I said, I haven't used a crystal before, so this is a learning experience for me! I used 5pF because that's just what a few pages I looked at said. I would hope that it would only be 1 or 2 pF, but I probably have a problem in my design, cause it almost seems like more...You say acute angles are bad, which ones in particular look bad to you?I'm fairly certain I am turning on and using the crystal correctly, but I can go through my code and make sure. Wouldn't that be a pain to find out I've actually been using the internal oscillator...

author: pigrew
author_rank: Frequent Contributor
timestamp: May 15, 2017, 12:01:30 am
content: Quote from: PCChazter on May 14, 2017, 11:42:00 pm10 or 13 pF should be about right, I'd think.Could the crystal have been damaged during soldering? They are somewhat heat-intolerant.Quote from: PCChazter on May 14, 2017, 11:42:00 pmIn this case, an oscilloscope isn't the answer. A frequency counter is what you would want.Quote from: PCChazter on May 14, 2017, 11:42:00 pmIn your track right above pad 1 of the crystal.Quote from: PCChazter on May 14, 2017, 11:42:00 pmI just browsed the chip's datasheet. It seems somewhat complicated with two internal oscillators, and an option for two different types of external clocks. Figure 6-9 of the datasheet seems to suggest a series damping resistor on the X2 pin? I don't understand it, but maybe it's to force the ESR to be in an acceptable range for the oscillator circuitry.You should be able to view system registers with the debugger to see which oscillator is in use.I've also run into micro issues where the period was off-by-one, and I had to program a period of 9 to actually get a period of 10, though this wouldn't offset the frequency by as much as you've seen.

author: StillTrying
author_rank: Super Contributor
timestamp: May 15, 2017, 12:04:49 am
content: If you could arrange for a LED to flash (or toggle) every 10 or 60 seconds you could compare with an accurate clock and detect if it's drifting without having to wait the full 10 to 20 hours.

author: pigrew
author_rank: Frequent Contributor
timestamp: May 15, 2017, 12:15:40 am
content: Quote from: pigrew on May 15, 2017, 12:01:30 amLooking through the TI message boards, Rd is used to reduce the drive level of the crystal, and they also say that it's generally unnecessary at above 10 MHz.

author: PCChazter
author_rank: Contributor
timestamp: May 15, 2017, 12:50:43 am
content: Quote from: pigrew on May 15, 2017, 12:01:30 amThis is a possibility, I used solder paste and a hot air gun to solder it on.Quote from: pigrew on May 15, 2017, 12:01:30 amDon't have one of these either, but my interrupt code pretty much does this for me.Quote from: pigrew on May 15, 2017, 12:01:30 amI see, I will refrain from this in the futureQuote from: pigrew on May 15, 2017, 12:01:30 amI went through my code, assuming the libraries were configuring the registers correctly, and it looked good. You're right, it can seem to be over complicated, but in my code, I am using internal oscillator 1 to drive the main code PLL, and the crystal to drive timer2. All other peripherals run off the PLL loop, and internal oscillator 2 is turned off. To add to confidence I am using the right oscillator source for timer2, I just removed the crystal completely, and the timer stopped counting, so it is not a case of mistakenly using the internal oscillator.Quote from: pigrew on May 15, 2017, 12:01:30 amThis is also something that I considered at first. The prescaler for the timer is exactly the way you describe, so I have it set to 11999 instead of 12000 to get 1ms timer intervals, which is then counted down from 1000 on the timer so that my interrupt triggers (or should trigger!) every 1 second.Quote from: StillTrying on May 15, 2017, 12:04:49 amI do like this idea. I can watch it in the debugger, but this would give a good quick reference to see if it is off.

author: cncjerry
author_rank: Unknown
timestamp: May 15, 2017, 01:24:12 am
content: is it always the same amount off? 20 seconds seems like a lot. If it was a crystal problem then temperature changes over the measurement period would vary the PPM up/down. My experience with designing clocks based on timers is the instruction timing is usually the culprit once you get the crystal close.

author: PCChazter
author_rank: Contributor
timestamp: May 15, 2017, 01:40:45 am
content: Quote from: cncjerry on May 15, 2017, 01:24:12 amIt does vary a slight amount, but it is always slow. I just haven't kept note of how much it varies. My problem is that I can't rule out the crystal oscillating correctly, but from what I can tell, my timer is set up right, and as long as my isr completes before the next interrupt, it should not affect the timer. If you see a problem in my code that I overlooked, let me know, it's in the main postSent from my XT1563 using Tapatalk

author: pigrew
author_rank: Frequent Contributor
timestamp: May 15, 2017, 01:41:17 am
content: Quote from: StillTrying on May 15, 2017, 12:04:49 amI would have it flash every second, and display an accurate (NTP-based?) clock on the computer. You should be able to see the blinking of the computer's second counter and LED go in and out of phase over a period of an hour, but you could see the phase change after less than ten minutes.EDIT: Or, not. The NIST time service page says not to use it as a frequency standard.

author: David Hess
author_rank: Super Contributor
timestamp: May 15, 2017, 01:55:26 am
content: Quote from: PCChazter on May 15, 2017, 12:50:43 amA frequency counter would be the right tool for this however if a known good reference frequency is applied to one of the microcontroller's capture inputs, the microcontroller can time its own clock frequency. This is commonly done for self calibration during production.

author: Rerouter
author_rank: Super Contributor
timestamp: May 15, 2017, 02:23:43 am
content: I have to say your layout isn't that nice, those caps grounds should be referenced to the oscillator ground pin and only join the plane at that pin, equally some rotation could tidy it up quite a fair amountSo possibly noise coupling, in general the wrong caps can only pull it +- 80ppm at most,Equally the crystal you bought, what was the initial accuracy tolerance, crystals are stable, but you can buy them in 1% initial accuracy on the cheaper ones, which may explain your error, a low ppm per year crystal with a poor initial accuracy.

author: PCChazter
author_rank: Contributor
timestamp: May 15, 2017, 03:10:53 am
content: Quote from: Rerouter on May 15, 2017, 02:23:43 amAs far as layout goes, is this better, or do you have some recommendations? I have been doing research over the past week to best practices on crystal layout, but input would be great! I have taken the crystal and capacitors off of the main ground plane, and have run just a trace from the nearest MCU GND pin, which is conveniently right next to the XTAL pins. There is a keepout area on the top layer for these components that goes to the other side of the MCU pins, and a separate ground plane attached at only one point under this keepout, with a via to connect the bottom ground plane to the top ground trace.Is this overthinking it, or is this standard layout for any crystal?Also, pigrew, you pointed out an acute angle in my first design, for the grounds on these 2 caps, would you leave it this way, make a 90º trace bend, or point them towards the crystal?Top layer:Bottom layer:Quote from: Rerouter on May 15, 2017, 02:23:43 amIt states +/- 15ppm for tolerance and +/- 15ppm for temperature stability

author: james_s
author_rank: Super Contributor
timestamp: May 15, 2017, 03:15:45 am
content: Most of the time if you need precise timing you want one of the two loading capacitors on the crystal to be a variable capacitor that can be trimmed. It's certainly possible to get good accuracy, I have a Cathode Corner scope clock that keeps excellent time. It took a few iterations but I tweaked it until it keeps time to within a few seconds between DST cycles.

author: PCChazter
author_rank: Contributor
timestamp: May 15, 2017, 04:26:35 am
content: Something interesting is that on the launchpad (TI's dev board), there is a spot for a 1M resistor parallel to the crystal (R7). What is the purpose of this resistor, and is it crucial to the crystal's accuracy? There is no mention of this resistor in the datasheet. They also show 36pF caps, which seems quite large to me.source:http://www.ti.com/lit/ug/sprui11/sprui11.pdfedit: oops, that's for the F28069, but the F28027 has the same value resistor

author: tombi
author_rank: Regular Contributor
timestamp: May 15, 2017, 05:31:10 am
content: Just a guess but I wonder if latency in the ISR could effect this? Like I wonder if the timer reload is somehow dependent on the ISR completing? Or the timer reload time is somehow a factor?So if you change the timer so instead of going off every 1ms it goes off every 5ms does this change the error? 20 hours - 7.2 x 10^6 triggers - only need a small time error per timeout to get 20s error.Tom

author: rs20
author_rank: Super Contributor
timestamp: May 15, 2017, 05:43:35 am
content: Quote from: PCChazter on May 15, 2017, 04:26:35 amWhen you make an oscillator using a simple NOT gate (input and output corresponding to X1 and X2 in your diagram), then I believe that 1M resistor is there to ensure that the oscillations start (otherwise, the NOT gate could start off with a low input and a high output, with no energy in the crystal and not enough leakage resistance in the crystal for anything to happen). The resistor ensures that the crystal drive staying high or low for long periods of time is impossible, and AFAICT it is assumed to have negligible importance or effect once the oscillator is up and running (hence the relatively enormous value).So perhaps that chip just has a NOT gate internally, or equivalent?

author: StillTrying
author_rank: Super Contributor
timestamp: May 15, 2017, 09:43:47 am
content: Despite its claims of Real time, Background, and Unobtrusive, are you sure the debugger doesn't stop the internal clocks for a few cycles every time it reads the internal registers.I think the new layout would be worse, all those long tracks and especially gnd would have quite a bit of inductance.Edit:Somethinglike this appears to have the shortest 12MHz tracks.

author: Rerouter
author_rank: Super Contributor
timestamp: May 15, 2017, 10:44:10 am
content: It will be listed in the chip datasheet, but in general the 1 Meg resistor is for 2 purposes, the first is to ensure it starts up reliably and in the time frame specified in the datasheet, and to reduce dc biasing issues.The second is to limit the gain of the oscillator, as its getting feedback through the resistor it doesn't need to swing as hard, which reduces the power consumption somewhat, and reduces the amplitude of the higher harmonics.The next best place to look for what is going wrong is compare the "drive strength" of the chip, to the same on the crystal, driving the crystal with too much power can cause gross calibration issues, essentially the crystal is swinging too hard and detuning itself somewhat. if the drive strength is too high, you may need to add a series resistor to reduce the drive strength.

author: David Hess
author_rank: Super Contributor
timestamp: May 15, 2017, 03:47:39 pm
content: Quote from: PCChazter on May 15, 2017, 04:26:35 amI agree with rs20. The resistor biases the inverter between X1 and X2 into its linear range. Otherwise leakage currents could result in the oscillator not starting. Some designs include this resistor as part of the integrated circuit so no external resistor is required. The proper resistor has no effect on accuracy.Parallel resonate crystals (this is a parallel resonate oscillator) have their frequency specified with a specific load capacitance so the total capacitance values including parasitic capacitance depend on the crystal specification. One of the capacitors may be a trimmer to allow adjusting the crystal frequency.

author: technix
author_rank: Super Contributor
timestamp: May 16, 2017, 12:35:35 am
content: If you need accurate RTC timing you can invest in one DS3231 TCXO RTC chip. That thing is guaranteed to stay within 3 seconds per year. And if you need a faster accurate clock you can trim the internal RC oscillator against this chip (effectively a digital feedback PLL.)Or if you want to, your micro can be clocked off an atomic clock's 10MHz output.

author: james_s
author_rank: Super Contributor
timestamp: May 16, 2017, 03:01:27 am
content: The DS3231 do indeed work very well, and they're dirt cheap from China. I'm curious where those come from, unlike many cheap gray market semiconductors from China, the DS3231s I've had work very well.

author: CatalinaWOW
author_rank: Super Contributor
timestamp: May 16, 2017, 05:29:29 am
content: You have said that your clock is off. Is it slow or fast? I am with the others who suspect software overhead, but this could be totally eliminated if the clock is fast.

author: rs20
author_rank: Super Contributor
timestamp: May 16, 2017, 05:37:22 am
content: Quote from: CatalinaWOW on May 16, 2017, 05:29:29 amQuote from: PCChazter on May 14, 2017, 11:42:00 pm

author: bson
author_rank: Unknown
timestamp: May 16, 2017, 08:03:04 am
content: Have you tried using timer 0 or 1?

author: PCChazter
author_rank: Contributor
timestamp: May 19, 2017, 02:21:39 am
content: Sorry for not updating, I have been busy, and have been trying to test some of the suggestions here before replying. I have taken another F28027, and put it on a launchpad dev board that I had with a burnt chip on it (replacing the chip), and put a crystal that was giving me error on my board onto the dev board (I have tested a few crystals now). I then created a new copy of my code, and only copied the relevant code that gets the chip initialized, and has my clock code on it.I did not put any capacitors on the crystal, my thoughts on this was to let it run off of just the stray capacitance, and it should run fast. Please correct me if this is not correct.I don't know how much exactly it is off, as I have not run it long enough, but over a half hour it is about 40 seconds slow...dunno what that is all about.I have pretty much come to the conclusion that I'm going to have to use a dedicated clock chip, but I would still like to know what is going wrong. I could be damaging the crystal when installing it, but on the last crystal I have tested, I made sure to put my hot air to 260ºC, it was set at 300ºC, and I have read that anything over 260 risks chance of damage. It could be the particular MCU I am using sucks at using a crystal, keeping in mind I have now tried 2 of them. It could be residual flux is causing a huge amount of stray capacitance, I have noticed that when removing the crystals and MCU there has been flux underneath, regardless of how much I clean it with iso and qtips. Any other ideas?Quote from: tombi on May 15, 2017, 05:31:10 amI have changed my code to trigger the interrupt from 1s to 10s, and have added a delay in the ISR of 1s, so I should see it be off by 1s*(however many seconds it has run/10s) if this is the case.Quote from: bson on May 16, 2017, 08:03:04 amI believe timer 2 is the only one that can use the crystalQuote from: technix on May 16, 2017, 12:35:35 amI am thinking I will need to end up using a dedicated clock chip.Quote from: Rerouter on May 15, 2017, 10:44:10 amThe datasheet for the MCU says it is a 1.8V crystal input/output, I don't see anything on the crystal.Quote from: StillTrying on May 15, 2017, 09:43:47 amI have turned off everything that I can tell that relates to debugging, I will see how it does.Quote from: StillTrying on May 15, 2017, 09:43:47 amIs it a good idea to run that trace under the XTAL? A few pages I have found have mentioned to have a separated ground plane under the XTAL, I have also seen an example close to what I have on page 7 of this pdf:http://www.cypress.com/file/221431/download.Also, I've seen a few people on other forums suggesting others to have the capacitor ground only attached to your main ground net at 1 point to reduce interference. What do you think of this? Perhaps a mixture of what you have there and what I've read with a separate ground plane on the top layer, or is what I'm reading irrelevant or incorrect?

author: rs20
author_rank: Super Contributor
timestamp: May 19, 2017, 04:33:17 am
content: When you say "dedicated clock chip", just be aware that that's a vague term that could mean one of at least two different things:A real-time clock chip (e.g.this) -- a device that counts time itself, and you can ask it for the time over SPIA crystal oscillator (e.g.FOX924), a quartz crystal, load capacitors and oscillator all in a single package, which outputs (say) 20 MHz which you can then input into your microcontroller. Eliminates concerns about stray capacitance, etc, because that's all internal to the package.Not sure what you had in mind, but be sure to consider both.Also, it's unfortunate that we can't even elucidate whether your crystal is oscillating at the wrong frequency, or whether your code is not dividing as you expected. It'd be really good to figure this out -- even if you don't have a frequency counter, you should be able to statically clock your CPU and at least check that a timer output is toggling after precisely N clocks as you expected.

author: pigrew
author_rank: Frequent Contributor
timestamp: May 19, 2017, 04:49:46 am
content: 260 C may still be too hot if you are using a hot air gun without a controlled thermal profile. I'd try using lead based solder at a lower temperature like 220 C, preferably with a preheater. Above 250C should only be needed for lead-free solder.For the new layout, the bottom grounds don't have a direct path to the chip's ground. They meander around too much. I would add a few ground vias around the crystal. Look at the example layouts of evaluation boards for inspiration.Also, don't be afraid to rotate the crystal 30 or 45 degrees, it may make the tracks more direct, though it's probably unnecessary.Maybe just live with the frequency inaccuracy, and scale your time constants accordingly?-Nathan

author: PCChazter
author_rank: Contributor
timestamp: May 21, 2017, 02:43:16 am
content: So first off, never assume that your reference is correct. Turns out the clock on the computer I was using is fast, so no matter what I did, my MCU always seemed slow.With that out of the way, I used a serial terminal program on a different computer that allows for time stamps and logging, and started to graph my time offsets. Turns out there is a bit of ISR latency as suggested in this post:Quote from: tombi on May 15, 2017, 05:31:10 amIt changes it very slightly, which is why I couldn't see it before (as well as the computer clock being fast), but the terminal I am using logs ms as well, so when I graph it, I can see it. If I change it to a 20s period, it is fast, change it to 1 or 2 s, and it is slow. I'm guessing it is like you say, and the process to reload the timer takes more than 1 clock cycle, which is why a longer period seems better. Which is weird because the way that it is described in the datasheet, it made it seem like it should not add latency. I could adjust the period to overcome this, as I want a 1s interval.Another thing I tried was to use the dedicated PWM module on the chip (still part of the MCU, just not directly tied to the CPU) instead of the timer. Unfortunately the prescaler is not as configurable as the timer, so I have to make it count in ms intervals, then my ISR adds 1s to my clock time variable every 1000ms. I also noticed the same latency on the PWM on anything under 5ms, but I'm guessing this could be partially because of my ISR taking too long to send the information over SCI, as well as any overhead latency it has.Quote from: pigrew on May 19, 2017, 04:49:46 amI have no idea how controlled the temperature on my hot air is, it's a cheap china made one. I use leaded solder, so I will try 220º next time, as long as I don't have to wait 10 minutes for my solder to flow :p. I do not have a preheater though...Quote from: pigrew on May 19, 2017, 04:49:46 amI see what you mean with meandering, didn't notice that when I posted it. I did do some research on layout, but they don't all follow the same rules, which is why I seeked out advice on my problem.Quote from: pigrew on May 19, 2017, 04:49:46 amI will give this a try and see if it's more direct. I didn't see the spot for Kicad to rotate manually, but I see it now.Quote from: pigrew on May 19, 2017, 04:49:46 amI think this is what I'm going to do, and have the dedicated chip as an added option on my board.Quote from: rs20 on May 19, 2017, 04:33:17 amSorry, I meant dedicated RTC chip, with everything including the clock counter packaged in one.Quote from: rs20 on May 19, 2017, 04:33:17 amI'm still not sure my crystal is oscillating at the right frequency, but do think the MCU has some overhead that is altering my clock readings. I could do what you suggest there, I still might, but for now I think I'm going to settle with that, and do some software trimming.

author: StillTrying
author_rank: Super Contributor
timestamp: May 22, 2017, 11:35:45 am
content: The reloading of the PreScaler/divider with (11999 +1) and reloading of the timer with 1000, is all done in hardware so Interrupt latencyshouldn'thave anything to do with it.But,"I'm guessing this could be partially because of my ISR taking too long to send the information over SCI, as well as any overhead latency it has."Sounds like a bad idea!If you made the PreScaler11,999,999, then timer2 would become a 1 second countdown timerallin hardware, which could be read anytime and not be effected by any interrupts, read it inverted '~' for a 1 second up counter.1 second per hour is 277ppm.Edit. PreScaler is only 16 bit, so largest useful divider could be 59,999 giving 5ms 200Hz ticks to the 32 bit timer2.

author: Bendba
author_rank: Regular Contributor
timestamp: May 22, 2017, 01:57:50 pm
content: Quote from: PCChazter on May 15, 2017, 12:50:43 amHi,Here is my uneducated opinion, I could be wrong.Your timer preload of 1000 sounds wrong to me, if you want to count 1000. Your timer interrupt would be on zero, which means you've counted to 1001, not 1000. Same reason you had to load your first time with 11,999 instead of 12,000.Plus the software handle of the interrupt, even if it only takes a few cycles.Why not seeing your timer at 11,999,999 (+- a correction value if needed) instead?

author: StillTrying
author_rank: Super Contributor
timestamp: May 22, 2017, 02:52:07 pm
content: Quote from: Bendba on May 22, 2017, 01:57:50 pmThe data sheet says the timer is reloaded with 1000 when it reaches 0, so itshouldcount down3, 2, 1, 1000, 999.If there was 1 extra ms in every second, the seconds count would be slow by 3.6 seconds per hour.

author: Bendba
author_rank: Regular Contributor
timestamp: May 22, 2017, 03:08:20 pm
content: Unless your oscillator is running too fast, especially with the low cap values used. If you count a little too much but too fast, at the end, you could only be going a very little bit too slow.But if the timer has an immediate hardware reset, that's not the problem. But then I don't know why you would have needed to set your prescaler at 11,999 instead of 12,000. That would be because your crystal is about 83ppm too fast, which is not within the specs stated at the start.Note: I just noticed the mention of thetimerprescaler being a 16 bit timer so, yes, gotta be done in two steps

author: StillTrying
author_rank: Super Contributor
timestamp: May 22, 2017, 03:57:43 pm
content: It's on page 62 of sprufn3d.pdfhttp://www.ti.com/lit/ug/sprufn3d/sprufn3d.pdfThe general operation of the CPU-timer is as follows:The 32-bit counter register TIMH:TIM is loaded with the value in the period register PRDH:PRD. The counter decrements once every (TPR[TDDRH:TDDR]+1) SYSCLKOUT cycles, where TDDRH:TDDR is the timer divider. When the counter reaches 0, a timer interrupt output signal generates an interrupt pulse.

author: Dr. Frank
author_rank: Super Contributor
timestamp: May 22, 2017, 04:23:00 pm
content: You have a 277ppm error, that seems to be too big an error as to be located in the XTAL circuit.Usually, you can't trim an XTAL so far off.This 277ppm deviation corresponds to about additional 3 clock counts, i.e. 12003 instead of 12000 divider counts.These give -250ppm and -27ppm, caused by the XTAL itself.So I assume, that your interrupt routine may have these 3 hidden clock delays.Embedded controllers usually have very bad oscillators, like a simple logic inverter, which requires this 1M series resistor.The driving level is often far too high, which doesn't give a reasonable accuracy, like these specified +/-15ppm. This latter value might be achieved easily in a proper 'analogue' oscillator circuit, like Colpitts, or similar.So for your digital oscillator, you shouldn't have too high expectations, but about 30..50ppm frequency accuracy should be achievable, when using proper capacitors.For mass production, automotive business, these capacitors were first chosen to give a good oscillation margin. (start up behavior).Afterwards, the XTAL will be produced in such a manner to meet the proper center frequency for the given controller.This 'pairing' of XTAL and controller is usually done at the XTAL manufacturer, who determines the resonance capacitors C1, C2, and the XTAL grinding parameters.The manufacturers of the XTAL, or of the controller often recommend proper parts and values in their specs.Kyocera is quite bad in this aspect, as even the XTAL cut is not specified (is it an AT-cut type??)In manufacturing, you then have about +/- 20ppm or more deviation, due to XTAL and oscillator exemplar variations.So the software accounts for variable correction factors, which are determined by an external frequency counter at the EOL testing.There's no other way to achieve <= 10ppm accuracy, or about 1sec/day, which is required by many automotive customers for the cars clock.The software should have a trimming range of several hundred ppm, and a resolution of 1ppm.That means, that you correct the clock by single counts every Nth interrupt, with sufficiently long correction counters.For your problem, you really need a precise counter, to decide, whether the fault is in the software, i.e. my supposed 3 counts, or if something is completely wrong with your XTAL circuit.The fine tuning, down to these +/-15ppm has also to be accomplished with a frequency counter.PS: Overheating of an XTAL usually causes a total failure, but very probably no such deviation of the resonant frequency.Remember, latter is determined tightly by the thickness of the Quarz disc, which will not change at all by heating.Frank

author: Dr. Frank
author_rank: Super Contributor
timestamp: May 22, 2017, 06:42:38 pm
content: As your clock is always slow, it just came to my mind, that other interrupts in your system may delay your timer or counter updates, or maybe skip increments from time to time.It is important for such programmed clocks, that the timer reloads itself, w/o your 1ms interrupt.Then, your timer and counter interrupts should have highest priority, so that any other interrupt, or system events can't disturb your timing routines.Frank

author: PCChazter
author_rank: Contributor
timestamp: May 25, 2017, 05:30:10 pm
content: Oh man, so much valuable information, thanks you guys! I think I finally have something livable! When I first read through the documents for the registers, I had understood that as soon as the counter gets to 0 it resets, but turns out it takes an extra clock cycle to do this, so I should be treating it the same as the prescaler and subtracting one. It also didn't help that unbeknownst to me, the computer clock I was trying to measure it against to was fast, and I think it slowly got faster over time. So no matter what I did at first it seemed as though I was not improving it.So I have changed the prescaler to 11 (from 11999), changed the period to 999999 us (instead of 1000ms), and put 10pF caps on the crystal. Changing the prescaler made a huge difference, because now an error of 1 clock cycle on the counter is equivalent to 1us instead of 1ms, then changing the period to 999999 gave me my base line, which I then did some software adjustment to get it looking good. In the end, the period (with the adjustments) is 1000030. Look below to see a graph of the MCU time minus my computer time over 7 hours.I will continue to try to improve my system, but for now it is livable. I will probably end up using the dedicated RTC that was suggested (or similar), and use some of the layout suggestions given here. I will still use my crystal timer RTC as a lower accuracy clock, but make the dedicated RTC an option for where higher accuracy on the clock is desired.Even though I may have solved my problem with the help of this post, I still have some questions.Quote from: Dr. Frank on May 22, 2017, 04:23:00 pmYour post was helpful in coming to terms with a crystal clock worse than the stated 15ppm, thanks. I am not sure what kind of oscillator circuit this MCU has, the only thing I can find is it uses the internal 1.8V regulator meant for the "CPU and logic digital power". Should I put this 1M resistor in place, even though there is no mention about it in the datasheet, and would it increase my likelihood of getting a more accurate and repeatable clock?Quote from: StillTrying on May 22, 2017, 11:35:45 amJust to clarify, I tried using a PWM interrupt every 1ms to see if that was any better, and have added a serial output of 10 characters at 9600baud into my ISR every 1000ms so I can log it using a serial terminal on my computer. So total time taken to send characters = 10 characters * (10 bits * (1 / 9600)) = 10.4ms. If my interrupt is every 1ms, and it can't override the interrupt while it's busy sending, it would miss 10 interrupts every 1000ms. The PWM would still keep on ticking, but the CPU wouldn't count those ticks cause it was already busy. This has no effect on my timer2 interrupt, because that ISR triggers every second, not every ms, so the ISR can complete before the next one triggers. Either way, I went back to using timer2, so this is irrelevant.Quote from: evb149 on May 21, 2017, 07:42:37 amI am not reloading the timer in my ISR. Do you have any idea how much jitter can be expected? I graphed my MCU RTC readings against the timestamp in my serial terminal after getting my MCU trimmed in software, and this is what I got:close up of first 10 minutes on same graph:I imagine some of this weird jitter is related to using the clock on my computer as a reference, but I was still curious as to what could be related to the ISR jitter.