美文网首页物联网相关技术研究物联网loT从业者
ESP8266学习笔记(11)——SNTP接口使用

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

作者: Leung_ManWah | 来源:发表于2019-07-31 17:06 被阅读2次

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

    相关文章

      网友评论

        本文标题:ESP8266学习笔记(11)——SNTP接口使用

        本文链接:https://www.haomeiwen.com/subject/ejytdctx.html