2017-06-19 197 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

谢谢你的回复。代码被添加到问题中。 –

相关问题