-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;
}
謝謝你的回覆。代碼被添加到問題中。 –