Skip to main content
hervett
Associate III
January 14, 2009
Question

Save my RTC

  • January 14, 2009
  • 11 replies
  • 2587 views
Posted on January 14, 2009 at 13:25

Save my RTC

    This topic has been closed for replies.

    11 replies

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:58

    Hello everybody and an happy new year !!!

    I still have problems with my I²C but it's not my question for the moment.

    I wonder how can I save my calendar when my device is off. I explain:

    I'm using the intern RTC for my calendar. I work with seconds, minutes, hours, day, month and year.

    I can save the RTC when the device is off( it is 05:54:45, I switch off during 15s and when I switch on, I have 05:56:00. It work fine !

    I have a cell of 3V for the RTC.

    But if I switch off my device two or three days, it can't recover the changement of day, or month.

    My IT is enable for second in my code, so my counter get +1 for each second.

    Have I to enable IT for minutes, hours, day, month and year in order to recover the changement ?

    Can I enable all these IT's at the same time ?

    Or easier, it is possible to save my calendar with the RTC of the STM32 ?

    Thank you everybody :)

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    And if I don't want use the unix way ?

    Because I havn't knowledges in that, my code is now started since a long time and I don't want to restart from the beginning

    relaxe
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    You should do it the Unix way:

    Use the 32 bits RTC register to save the number of seconds since 1et jan. 1970.

    Ok, now that you've calmed down: This is the ''standart'' unix-C method. Doing so will allow you to use the to it's full potential: you can use the tm struct to populate month, date, year, etc. , then use mktime to transfer the struct to a value, or convert back to a u32, print formatted date with ctime(), etc.

    Just google around for time.h, you'll see.

    Ah, yes, doing so will ''only'' be valid until 2038, so enjoy those 29 years left!

    -Relaxe

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    I just find the application note AN2821 added recently . So I think it will answer at all my questions, I will be back here if I have problems again !!

    Thanks

    jj_it
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    Please do report your results - good or bad - so that the forum learns from your ''process.'' When we ''close the loop'' the forum is more valuable to all. Thanks...

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    No problems !

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    I watched this application note and thought about that problem. I think it is not possible to save the calendar if I switch off totally the STM32. It is possible in standbymode or stop mode but not in off mode! You can save the RTC counter when you switching off the system and recover it updated after the power on ( acutally working on my device ). But when the RTC counter go to zero, you don't have something to tell you that WHEN THE DEVICE IS OFF. So you can't count day, and month or year when the device is off. You can save the time but not the date. But maybe there is an overflow flag after the reset of the RTC, but it have to be save automaticly in the BKP domain when the device is off in order to recover it. Beause when you make the overflow flag yourself in the stm32it.c, the code is not executed during the power off.

    Whem i'm talking of the power off, I suppose that there is not the 3,3V on VCC but there is the cell of 3V for the RTC and the BKP domain.

    So in order to make my OWN conclusion, I think it is possible to save the calendar and recover it updated only after a standby mode or stop mode but NOT if you switch totally off the device .

    It is only based with my knowledges !

    So for my application I think I will do that with a M41T56 or something like that !!

    I'm waiting for comments.

    hervett
    hervettAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    I'M SO STUPIDD !!

    I had already that solution programed on my STM32 ( solution of relaxe ) but I did mistakes in my calculation. I was persuaded that this solution didn't work if the device was off more than two weeks. But I did again my calculations and found 136 years !!!!

    And I don't think that my device will be off more than 136 years, and I don't know too if someone will be here in 136 years in order to switch on the device !! ^^

    I'm so stupid and I'm sorry to have made you waste your time !...and mine too !

    So I will continu to use that and make my calendar system with that !!

    Thank you relaxe to have switched the right button in my brain !!

    relaxe
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    Is your RTC calibrated to save a ''number of seconds''? If so, why not just let it count, then add a small condition to your startup loop:

    if (RTC_GetCounter() >= (60*60*24)) //Timer counted for more than a day

    DaysPassedInHibernate = (RTC_GetCounter() / (60*60*24));

    Then remove the ''excess days'' from the counter.

    relaxe
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:59

    Instead of building a whole calendar, try the code below. Just include time.h

    And look at the doc here:

    http://www.cplusplus.com/reference/clibrary/ctime/

    Will probably prevent you from reinventing the wheel...

    -Relaxe.

    /*******************************************************************************

    * Function Name : Time_Regulate

    * Description : Returns the time entered by user, using Hyperterminal.

    * Input : None

    * Output : None

    * return : Current time RTC counter value

    *******************************************************************************/

    u32 Time_Regulate(void)

    {

    struct tm t;

    time_t t_of_day;

    printf(''\r\n==============Time Settings====================================='');

    printf(''\nYear:'');

    t.tm_year = USART_Scanf(2038)-1900;

    printf(''\nMonth:'');

    t.tm_mon = USART_Scanf(12)-1; //Number of months since January. [0-11] Go figure.

    printf(''\nDay:'');

    t.tm_mday = USART_Scanf(31);

    printf(''\nHour:'');

    t.tm_hour = USART_Scanf(24);

    printf(''\nMinutes:'');

    t.tm_min = USART_Scanf(60);

    printf(''\nSeconds:'');

    t.tm_sec = USART_Scanf(60);

    t.tm_isdst = 0;

    t_of_day = mktime(&t);

    printf(''\n'');

    printf(ctime(&t_of_day));

    /* Return the value to store in RTC counter register */

    return(t_of_day);

    }

    /*******************************************************************************

    * Function Name : USART_Scanf

    * Description : Gets numeric values from the hyperterminal.

    * Input : None

    * Output : None

    * Return : None

    *******************************************************************************/

    u32 USART_Scanf(u32 value)

    {

    u32 index = 0;

    u32 tmp[10] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};

    u32 indexlength = 0;

    u32 valuetmp;

    //Calculate the length (in char) max of user input

    valuetmp = value;

    if(value)

    {

    indexlength++;

    }

    for(valuetmp = value; valuetmp > 9; ++indexlength)

    {

    valuetmp = (valuetmp / 10);

    }

    index = 10-indexlength;

    while (index != 10)

    {

    /* Loop until RXNE = 1 */

    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)

    {}

    tmp[index++] = (USART_ReceiveData(USART1));

    if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))

    {

    printf(''\n\rPlease enter valid number between 0 and 9'');

    index--;

    }

    else

    {

    USART_SendData(USART1, (u8) tmp[index-1]);

    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)

    {}

    }

    }

    /* Calculate the Corresponding value */

    index = (tmp[9] - 0x30) +

    ((tmp[8] - 0x30) * 10) +

    ((tmp[7] - 0x30) * 100) +

    ((tmp[6] - 0x30) * 1000) +

    ((tmp[5] - 0x30) * 10000) +

    ((tmp[4] - 0x30) * 100000) +

    ((tmp[3] - 0x30) * 1000000) +

    ((tmp[2] - 0x30) * 10000000) +

    ((tmp[1] - 0x30) * 100000000) +

    ((tmp[0] - 0x30) * 1000000000);

    /* Checks */

    if (index > value)

    {

    printf(''\n\rPlease enter valid number between 0 and %d'', value);

    return 0xFFFFFFFF;

    }

    return index;

    }

    [ This message was edited by: relaxe on 14-01-2009 18:27 ]