C语言mktime()
最近在调试stm32L151单片机,因为业务需要将从RTC获取的时间转换成时间戳。转换的时候发现获取的时间戳一直不对。一直被两个问题困扰。
1.从RTC获取出来的月份为什么比实际月份小1?
2.转换得来的时间戳一直不对。
检查半天发现原来是我没有正确的理解C中的struct tm
1 struct tm { 2 int tm_sec; /* 秒,范围从 0 到 59 */ 3 int tm_min; /* 分,范围从 0 到 59 */ 4 int tm_hour; /* 小时,范围从 0 到 23 */ 5 int tm_mday; /* 一月中的第几天,范围从 1 到 31 */ 6 int tm_mon; /* 月份,范围从 0 到 11 */ 7 int tm_year; /* 自 1900 起的年数 */ 8 int tm_wday; /* 一周中的第几天,范围从 0 到 6 */ 9 int tm_yday; /* 一年中的第几天,范围从 0 到 365 */ 10 int tm_isdst; /* 夏令时 */ 11 };
tm.tm_year表示的是自1900起的年数。我一直以为这个是当前的年份。所以导致了时间戳一直不对。
tm.tm_mon表示月份,范围从0到11 也就是说0代表的是1月份。
另外附上RTC其他代码:
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 varies 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) //获取时间戳 { 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) //设置RTC时间 { RTC_DateTypeDef sdatestructure; RTC_TimeTypeDef stimestructure; struct tm *tmstr; tmstr = localtime(×tamp); 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); }
Done is better than perfect.