C mktime () and mktime
I recently debugged the stm32L151 single-chip microcomputer because the business needs to convert the time obtained from RTC into a timestamp. During conversion, the obtained timestamp is always incorrect. It has been plagued by two problems.
1. Why is the month obtained from RTC smaller than the actual month?
2. The converted timestamp is always incorrect.
After checking for half a day, I found that I didn't understand struct tm in C correctly.
1 struct tm {
2 int tm_sec; / * seconds, ranging from 0 to 59 * /
3 int tm_min; / * minutes, ranging from 0 to 59 * /
4 int tm_hour; / * hours, range from 0 to 23 * /
5 int tm_mday; / * Day of the month, ranging from 1 to 31 * /
6 int tm_mon; / * month, range from 0 to 11 * /
7 int tm_year; / * number of years since 1900 * /
8 int tm_wday; / * days of the week, ranging from 0 to 6 * /
9 int tm_yday; / * Day of the year, ranging from 0 to 365 * /
10 int tm_isdst; / * daylight saving time * /
11};
Tm. tm_year indicates the number of years since 1900. I always thought this was the current year. Therefore, the timestamp is always incorrect.
Tm. tm_mon indicates the month, which ranges from 0 to 11. That is, 0 indicates the month of July.
Add other RTC code:
static void RTC_Config (void)
{
#if 1
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/ * Enable the PWR clock * /
RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR, ENABLE);
// RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG, ENABLE);
/ * Allow access to RTC * /
PWR_RTCAccessCmd (ENABLE);
/ * LSE used as RTC source clock * /
/ * The RTC Clock may vary due to LSE frequency dispersion. * /
/ * Enable the LSE OSC * /
RCC_LSEConfig (RCC_LSE_ON);
// RCC_LSEConfig (RCC_LSE_Bypass);
/ * Wait till LSE is ready * /
while (RCC_GetFlagStatus (RCC_FLAG_LSERDY) == RESET)
{
}
/ * Select the RTC Clock Source * /
RCC_RTCCLKConfig (RCC_RTCCLKSource_LSE);
/ * Enable the RTC Clock * /
RCC_RTCCLKCmd (ENABLE);
/ * Wait for RTC APB registers synchronisation * /
if (ERROR == RTC_WaitForSynchro ())
{
printf ("Wait for RTC APB registers synchronisation Failed \ r \ n");
}
#endif
/ * Calendar Configuration * /
RTC_InitStructure.RTC_AsynchPrediv = 127; // 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0x120; / * (37KHz / 128)-1 = 0x120 * /
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
if (RTC_Init (& RTC_InitStructure) == ERROR)
{
printf ("Rtc_Init failed \ r \ n");
}
RTC_TimeStampCmd (RTC_TimeStampEdge_Rising, ENABLE);
}
time_t GetTimeStamp (void) // Get timestamp
{
RTC_DateTypeDef sdatestructure;
RTC_TimeTypeDef stimestructure;
struct tm tmstr;
RTC_GetDate (RTC_Format_BIN, & sdatestructure);
RTC_GetTime (RTC_Format_BIN, & stimestructure);
tmstr.tm_year = sdatestructure.RTC_Year;
tmstr.tm_mon = sdatestructure.RTC_Month;
tmstr.tm_mday = sdatestructure.RTC_Date;
tmstr.tm_hour = stimestructure.RTC_Hours;
tmstr.tm_min = stimestructure.RTC_Minutes;
tmstr.tm_sec = stimestructure.RTC_Seconds;
printf ("% u-% u-% u-% u-% u-% u. \ r \ n", tmstr.tm_year + 1900, tmstr.tm_mon + 1, tmstr.tm_mday, tmstr.tm_hour, tmstr.tm_min , tmstr.tm_sec);
return mktime (& tmstr);
}
void SetRtcTime (time_t timestamp) // Set RTC time
{
RTC_DateTypeDef sdatestructure;
RTC_TimeTypeDef stimestructure;
struct tm * tmstr;
tmstr = localtime (& timestamp);
printf ("set >>% u-% u-% u-% u-% u-% u. \ r \ n", tmstr-> tm_year + 1900, tmstr-> tm_mon + 1, tmstr-> tm_mday, tmstr -> tm_hour, tmstr-> tm_min, tmstr-> tm_sec);
sdatestructure.RTC_Year = (tmstr-> tm_year);
sdatestructure.RTC_Month = tmstr-> tm_mon;
sdatestructure.RTC_Date = tmstr-> tm_mday;
sdatestructure.RTC_WeekDay = tmstr-> tm_wday;
stimestructure.RTC_Hours = tmstr-> tm_hour;
stimestructure.RTC_Minutes = tmstr-> tm_min;
stimestructure.RTC_Seconds = tmstr-> tm_sec;
RTC_SetTime (RTC_Format_BIN, & stimestructure);
RTC_SetDate (RTC_Format_BIN, & sdatestructure);
}