Hello, I'm having problems with RTC in LPC1768. The RTC is running, but is advancing approx 5 seconds per hour. The electrical circuit is good, with a 20ppm crystal tolerance, and 12,5pf capacitors of load. Tha VBAT is conected in CR1220 lithium battery. I have reviewed the source code and is OK. Below is my code:
void InitRTC(void) { LPC_RTC->CCR = ( !CLKEN | CTCRST ); LPC_RTC->CCR &= ~CTCRST; return; } /***************************/ void StartRTC(void){ LPC_RTC->CCR |= ( CLKEN ); return; } /***************************/ int main (void){ char temp[36]; InitRTC(); StartRTC(); while(1){ sprintf ((char *)temp,"%2.2d/%2.2d/%.2d %2.2d:%2.2d",LPC_RTC->DOM,LPC_RTC->MONTH,LPC_RTC->YEAR,LPC_RTC->HOUR,LPC_RTC->MIN); lcd_gotoxy(1,0); lcd_print(temp); } return 0; }
The RTC is running correctly without the battery, with main power connected in VBAT. But yet the RTC is running advancing. I can't use the calibration of application note AN10849. I have 100 identical hardwares, and they are with different accurate. I think that this variation is very high for be simply a low accuracy of LPC. There must be some other problem.
Does anyone know what might be happening? Thanks
"advancing approx 5 seconds per hour"
So about 8% fast.
LPC_RTC->CCR = ( !CLKEN | CTCRST );
Are you sure that's right? Remember that '!' is not a bit-wise operator...
"I can't use the calibration of application note AN10849"
Why not?
"I think that this variation is very high for be simply a low accuracy of LPC"
But what does the Datasheet say?
I think that 8% is a very high variation. Not found in data sheet the clock accuracy of RTC.
The use of calibration it is not practical because I have 100 identical hardwares, and they dont are advancing equal. Some are advancing less, about 5%, and other about 3%. So, is not feasible calculate the calibration for each hardware.
Does the PCB layout can be a cause for this variation?
More like 0.14 %, a.k.a. 1400 ppm, actually. You were thinking 5 seconds per minute, instead of per hour.
Oops - so I was!
Are you sure that's right?
Remember that '!' is not a bit-wise operator...
Well, regardless whether it's right, at least it's harmless. The effect of actually zeroing that bit correctly would be the same as the above. The trickier question would be whether it's correct to zero all bits of that register except CTRST in the process.
Anyway, the RTC is running. The problem is accuracy.
And might that be affected by those other bits in that register...?
Table 509. Clock Control Register (CCR - address 0x4002 4008) bit description
Bit 0 = CLKEN, Clock Enable Bit 1 = CTCRST, CTC Reset Bit 3:2 = Internal test mode controls. These bits must be 0 for normal RTC operation. Bit 4 = CCALEN, Calibration counter enable. 1 The calibration counter is disabled and reset to zero. 0 The calibration counter is enabled and counting, using the 1 Hz clock. When the calibration counter is equal to the value of the CALIBRATION register, the counter resets and repeats counting up to the value of the CALIBRATION register. See Section 27.6.4.2 and Section 27.6.5. Bit 31:5 = Reserved, user software should not write ones to reserved bits.
lpc17xx.cmsis.driver.library.zip
/********************************************************************//** * @brief Initializes the RTC peripheral. * @param[in] RTCx RTC peripheral selected, should be LPC_RTC * @return None *********************************************************************/ void RTC_Init (LPC_RTC_TypeDef *RTCx) { CHECK_PARAM(PARAM_RTCx(RTCx)); /* Set up clock and power for RTC module */ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, ENABLE); // Clear all register to be default RTCx->ILR = 0x00; RTCx->CCR = 0x00; RTCx->CIIR = 0x00; RTCx->AMR = 0xFF; RTCx->CALIBRATION = 0x00; } /*********************************************************************//** * @brief Enable/Disable calibration counter in RTC peripheral * @param[in] RTCx RTC peripheral selected, should be LPC_RTC * @param[in] NewState New State of this function, should be: * - ENABLE: The calibration counter is enabled and counting * - DISABLE: The calibration counter is disabled and reset to zero * @return None **********************************************************************/ void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState) { CHECK_PARAM(PARAM_RTCx(RTCx)); CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); if (NewState == ENABLE) { RTCx->CCR &= (~RTC_CCR_CCALEN) & RTC_CCR_BITMASK; } else { RTCx->CCR |= RTC_CCR_CCALEN; } }
/*-------------------------MAIN FUNCTION------------------------------*/ /*********************************************************************//** * @brief c_entry: Main RTC program body * @param[in] None * @return int **********************************************************************/ int c_entry(void) { [DELETED] /* Enable rtc (starts increase the tick counter and second counter register) */ RTC_ResetClockTickCounter(LPC_RTC); RTC_Cmd(LPC_RTC, ENABLE); RTC_CalibCounterCmd(LPC_RTC, DISABLE); [DELETED]
We have seen this behavior in our designs with the LPC1765. Clocks would be very inaccurate or even stop and start randomly. Very sensitive to stray capacitance.
There was an errata about the RTC, but even after the errata, and using new revision ICs, we still saw strange behavior. I've seen users in other forums also complain about the LPC17XX RTC even in the supposedly 'fixed' silicone.
So please consider it may be the chip.
Good luck!
Definitely a reason to contact NXP support engineers.
On the other hand, NXP have had their share of RTC issues.
The LPC23xx series have a hw goof making the RTC power line consume loooots of power.
And the LPC17xx got an errata about temperature issues, without NXP specifying exactly how large temperature range that the RTC could be trusted.