|
LPC2000 series of microcontrollers have built in Real Time Clock(RTC) unit which is may be used for counting time in order to maintain a calendar and clock. RTC is designed for low power designs that enables to use in battery powered designs. Real time clock is capable to count time in Seconds, Minutes, Hours, Days of Month, Months, Years, Days of the week and Days of Year. Real time module can be clock using distinct 32kHz clock oscillator or internal prescaller from VPB clock. Real time clock unit has additional power supply pins(3.3V) what allows RTC clock to work when system is off – actually power down mode operated from clock battery.  As there are many functions in clocks like time units(seconds, minutes, etc,) and alarms, there are quite a number of registers to cover clock functionality. There are several groups of registers:
Miscellaneous registers like Interrupt Location Register(ILR), Clock Tick Counter(CTC), Alarm Mask Register(AMR); Time Counter register Group which includes registers that contain Time values(Seconds, Minutes,...); Alarm register group – registers that hold alarm settings and that are compared to Time Group registers. When match occurs an interrupt is generated; Registers that control Reference Clock Divider – with these registers it is possible to get 32768Hz from peripheral clock frequency. Among Miscellaneous register group there are three Consolidated Time registers. They have pasked time value in one word: CTIME0 register contain Seconds[5:0], Minutes[13:8], Hours[20:16] and Day of Week[26:24]; CTIME1 register contain Day of Month[4:0], Month[11:8], Year[27:16] and CTIME2 contains day of Year[11:0]. So Consolidated registers allow reading all time information just in three operations instead of eight. RTC has two interrupt mechanisms. One of them is that you can program an interrupt each time any timer-counter is incremented – this allows generating and interrupt every second and once a year when Year value is incremented. So this way you can generate interrupts for each of eight time registers increment. Second interrupt mechanism allows generating an interrupt according to alarm register values. Simply when alarm registers match time counter registers. Simply speaking is alarm register is unmasked then interrupt will occur when all time registers match. Mask register is used to mask registers of that don't have to be compared, like if you want to set alarm for each morning,then you need to mask off Year, day of week, day of month and so on. Jus leave seconds, minutes and hours. /************************************************************************* * WinARM RTC application * - UART0 send in Interrupt-Mode * - Sends message every seccond. * - RTC interupt every second *************************************************************************/ #include "types.h" #include "LPC214x.h" #include "config.h" #include "armVIC.h" #include "uart.h" uint32_t time_toggle=0; static void rtc0(void) __attribute__ ((interrupt ("IRQ"))); static void sysInit(void) { // set PLL multiplier & divisor. // values computed from config.h PLLCFG = PLLCFG_MSEL | PLLCFG_PSEL; // enable PLL PLLCON = PLLCON_PLLE; PLLFEED = 0xAA; // Two updates PLLFEED = 0x55; // MUST occur in sequence. // setup the parallel port pin IO0CLR = PIO0_ZERO_BITS; // clear the ZEROs output IO0SET = PIO0_ONE_BITS; // set the ONEs output IO0DIR = PIO0_OUTPUT_BITS; // set the output bit direction IO1CLR = PIO1_ZERO_BITS; // clear the ZEROs output IO1SET = PIO1_ONE_BITS; // set the ONEs output IO1DIR = PIO1_OUTPUT_BITS; // set the output bit direction // wait for PLL lock while (!(PLLSTAT & PLLSTAT_LOCK)) continue; // enable & connect PLL PLLCON = PLLCON_PLLE | PLLCON_PLLC; PLLFEED = 0xAA; // Two updates PLLFEED = 0x55; // MUST occur in sequence. // setup & enable the MAM MAMTIM = MAMTIM_CYCLES; MAMCR = MAMCR_FULL; // set the peripheral bus speed // value computed from config.h VPBDIV = VPBDIV_VALUE; // set the peripheral bus clock speed // set the interrupt controller defaults #if defined(RAM_RUN) MEMMAP = MEMMAP_SRAM; // map interrupt vectors space into SRAM #elif defined(ROM_RUN) MEMMAP = MEMMAP_FLASH; // map interrupt vectors space into FLASH #else #error RUN_MODE not defined! #endif VICIntEnClear = 0xFFFFFFFF; // clear all interrupts VICIntSelect = 0x00000000; // clear all FIQ selections VICDefVectAddr = (uint32_t)reset; // point unvectored IRQs to reset() // wdtInit(); // initialize the watchdog timer initSysTime(); // initialize the system timer uart0Init(UART_BAUD(HOST_BAUD), UART_8N1, UART_FIFO_8); } /*************************************************************/ void rtc0(void) { if (time_toggle==0) { uart0Puts("\n\rTic\r\n");//Tic Tac output to UART0 time_toggle=1; } else { uart0Puts("\n\rTac\r\n"); time_toggle=0; } ILR |= 1; // Clear interrupt flag VICVectAddr = 0; // Acknowledge Interrupt PCON = 1; // IDLE mode } void init_rtc(void) { ILR = 3; // Disable 32'768 interrupt CCR = 0x11; // Clock enable + 32'767Hz quartz enable CIIR = 0x01; // Interupt every second VICVectAddr1 = (unsigned long)rtc0; // set interrupt vector in 1 VICVectCntl1 = 0x0000002D; // use it for RTC Interrupt VICIntEnable = 0x00002000; // Enable RTC Interrupt } void set_time(void) { YEAR = 2006; // Year MONTH = 5; // Month DOM = 23; // Day of month DOY = 38; // Day of year DOW = 143; // Day of week HOUR = 23; // Hours MIN = 14; // Minutes SEC = 30; // Seconds } int main(void) { uint32_t startTime; sysInit(); //system init #if defined(UART0_TX_INT_MODE) || defined(UART0_RX_INT_MODE) enableIRQ(); #endif uart0Puts("\n\rRTC interupts every second\r\n"); //This function returns the current system time in TICs startTime = getSysTICs(); init_rtc();//init RTC set_time();//Set initial time for (;;) { } // for return 0; } Download WinARM Project Files. |