Using the Real Time Clock and Calendar (RTCC) module on a PIC24

5.00 avg. rating (94% score) - 1 vote

This article shares the source code which I have written to set and get the current time using the Real Time Clock and Calendar (RTCC) module on the PIC24. It is tested with the PIC24FJ64GA002 but will work with other similar PICs with little modification. I decided to post it here as I found very little information on this on the Internet.

First, before you get too excited and think you will no longer need an external RTC module such as the DS1307, take note that unlike the DS1307, there is no time keeping battery for the RTCC module – it shares power with the PIC. So to keep it running for extended period, you will probably need to put the PIC into standby when not in use to save power while still keeping the RTCC running.

The following code will enable the secondary oscillator for the RTCC module:

__builtin_write_OSCCONL(OSCCON | 0x02);

The following function will write the specified date and time value to the RTCC module:

void setRTCTime(unsigned char year, unsigned char month, unsigned char day, unsigned char weekday, unsigned char hour, unsigned char minute, unsigned char second)
{
// Enable RTCC Timer Access

/*
NVMKEY is a write only register that is used to prevent accidental writes/erasures of Flash or
EEPROM memory. To start a programming or an erase sequence, the following steps must be
taken in the exact order shown:
1. Write 0x55 to NVMKEY.
2. Write 0xAA to NVMKEY.
*/

NVMKEY = 0x55;
NVMKEY = 0xAA;
RCFGCALbits.RTCWREN = 1;

// Disable RTCC module
RCFGCALbits.RTCEN = 0;

// Write to RTCC Timer
RCFGCALbits.RTCPTR = 3; // RTCC Value Register Window Pointer bits
RTCVAL = bin2bcd(year); // Set Year (#0x00YY)
RTCVAL = (bin2bcd(month) << 8) + bin2bcd(day);// Set Month and Day (#0xMMDD)
RTCVAL = (bin2bcd(weekday) << 8) + bin2bcd(hour); // Set Weekday and Hour (#0x0WHH). Weekday from 0 to 6
RTCVAL = (bin2bcd(minute) << 8) + bin2bcd(second); // Set Minute and Second (#0xMMSS)

// Enable RTCC module
RCFGCALbits.RTCEN = 1;

// Disable RTCC Timer Access
RCFGCALbits.RTCWREN = 0;
}

The following code will get the current RTCC time:

// Wait for RTCSYNC bit to become ‘0’
while(RCFGCALbits.RTCSYNC==1);

// Read RTCC timekeeping register
RCFGCALbits.RTCPTR=3;

year = bcd2bin(RTCVAL);

unsigned int month_date=RTCVAL;
month = bcd2bin(month_date >> 8);
day = bcd2bin(month_date & 0xFF);

unsigned int wday_hour=RTCVAL;
weekday = bcd2bin(wday_hour >> 8);
hour = bcd2bin(wday_hour & 0xFF);

unsigned int min_sec=RTCVAL;
minute = bcd2bin(min_sec >> 8);
second = bcd2bin(min_sec & 0xFF);

The date and time values are stored internally as binary coded decimals (BCD). I have written functions bcd2bin and bin2bcd to assist in the conversion of the values. The completed source code, with the BCD conversion functions, can be downloaded here.

5.00 avg. rating (94% score) - 1 vote
ToughDev

ToughDev

A tough developer who likes to work on just about anything, from software development to electronics, and share his knowledge with the rest of the world.

2 thoughts on “Using the Real Time Clock and Calendar (RTCC) module on a PIC24

  • April 23, 2015 at 10:17 am
    Permalink

    Hi,

    Thanks for the helpful codes!

    I have downloaded the source code, and I have some question would like to seek for your advice.

    In of one the functions getRTCTime(); it returns a value retVal. I notice that this is a structure variable, may I know how should I declare a variable such that I can fetch this return value in my main loop?

    i.e.
    time = getRTCTime();

    how should I declare time in the main loop?

    Thanks!

    (*I am a new learner in C programming :> )

    Howard

  • April 23, 2015 at 11:27 am
    Permalink

    Hi,

    If you check the header file rtcc.h you will find the following declaration

    RTCTime getRTCTime();

    The return value of function getRTCTime is of type RTCTime (struct). The declaration of this struct can be found at the top of the same file:

    typedef struct _RTCTime
    {
    unsigned char year;
    unsigned char month;
    unsigned char day;
    unsigned char weekday; // Monday is 0, Sunday is 6
    unsigned char hour;
    unsigned char minute;
    unsigned char second;
    } RTCTime;

    You can get the time using the following code snippet:

    RTCTime time; // declare the type of the time object
    time = getRTCTime(); // get the time

    After that access the time using time.year, time.month, time.day, time.hour, etc. for the year, month, day, hour, etc. respectively.
    a
    Let me know if it works.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>