ESP8266学习笔记(11)——SNTP接口使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_36347513/article/details/97935332

一、SNTP简介

简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟

二、SNTP接口

SNTP 接口位于 ESP8266_NONOS_SDK/include/sntp.h


三、初始化SNTP

设置三个时间服务器域名并初始化。

/**
 @brief 初始化SNTP服务
 @param 无
 @return 无
*/
void ICACHE_FLASH_ATTR
SNTP_Init(void)
{
	sntp_setservername(0,"0.cn.pool.ntp.org");
	sntp_setservername(1,"1.cn.pool.ntp.org");
	sntp_setservername(2,"2.cn.pool.ntp.org");
	sntp_init();
}

四、获取SNTP时间

4.1 获取时间字符串

/**
 @brief 获取SNTP时间
 @param pRealTime -[in&out] 实时时间
 @return 无
*/
void ICACHE_FLASH_ATTR
GetSntpTime(char *pRealTime)
{
	uint32_t time = sntp_get_current_timestamp();
	os_sprintf(pRealTime, "%s", sntp_get_real_time(time));
	os_sprintf(pRealTime, "%s", sntpTimeChangeToSimpleDateFormat(pRealTime));
}

由于通过 sntp_get_real_time()函数 获取出来的时间字符串格式为Thu Dec 27 22:40:21 2018,不是我想要的格式,所以需要重新转换格式。

4.2 SNTP时间转化为简单日期格式

typedef struct sntpData_t
{
	uint8 week;
	uint8 month;
	uint8 day;
	uint8 hour;
	uint8 minute;
	uint8 second;
	uint8 year;
} SntpData_t;

/**
 @brief SNTP时间转化为简单日期格式
 @param pSntpRealTime -[in] 实时时间
 @return 简单日期格式时间字符串
*/
static char *ICACHE_FLASH_ATTR
sntpTimeChangeToSimpleDateFormat(char *pSntpRealTime)
{
	if(!pSntpRealTime)
	{
		return "";
	}

	pSntpRealTime[24] = '\0';						// 不要年份后面的数据
	SntpData_t sntpData;
	uint8 dateType[7] = {3, 3, 2, 2, 2, 2, 4};		// 3-Fri 3-May 2-31 2-11: 2-21: 2-42 4-2019
	uint8 temp[5];
	uint8 i = 0, j = 0;

	while(*pSntpRealTime != '\0')
	{
		if(*pSntpRealTime == ' ' || *pSntpRealTime == ':')
		{
			pSntpRealTime++;
			i++;
		}
		else
		{
			os_memset(temp, '\0', 5);
			for(j = 0; j < dateType[i]; j++)
			{
				temp[j] = *pSntpRealTime;
				pSntpRealTime++;
			}
			switch(i)
			{
			case 0: // 周
				sntpData.week = checkWahtWeek(temp);
				break;
			case 1: // 月
				sntpData.month = checkWahtMonth(temp);
				break;
			case 2: // 日
				sntpData.day = checkWahtDay(temp);
				break;
			case 3: // 时
				sntpData.hour = checkWahtHour(temp);
				break;
			case 4: // 分
				sntpData.minute = checkWahtMinute(temp);
				break;
			case 5: // 秒
				sntpData.second = checkWahtSecond(temp);
				break;
			case 6: // 年
				sntpData.year = checkWahtYear(temp);
				break;
			default:
				break;
			}
		}
	}

	os_memset(pSntpRealTime, 0, 24);
	os_sprintf(pSntpRealTime, "20%x-%02x-%02x %02x:%02x:%02x",
								sntpData.year, sntpData.month,
								sntpData.day, sntpData.hour,
								sntpData.minute, sntpData.second);
	return pSntpRealTime;
}

4.3 解析年月日时分秒

/**
 @brief 检查星期几
 @param pWeek -[in] 待检测字符串
 @return 星期几
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtWeek(char *pWeek)
{
	if(!pWeek)
	{
		return 0;
	}

	uint8 week;
	if(strcmp(pWeek, "Mon") == 0)
	{
		week = 1;									// 星期一
	}
	else if(strcmp(pWeek, "Tue") == 0)
	{
		week = 2;									// 星期二
	}
	else if(strcmp(pWeek, "Wed") == 0)
	{
		week = 3;									// 星期三
	}
	else if(strcmp(pWeek, "Thu") == 0)
	{
		week = 4;									// 星期四
	}
	else if(strcmp(pWeek, "Fri") == 0)
	{
		week = 5;									// 星期五
	}
	else if(strcmp(pWeek, "Sat") == 0)
	{
		week = 6;									// 星期六
	}
	else if(strcmp(pWeek, "Sun") == 0)
	{
		week = 7;									// 星期天
	}
	return week;
}

/**
 @brief 检查几月份
 @param pMonth -[in] 待检测字符串
 @return 几月份
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtMonth(char *pMonth)
{
	if(!pMonth)
	{
		return 0;
	}

	uint8 month;
	if(strcmp(pMonth, "Jan") == 0)
	{
		month = 1;									// 一月
	}
	else if(strcmp(pMonth, "Feb") == 0)
	{
		month = 2;									// 二月
	}
	else if(strcmp(pMonth, "Mar") == 0)
	{
		month = 3;									// 三月
	}
	else if(strcmp(pMonth, "Apr") == 0)
	{
		month = 4;									// 四月
	}
	else if(strcmp(pMonth, "May") == 0)
	{
		month = 5;									// 五月
	}
	else if(strcmp(pMonth, "Jun") == 0)
	{
		month = 6;									// 六月
	}
	else if(strcmp(pMonth, "Jul") == 0)
	{
		month = 7;									// 七月
	}
	else if(strcmp(pMonth, "Aug") == 0)
	{
		month = 8;									// 八月
	}
	else if(strcmp(pMonth, "Sep") == 0)
	{
		month = 9;									// 九月
	}
	else if(strcmp(pMonth, "Oct") == 0)
	{
		month = 10;									// 十月
	}
	else if(strcmp(pMonth, "Nov") == 0)
	{
		month = 11;									// 十一月
	}
	else if(strcmp(pMonth, "Dec") == 0)
	{
		month = 12;									// 十二月
	}
	return month;
}

/**
 @brief 检查几日
 @param pDay -[in] 待检测字符串
 @return 几日
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtDay(char *pDay)
{
	if(!pDay)
	{
		return 0;
	}

	uint8 day = (*pDay & 0x0f) << 4;
	day = day | (*(pDay+1) & 0x0f);

	return day;
}

/**
 @brief 检查几时
 @param pHour -[in] 待检测字符串
 @return 几时
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtHour(char *pHour)
{
	if(!pHour)
	{
		return 0;
	}

	uint8 hour = (*pHour & 0x0f) << 4;
	hour = hour | (*(pHour+1) & 0x0f);

	return hour;
}

/**
 @brief 检查几分
 @param pMinute -[in] 待检测字符串
 @return 几分
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtMinute(char *pMinute)
{
	if(!pMinute)
	{
		return 0;
	}

	uint8 minute = (*pMinute & 0x0f) << 4;
	minute = minute | (*(pMinute+1) & 0x0f);

	return minute;
}

/**
 @brief 检查几秒
 @param pSecond -[in] 待检测字符串
 @return 几秒
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtSecond(char *pSecond)
{
	if(!pSecond)
	{
		return 0;
	}

	uint8 second = (*pSecond & 0x0f) << 4;
	second = second | (*(pSecond+1) & 0x0f);

	return second;
}

/**
 @brief 检查几年
 @param pYear -[in] 待检测字符串
 @return 几年
*/
static uint8 ICACHE_FLASH_ATTR
checkWahtYear(char *pYear)
{
	if(!pYear)
	{
		return 0;
	}

	uint8 year = (*(pYear+2) & 0x0f) << 4;
	year = year | (*(pYear+3) & 0x0f);

	return year;
}

五、使用方法

首先,在 user_main.cuser_init() 中调用 SNTP_Init() 初始化。

void ICACHE_FLASH_ATTR
user_init(void)
{
  ···
  SNTP_Init();														// SNTP服务初始化
  ···
}

在其他地方调用 GetSntpTime() 获取时间

uint8 time[25];
GetSntpTime(time);
os_printf("%s\n", time);

获取到时间格式为:
2019-07-31 17:01:01


• 由 Leung 写于 2019 年 7 月 31日

• 参考:esp8266_SNTP时间获取处理成BCD码
    ESP8266 Non-OS SDK API参考[7qq6]

猜你喜欢

转载自blog.csdn.net/qq_36347513/article/details/97935332