STM32 之 时间戳的解析与生成

什么是时间戳
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。 它的提出主要是为用户提供一份电子证据, 以证明用户的某些数据的产生时间。 在实际应用上, 它可以使用在包括电子商务、 金融活动的各个方面, 尤其可以用来支撑公开密钥基础设施的 “不可否认” 服务。

STM32 怎么使用时间戳
STM32 使用时间戳主要涉及两方面:
1 获取时间戳后解析成本地时间
2 根据本地时间生成时间戳
注:测试时,可以用在线工具 https://tool.lu/timestamp/ 转换时间戳和本地时间

这里的时间戳解析和生成主要用到 C 中 time.h 提供的 mktime 函数和 localtime 函数,前者用于解析时间戳,生成 tm 格式的数据,后者根据 tm 格式的数据生成时间戳( 详细内容参考 time.h 文件中的注释)。
下面看下 tm 数据结构的定义:
struct tm {
    int tm_sec;   /* seconds after the minute, 0 to 60
                     (0 - 60 allows for the occasional leap second) */
    int tm_min;   /* minutes after the hour, 0 to 59 */
    int tm_hour;  /* hours since midnight, 0 to 23 */
    int tm_mday;  /* day of the month, 1 to 31 */
    int tm_mon;   /* months since January, 0 to 11 */
    int tm_year;  /* years since 1900 */
    int tm_wday;  /* days since Sunday, 0 to 6 */
    int tm_yday;  /* days since January 1, 0 to 365 */
    int tm_isdst; /* Daylight Savings Time flag */
    union {       /* ABI-required extra fields, in a variety of types */
        struct {
            int __extra_1, __extra_2;
        };
        struct {
            long __extra_1_long, __extra_2_long;
        };
        struct {
            char *__extra_1_cptr, *__extra_2_cptr;
        };
        struct {
            void *__extra_1_vptr, *__extra_2_vptr;
        };
    };
};
在这里我们要注意如下内容:
1 tm 中定义的 year 是从 1900 开始的,而 STM32 RTC中设置的 year 取值范围在 0-99,那么赋值时要在 RTC year上加 100。即:stm.tm_year = RTC_DateStruct.RTC_Year + 100;
2 同理,tm 中定义的 months 取值范围是 0-11,而 STM32 RTC中设置 month 取值范围在 1-12,那么在赋值时要在 RTC month 上 减 1。即:stm.tm_mon= RTC_DateStruct.RTC_Month-1;
3 我们在生成时间戳时是将 本地时间 转为 UTC 时间,其关系为: UTC + 时区差 = 本地时间,那么我们设置的UTC时间为:UTC = 本地时间(北京时间))- 8
注意了如上细节后,下面分别实现时间戳解析成本地时间函数和根据本地时间生成时间戳函数。

本地时间生成时间戳函数
char* time_to_timestamp(void)
{
	unsigned int timestamp;
	struct tm stm;
	char *timestamp_buf;
	char *buf;
	timestamp_buf = (char *)mem_malloc(10);
	buf = (char *)mem_malloc(100);
	
	RTC_DateTypeDef RTC_DateStruct;
	RTC_TimeTypeDef	RTC_TimeStruct;
	RTC_GetDate(RTC_Format_BIN,&RTC_DateStruct);
	RTC_GetTime(RTC_Format_BIN,&RTC_TimeStruct);
	
	stm.tm_year = RTC_DateStruct.RTC_Year + 100;	//RTC_Year rang 0-99,but tm_year since 1900
	stm.tm_mon	= RTC_DateStruct.RTC_Month-1;		//RTC_Month rang 1-12,but tm_mon rang 0-11
	stm.tm_mday	= RTC_DateStruct.RTC_Date;			//RTC_Date rang 1-31 and tm_mday rang 1-31
	stm.tm_hour	= RTC_TimeStruct.RTC_Hours-8;			//RTC_Hours rang 0-23 and tm_hour rang 0-23
	stm.tm_min	= RTC_TimeStruct.RTC_Minutes;   //RTC_Minutes rang 0-59 and tm_min rang 0-59
	stm.tm_sec	= RTC_TimeStruct.RTC_Seconds;		
	sprintf(buf,"\r\nrtc %d-%d-%d  %d.%d.%d\r\n",\
	RTC_DateStruct.RTC_Year,RTC_DateStruct.RTC_Month,RTC_DateStruct.RTC_Date,\
	RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes,RTC_TimeStruct.RTC_Seconds);
	USART_COM3_Send_data(buf,strlen(buf));
	mem_free(buf);
	sprintf(timestamp_buf,"%u",mktime(&stm));
	USART_COM3_Send_data(timestamp_buf,strlen(timestamp_buf));
	return timestamp_buf;
}
时间戳解析成本地时间函数
void timestamp_to_time(unsigned int timestamp)
{
	struct tm *stm= NULL;
	char *buf;
	buf = (char *)mem_malloc(100);
	
	RTC_DateTypeDef RTC_DateStruct;
	RTC_TimeTypeDef	RTC_TimeStruct;
	
	stm = localtime(×tamp);
	RTC_DateStruct.RTC_Year = stm->tm_year - 100;
	RTC_DateStruct.RTC_Month = stm->tm_mon + 1;
	RTC_DateStruct.RTC_Date = stm->tm_mday;
	RTC_TimeStruct.RTC_Hours = stm->tm_hour + 8;
	RTC_TimeStruct.RTC_Minutes = stm->tm_min;
	RTC_TimeStruct.RTC_Seconds = stm->tm_sec;
	
	sprintf(buf,"\r\nstm %d-%d-%d  %d.%d.%d\r\n",\
	stm->tm_year,stm->tm_mon,stm->tm_mday,\
	stm->tm_hour,stm->tm_min,stm->tm_sec);
	USART_COM3_Send_data(buf,strlen(buf));
	mem_free(buf);
	
	RTC_SetDate(RTC_Format_BIN,&RTC_DateStruct);
	RTC_SetTime(RTC_Format_BIN,&RTC_TimeStruct);
}
 
  

你可能感兴趣的:(STM32 之 时间戳的解析与生成)