pic32 rtccTime structure

Discussion in 'Embedded Systems and Microcontrollers' started by adrenalina, Jun 15, 2012.

  1. adrenalina

    Thread Starter Active Member

    Jan 4, 2011
    78
    3
    Hello everybody. I am working on a project using the rtcc module from a pic32 and I have a question about the module.
    what would happen with the code below, will tm.hour = 0x10 or will it be 0x0A? If it equals 0x0A is there some way to do bcd math with c?

    Code ( (Unknown Language)):
    1.  
    2. rtccTime tm;
    3.  
    4. tm.hour = 0x09;
    5. tm.hour += 1;
    6.  
    7.  
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Let's start by looking at the rtcc structure. It is defined in rtcc.h, and you can read about it in the "C32 Peripherial Lib Guide" which you should find as the very last item in your MPLAB Help | Topics area.

    Code ( (Unknown Language)):
    1.  
    2. // union/structure for read/write of time into the RTCC device
    3. typedef union
    4. {
    5.     struct
    6.     {
    7.         unsigned char    rsvd;        // reserved for future use. should be 0
    8.         unsigned char    sec;         // BCD codification for seconds, 00-59
    9.         unsigned char    min;         // BCD codification for minutes, 00-59
    10.         unsigned char    hour;        // BCD codification for hours, 00-24
    11.     };                                // field access
    12.     unsigned char        b[4];        // byte access
    13.     unsigned short       w[2];        // 16 bits access
    14.     unsigned long        l;           // 32 bits access
    15. }rtccTime;
    16.  
    From this we can see the hours member is defined as an unsigned char and holds a packed BCD number.

    Thus when you perform your code:
    Code ( (Unknown Language)):
    1. rtccTime tm;
    2.  
    3. tm.hour = 0x09;
    4. tm.hour += 1;
    the tm.hour quantity advances from 0x09 to 0x0A as any other unsigned char would. That is not so good for you as you wish the answer to be 0x10 to properly represent the packed BCD number.

    The solution is to write some routine to do the increment and check the answer. This also applies to the min and sec members, meaning incrementing sec may mean you also increment min and hour.

    Aside: while slightly more cryptic for the beginner, the preferred way to increment a variable is with the increment operator:
    Code ( (Unknown Language)):
    1. rtccTime tm;
    2.  
    3. tm.hour = 0x09;
    4. tm.hour++;   // use the increment operator to do this
    Depending on the compiler this may result in a tiny bit smaller code, while in this context it still gives the same "incorrect" answer and needs further coding to correct to a valid packed BCD number.
     
  3. adrenalina

    Thread Starter Active Member

    Jan 4, 2011
    78
    3
    Thanks for tha help. I really appreciate it.
     
  4. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    I used the following code as a way to make sure my hours are right in the time structure when incrementing the Hours via user input buttons....

    Code ( (Unknown Language)):
    1.  
    2. int tSH,nREP;
    3. tSH=tSH+0x01;           //[COLOR="DarkRed"]increment hour variable[/COLOR]
    4. nREP=nREP+0x01;                //[COLOR="DarkRed"]Increment counter[/COLOR]
    5. if(nREP>0x09){tSH=tSH+6;nREP=0;}//[COLOR="DarkRed"]If counter has reached 10 add 6 to Hour variable[/COLOR]
    6. if(tSH>0x23){tSH=0x00;nREP=0;}//[COLOR="DarkRed"]If Hour Variable has reached 24, reset to 0[/COLOR]
    7. ttm.hour=tSH;    //[COLOR="DarkRed"]Set Time structure with Hour Variable[/COLOR]
    8.  
     
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Well if you're going to be that way...

    Inline increment:
    Code ( (Unknown Language)):
    1.  
    2.   if( (++hours & 0x0F) > 0x09) hours += 0x06;
    3.   if ( (hours) > 0x23 ) hours = 0;
    4.  
    Subroutine increment:
    Code ( (Unknown Language)):
    1.  
    2. void IncHour(unsigned char* digit)
    3. {
    4.   if( (++*digit & 0x0F) > 0x09) *digit += 0x06;
    5.   if ( *digit > 0x23 ) *digit = 0;
    6. }  
    7.  
    Function increment:
    Code ( (Unknown Language)):
    1.  
    2. unsigned char IncHour(unsigned char digit)
    3.  {
    4.    if( (++*digit & 0x0F) > 0x09) *digit += 0x06;
    5.    if ( *digit > 0x23 ) *digit = 0;
    6.    return digit;
    7.  }  
    8.  
    (No wonder they call "C" a "write-only" language.)
     
    Last edited: Jun 16, 2012
Loading...