Real time clock of LPC2148

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.

Add new comment

Who's online

There are currently 0 users online.