物联网相关技术研究物联网loT从业者

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

2019-07-31  本文已影响2人  Leung_ManWah

一、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]

上一篇下一篇

猜你喜欢

热点阅读