2017-06-19 147 views
-1

我想在幾秒鐘內從RTC獲得系統的正常運行時間。重點是雖然我可以從RTC時間寄存器(RTC_TR)中總結出值,但它只能工作24小時,然後在RTC日期寄存器(RTC_DR)中添加一天時溢出。從RTC獲得正常運行時間

從我啓動系統的時間開始,如何計算秒數?我不需要日曆。

下面的我所說的「溢出」

我根據STM的RTC_LSI例如對於StdPeriph配置RTC和設置只有時間,而不是日期指交代。

但是,當我使用RTC_GetTime函數從RTC_TR獲取時間之後,23小時59分59秒後,時間回到0h0m0s。

當然,RTC_TR以十位和當前小時,分鐘和秒爲單位保存其BCD格式的時間,日期以RTC_DR計數。無論如何,我希望它繼續增加幾個小時,而不是將日期添加到日期註冊表中,因爲我只計算正常運行時間,並且如果我開始計算幾個月和幾天,我會遇到問題。

void RtcConfig(void) 
{ 
    RTC_InitTypeDef RTC_InitStructure; 
    RTC_TimeTypeDef RTC_TimeStructure; 
    RTC_DateTypeDef RTC_DateStructure; 
    uint32_t LSIFreq = 0; 

    /* Enable the PWR clock */ 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 

    /* Allow access to Backup Domain */ 
    PWR_BackupAccessCmd(ENABLE); 

    /* Disable wake-up source(ALARM) to guarantee free access to WUT level-OR input */ 
    RTC_ITConfig(RTC_IT_ALRA, DISABLE); 

    /* Clear Wakeup flag */ 
    PWR_ClearFlag(PWR_FLAG_WU); 

    /* Enable wake-up source(ALARM) to guarantee free access to WUT level-OR input */ 
    RTC_ITConfig(RTC_IT_ALRA, ENABLE); 

    /* Enable the LSI OSC */ 
    RCC_LSICmd(ENABLE); 

    /* Wait till LSI is ready */ 
    while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) 
    {} 

    /* Check if the StandBy flag is set (leaving stand-by) */ 
    if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) 
    { 
    /* Clear StandBy flag */ 
    PWR_ClearFlag(PWR_FLAG_SB); 

    /* Check if the StandBy flag is cleared */ 
    if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) 
    { 
     while(1); 
    } 

    RTC_WaitForSynchro(); 

    /* No need to configure the RTC as the RTC config(clock source, enable, 
    prescaler,...) are kept after wake-up from STANDBY */ 
    } 
    else 
    { 
    /* RTC Configuration ******************************************************/ 
    /* Reset Backup Domain */ 
    RCC_BackupResetCmd(ENABLE); 
    RCC_BackupResetCmd(DISABLE); 

    /* Select the RTC Clock Source */ 
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); 

    /* Enable the RTC Clock */ 
    RCC_RTCCLKCmd(ENABLE); 

    /* Wait for RTC APB registers synchronisation */ 
    RTC_WaitForSynchro(); 

    /* Get the LSI frequency: TIM14 is used to measure the LSI frequency */ 
    LSIFreq = GetLSIFrequency(); 

    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; 
    RTC_InitStructure.RTC_AsynchPrediv = 99; 
    RTC_InitStructure.RTC_SynchPrediv = (LSIFreq/100) - 1; 

    RTC_Init(&RTC_InitStructure); 

    /* Set the time to 00h 00mn 00s AM */ 
    RTC_TimeStructure.RTC_H12  = RTC_H12_PM; 
    RTC_TimeStructure.RTC_Hours = 0; 
    RTC_TimeStructure.RTC_Minutes = 0; 
    RTC_TimeStructure.RTC_Seconds = 0; 
    RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure); 
    } 
} 

uint32 GetLSIFrequency(void) 
{ 
    NVIC_InitTypeDef NVIC_InitStructure; 
    TIM_ICInitTypeDef TIM_ICInitStructure; 
    RCC_ClocksTypeDef RCC_ClockFreq; 

    /* TIM14 configuration *******************************************************/ 
    /* Enable TIM14 clock */ 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); 

    /* Reset TIM14 registers */ 
    TIM_DeInit(TIM14); 

    /* Configure TIM14 prescaler */ 
    TIM_PrescalerConfig(TIM14, 0, TIM_PSCReloadMode_Immediate); 

    /* Connect internally the TIM14_CH1 to the RTC clock output */ 
    TIM_RemapConfig(TIM14, TIM14_RTC_CLK); 

    /* TIM14 configuration: Input Capture mode --------------------- 
    The reference clock(LSE or external) is connected to TIM14 CH1 
    The Rising edge is used as active edge, 
    The TIM14 CCR1 is used to compute the frequency value 
    ------------------------------------------------------------ */ 
    TIM_ICInitStructure.TIM_Channel  = TIM_Channel_1; 
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8; 
    TIM_ICInitStructure.TIM_ICFilter = 0x0; 
    TIM_ICInit(TIM14, &TIM_ICInitStructure); 

    /* Enable the TIM14 global Interrupt */ 
    NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 

    /* Enable TIM14 counter */ 
    TIM_Cmd(TIM14, ENABLE); 

    /* Reset the flags */ 
    TIM14->SR = 0; 

    /* Enable the CC1 Interrupt Request */ 
    TIM_ITConfig(TIM14, TIM_IT_CC1, ENABLE); 


    /* Wait until the TIM14 get 2 LSI edges (refer to TIM14_IRQHandler() in 
    stm32F0xx_it.c file) ******************************************************/ 
    while(CaptureNumber != 2) 
    { 
    } 
    /* Deinitialize the TIM14 peripheral registers to their default reset values */ 
    TIM_DeInit(TIM14); 


    /* Compute the LSI frequency, depending on TIM14 input clock frequency (PCLK1)*/ 
    /* Get SYSCLK, HCLK and PCLKx frequency */ 
    RCC_GetClocksFreq(&RCC_ClockFreq); 

    /* Disable TIM14 counter */ 
    TIM_Cmd(TIM14, DISABLE); 
    TIM_ITConfig(TIM14, TIM_IT_CC1, DISABLE); 

    /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */ 
    return ((RCC_ClockFreq.PCLK_Frequency/PeriodValue) * 8); 
} 

void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) 
{ 
    uint32_t tmpreg = 0; 

    /* Check the parameters */ 
    assert_param(IS_RTC_FORMAT(RTC_Format)); 

    /* Get the RTC_TR register */ 
    tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); 

    /* Fill the structure fields with the read parameters */ 
    RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); 
    RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); 
    RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); 
    RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); 

    /* Check the input parameters format */ 
    if (RTC_Format == RTC_Format_BIN) 
    { 
    /* Convert the structure parameters to Binary format */ 
    RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); 
    RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); 
    RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); 
    } 
} 

uint32 RtcGetTimeSec(void) 
{ 
    RTC_TimeTypeDef RTC_TimeStructure; 

    uint32 currenttimesec = 0; 

    /* Get the Current time in second */ 
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); 
    currenttimesec = ((RTC_TimeStructure.RTC_Hours * 3600) +(RTC_TimeStructure.RTC_Minutes * 60) + 
    RTC_TimeStructure.RTC_Seconds); 

    return currenttimesec; 
} 

回答

1

這是什麼意思溢出。顯示你的代碼&數學

在32位,你可以存儲:

Seconds   Hours   Days    Years 
4294967295  1193046.471  49710.26962  136.1925195 

如果你的預測運行時間超過136.2年使用64位無符號整數,你西港島線能夠數到:

Seconds     Hours    Days   Years   Decades  Centuries Millenniums Aeons (10e9 years) 
18446744073709600000 5124095576030430 213503982334601 584942417355 58494241736 5849424174 584942417 585 

希望對你來說足夠了。

+0

謝謝你的回覆。代碼被添加到問題中。 –