LPC1768 RTC frequency check with WDT. Compare RTC against MCU's microsecond Timer.
Check LPC1768 RTC crystal frequency using WDT. Measure with MCU's microsecond Timer. The MCU's crystal may be off a bit as well. I measured the RTC frequency error at 22 ppm. The spec for the RTC crystal is 20 ppm. Using NTP and a GPS, I had measured the MCU's crystal frequency error at -2 ppm.
Frequency measurements for other MCU/RTC cyrstals at
https://github.com/manitou48/crystals/blob/master/crystals.txt
main.cpp
- Committer:
- manitou
- Date:
- 2015-11-16
- Revision:
- 0:11cc29f22037
File content as of revision 0:11cc29f22037:
// use WDT to measure drift of RTC and IRC // seems WDT ISR will only fire once #include "mbed.h" DigitalOut led1(LED1); uint32_t ticks; void kick() { __disable_irq(); LPC_WDT->WDFEED = 0xAA; LPC_WDT->WDFEED = 0x55; __enable_irq(); } void isr_wdt(void) { ticks++; led1 = 1; LPC_WDT->WDMOD |= (1<<3); // LPC_WDT->WDMOD &= ~(1<<2); // kick(); } void wdt_init() { LPC_WDT->WDCLKSEL = 0x2; // Set CLK src 0 IRC 1 PCLK 2 RTC // uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 LPC_WDT->WDTC = 0xfffffff; // max countdown LPC_WDT->WDMOD = 0x01; // enable but no reset NVIC_SetVector(WDT_IRQn, (uint32_t)&isr_wdt); NVIC_ClearPendingIRQ(WDT_IRQn); NVIC_EnableIRQ(WDT_IRQn); kick(); } int main() { uint32_t t,t0=0,us,us0,prev; int ppm; Timer tmr; tmr.start(); printf("hello %x\n",LPC_WDT->WDMOD); wait(1.0); wdt_init(); prev=LPC_WDT->WDTV; while(1) { t=LPC_WDT->WDTV; us = tmr.read_us(); if (t0==0 || t0 == 255) { t0 = t; us0 = us; } double tf = (t0-t)/8192.; // /8192 for rtc 1000000 for IRC double secs = 1.e-6*(us-us0); ppm = 1.e6*(tf-secs)/secs; printf("ticks %d %d %u %d us %x %d ppm \n",ticks,prev-t,t0-t,us-us0,t,ppm); prev=t; wait(2.0); } }