Search code examples
embeddedarmmicrocontrollerreal-time-clock

Coding realtime clock for for ARM architecture based microcontroller


I need to write a program to implement real time clock for ARM architecture. example: LPC213x

It should display Hour Minute and Seconds. I have no idea about ARM so having trouble getting started.

My code below is not working

// ...

int main (void) {
    int hour=0;
    int min=0;
    int sec;
    init_serial(); /* Init UART */
    Initialize();
    CCR=0x11;
    PCONP=0x1815BE; 
    ILR=0x1;         //  Clearing Interrupt

    //printf("\nTime is %02d:%02x:%02d",hour,min,sec);

    while (1) { /* Loop forever */
    }
}

void Initialize()
{
VPBDIV=0x0;
//CCR=0x2; 
//ILR=0x3; 
HOUR=0x0;
SEC=0x0;
MIN=0x0;


ILR = 0x03; 
CCR = (1<<4) | (1<<0); 

VICVectAddr13 = (unsigned)read_rtc; 
VICVectCntl13 |= 0x20 | VIC_RTC; 
VICIntEnable |= (1 << VIC_RTC);

}
/* Interrupt Service Routine*/
__irq void read_rtc() 
{
int hour=0;
int min=0;
int sec;
ILR=0x1;         //  Clearing Interrupt
hour=(CTIME0 & MASKHR)>>16;
min= (CTIME0 & MASKMIN)>>8;
sec=CTIME0 & MASKSEC;

printf("\nTime is %02d:%02x:%02d",hour,min,sec);

//VICVectAddr=0xff;
VICVectAddr = 0;
}

Solution

  • This is all for the LPC2468. We have a setTime function too, but I don't want to do ALL the work for you. ;) We have custom register files for ease of access, but if you look at the LPC manual, it's obvious where they correlate. You just have to shift values into the right place, and do bitwise operations. For example:

    #define RTC_HOUR       (*(volatile RTC_HOUR_t *)(RTC_BASE_ADDR + (uint32_t)0x28))
    

    Time struture:

    typedef struct {
      uint8_t  seconds;        /* Second value - [0,59] */
      uint8_t  minutes;        /* Minute value - [0,59] */
      uint8_t  hour;           /* Hour value - [0,23] */
      uint8_t  mDay;           /* Day of the month value - [1,31] */
      uint8_t  month;          /* Month value - [1,12] */
      uint16_t year;           /* Year value - [0,4095] */
      uint8_t  wDay;           /* Day of week value - [0,6] */
      uint16_t yDay;           /* Day of year value - [1,365] */
    } rtcTime_t;
    

    RTC functions:

    void rtc_ClockStart(void) {
      /* Enable CLOCK into RTC */
      scb_ClockStart(M_RTC);
      RTC_CCR.B.CLKSRC = 1;
      RTC_CCR.B.CLKEN  = 1;
      return;
    }
    
    void rtc_ClockStop(void) {
      RTC_CCR.B.CLKEN = 0;
      /* Disable CLOCK into RTC */
      scb_ClockStop(M_RTC);
      return;
    }
    
    void rtc_GetTime(rtcTime_t *p_localTime) {
      /* Set RTC timer value */
      p_localTime->seconds = RTC_SEC.R;
      p_localTime->minutes = RTC_MIN.R;
      p_localTime->hour    = RTC_HOUR.R;
      p_localTime->mDay    = RTC_DOM.R;
      p_localTime->wDay    = RTC_DOW.R;
      p_localTime->yDay    = RTC_DOY.R;
      p_localTime->month   = RTC_MONTH.R;
      p_localTime->year    = RTC_YEAR.R;
    }
    

    System control block functions:

    void scb_ClockStart(module_t module) {
      PCONP.R |= (uint32_t)1 << module;
    }
    
    void scb_ClockStop(module_t module) {
      PCONP.R &= ~((uint32_t)1 << module);
    }