Timer 从RTC获取正常运行时间

Timer 从RTC获取正常运行时间,timer,arm,stm32,uptime,real-time-clock,Timer,Arm,Stm32,Uptime,Real Time Clock,我想在几秒钟内从RTC获得系统的正常运行时间。关键是,虽然我可以从RTC时间寄存器(RTC_TR)中求和值,但它最多只能工作24小时,然后在将一天添加到RTC日期寄存器(RTC_DR)时溢出 如何从启动系统开始计算秒数?我不需要日历 下面是我对“溢出”的解释 我已经根据STM的RTC_LSI示例为StdPeriph配置了RTC,并且只设置了时间而不是日期 但是,当我使用RTC_GetTime函数从RTC_TR获取时间时,23h59m59秒后,时间返回到0h0m0s 当然,RTC_TR以其BCD格

我想在几秒钟内从RTC获得系统的正常运行时间。关键是,虽然我可以从RTC时间寄存器(RTC_TR)中求和值,但它最多只能工作24小时,然后在将一天添加到RTC日期寄存器(RTC_DR)时溢出

如何从启动系统开始计算秒数?我不需要日历

下面是我对“溢出”的解释

我已经根据STM的RTC_LSI示例为StdPeriph配置了RTC,并且只设置了时间而不是日期

但是,当我使用RTC_GetTime函数从RTC_TR获取时间时,23h59m59秒后,时间返回到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;
}

这是什么意思。展示你的代码和数学

在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

希望这对你来说足够了。

这是什么意思。展示你的代码和数学

在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

希望你的回答足够了。

谢谢你的回复。代码已添加到问题中。谢谢您的答复。代码被添加到问题中。