This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28027: Getting an accurate clock with a crystal

Part Number: TMS320F28027

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. I should also mention that it is powered off of a 3.3V  buck regulator, and the jtag debugger is attached and connected. I'm not sure if this changes anything, like does the debugger supply a clock that overrides any crystal?

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/5995243

The Capacitors: https://www.digikey.ca/product-detail/en/tdk-corporation/C1608C0G1H060D080AA/445-5037-1-ND/2093652

The (relevant) board layout:

The Code:

uint32_t clock_period = 1000; //in ms
uint32_t clock_time_s = 0; //in s
uint32_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++;
}

  • Cody,

    Connecting the JTAG connector should make no difference. It does not "override" the crystal. 15 ppm for a 12 MHz crystal implies the variation could be up to 180 cycles at any time. Besides, the error is cumulative and would add-up over time. So, it is not surprising you are off by 556 counts over a 20-hour period. Agree that the error can be both positive and negative. Hard to discern exactly how it manifests in your experiment.

  • Good to know the JTAG does not override, I figured as much, but never know. I'm not out by 556 counts over 20 hours, if the timer only varied by 556 crystal counts over a 20 hour period, I'd be laughing! It's off 20 seconds over a 20 hour period, which translates to 556ppm. Agreed the error can vary in the positive and negative range, but regardless of whether my sample size is 20 hours or 200 hours, it would (more than likely) stay close to 556ppm. I have ran it for a few days to confirm this.

    Let me know if you have any ideas, I'm still hoping to utilize the crystal for an on-chip rtc if it is possible (and repeatable). I have been playing around with a couple different capacitor values over around a 20 hour sample each, but still no luck. I looked back into the timer registers to make sure that I was right in using 11999 as the prescaler instead of 12000, and it does in fact state that the prescaler takes one more clock cycle to trigger a timer count, so to subtract one from your desired amount of clock cycles for the prescaler value. While I was going through the datasheet, I did notice it had a chart that specifies 15pF for 10Mhz to 15Mhz, so I have put on a 10pF in parallel with a 6pF (it's what I had), and I'll see how that is after around 20 hours or so.