一、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-2019uint8 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.c 的 user_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]