使用SNTP协议获取ESP8266网络时间

描述

1. NTP和SNTP协议

NTP是网络时间协议(Network Time Protocol),用来同步网络设备(如PC、手机)的时间的协议

SNTP由 NTP改编而来(简单网络时间协议,Simple NTP)大大简化了 NTP协议,同时也能保证时间达到一定的精确度。在实际应用中,SNTP协议主要被用来同步因特网上计算机的时间

SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点)模式操作。SNTP服务器通过接收 GPS信号或自带的原子钟作为系统的时间基准。单播模式下,SNTP客户端能够通过定期访问 SNTP服务器获得准确的时间信息,用于调整客户端自身所在系统的时间,达到同步时间的目的。广播模式下,SNTP服务器周期性地发送消息给指定的 IP广播地址或者 IP多播地址。SNTP客户端通过监听这些地址来获得时间信息

一些常见的 NTP服务器

  • 最常见的NTP服务器:www.pool.ntp.org/zone/cn
  • 其国内地址为:cn.pool.ntp.org
  • Windows系统上自带的两个:time.windows.com 和 time.nist.gov
  • Mac OS上自带的两个:time.apple.com 和 time.asia.apple.com

ESP8266

2. SNTP接口说明

设置SNTP服务器:通过IP地址设置SNTP服务器,最多支持设置3个

void sntp_setserver(unsigned char idx, ip_addr_t *addr)
//idx 服务器编号,最多⽀持3个(0~2);0为主服务器,1和2为备用
//addr 服务器IP地址;需自行确保传入的是合法SNTP服务器地址

设置SNTP服务器:通过域名设置SNTP服务器,最多支持设置3个

void sntp_setservername(unsigned char idx, char *server)
//idx 服务器编号,最多⽀持3个(0~2);0号为主服务器,1和2号为备用
//server 服务器域名;需自行确保传入的是合法SNTP服务器域名

初始化和关闭SNTP

void sntp_init(void)
void sntp_stop(void)

查询当前距离基准时间(1970.01.01 00:00:00 GMT+8)的时间戳,单位为秒

uint32 sntp_get_current_timestamp()
//返回值:距离基准时间的时间戳

查询实际时间(GMT+8)

char* sntp_get_real_time(long t)
//t 与基准时间相距的时间戳
//返回值:实际时间

3. SNTP功能实现

SNTP功能开发:在 freeRTOS下新建 SNTP任务,实现定时5秒串口打印一次网络时间

任务流程如下示:

ESP8266

实现步骤如下:

在ESP8266_RTOS_SDK目录下新建sntp文件夹,把ESP8266开发环境搭建中的 app目录下所有文件拷贝到该文件夹中

在user目录下新建 user_sntp.c文件,并添加如下代码

/*******************user_sntp.c********************************/
char* SntpServerNames[3] ={
"ntp1.aliyun.com",
"ntp2.aliyun.com",
"ntp3.aliyun.com"
};
//ATaskSntp任务
void ATaskSntp( void *pvParameters ){
  STATION_STATUS Status;
  uint32 time;
  do{
    Status = wifi_station_get_connect_status();
    vTaskDelay(100);   
  }while(Status != STATION_GOT_IP);
  printf("task is SNTP
");
  printf("STATION_GOT_IP!
");
  sntp_setservername(0,SntpServerNames[0]);
  sntp_setservername(1,SntpServerNames[1]);
  sntp_setservername(2,SntpServerNames[2]);
  sntp_init();
  for(;;){
    time = sntp_get_current_timestamp();
    if(time){
      printf("current date:%s
",sntp_get_real_time(time));
    }
    vTaskDelay(500);
  }
  vTaskDelete(NULL);
}
//Sntp_init 初始化
void Sntp_init(void){
  xTaskCreate(ATaskSntp, "Sntp", 512, NULL, 4, NULL);
}

在include目录下新建 user_sntp.h文件,并添加声明

void ATaskSntp(void *pvParameters);
void Sntp_init(void);

在user_main.c文件中的 user_init()函数下添加如下代码

#define SSID "Hotspot"    //ESP8266要加入的无线网
#define PASSWORD "88888888"
void ICACHE_FLASH_ATTR
user_init(void){
  printf("SDK version:%s
", system_get_sdk_version());
  Led_init();
  wifi_set_opmode(STATION_MODE);
  struct station_config *config = (struct station_config *)        zalloc(sizeof(struct station_config));
  sprintf(config->ssid,SSID);
  sprintf(config->password,PASSWORD);
  wifi_station_set_config(config);
  free(config);
  wifi_station_set_auto_connect(TRUE);    
  Sntp_init();
  xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);
}

在ESP8266编译器中编译完成,烧写 bin文件到 ESP8266,打开串口助手,每5秒输出一次实时时间

ESP8266

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分