本文來源電子發(fā)燒友社區(qū),作者:李元江, 帖子地址:https://bbs.elecfans.com/jishu_2025289_1_1.html
今天的帖子我寫的是關于網絡時間同步,主要功能為按下按鍵,進入網絡NTP時間獲取功能,最后完成網絡時間的同步。
首先說說怎么獲取網絡時鐘。現(xiàn)在很多NTP時間服務器,從服務器中就能獲取網絡時間。我所使用的時間服務器為time.windows.com,IP地址為52.231.114.183,端口號為123,采用UDP協(xié)議。需要先采用UDP方式,連接到該服務器。之后再發(fā)送48個字節(jié)的十六進制數(shù)(不用回車加換行):0b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 6d d9 00 00 00 00 00然后就可以看到時間服務器返回來的數(shù)據(jù),下圖是我使用調試組手獲得的數(shù)據(jù),正常情況下一共會收到48個字節(jié)數(shù)據(jù),第41-44字節(jié)的數(shù)據(jù)是我們所需要的時間數(shù)據(jù)。如下獲得的NTP數(shù)據(jù)為0xE398556A。
-
注意:該NTP數(shù)據(jù)是從1900年開始算的,而時間戳是從1970年開始算的
二、軟件設計
- #ifndef PARAM_HOTSPOT_SSID
- #define PARAM_HOTSPOT_SSID "YYYYY" // your AP SSID
- #endif
- ?
- #ifndef PARAM_HOTSPOT_PSK
- #define PARAM_HOTSPOT_PSK"123456"http:// your AP PSK
- #endif
該函數(shù)主要完成網絡連接,連接時間服務器及時間獲取,并根據(jù)獲取到的NTP時間計算出對應的時間戳。獲取到的NTP時間數(shù)值是從1900年開始計算,時間戳數(shù)值從1970年開始計算。因此需要減去1970-1900年間的數(shù)值,才能得到我們所需的時間戳。
- #include
- #include
- #include
- #include
- ?
- #include "net_demo.h"
- #include "net_common.h"
- #include "net_params.h"
- #include "wifi_connecter.h"
- #include "ohos_init.h"
- #include "cmsis_os2.h"
- ?
- #define NTPIPADDR "52.231.114.183"
- #define NTPPORT 123
- ?
- #define NTP_TIMESTAMP_DELTA 2208988800ull
- ?
- externuint32_t timedata;
- extern bool GetNTPFlag;
- ?
- void getNtpTime(void)
- {
- ?
- uint32_t NTP_Time;
- unsigned char buf[48];//存儲NTP服務器返回的數(shù)據(jù)
- unsigned char NTP_Data[]=
- { 0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x0d6,0x06d,0x0d9,0x00,0x00,0x00,0x00,0x00};
- ; //48字節(jié)的報文
- ?
- ?
- WifiDeviceConfig config = {0};
- ?
- // 準備AP的配置參數(shù)
- strcpy(config.ssid, PARAM_HOTSPOT_SSID);
- strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
- config.securityType = PARAM_HOTSPOT_TYPE;
- osDelay(10);
- int netId = ConnectToHotspot(&config);
- ?
- ssize_t retval = 0;
- int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // UDP socket
- ?
- struct sockaddr_in toAddr = {0};
- toAddr.sin_family = AF_INET;
- toAddr.sin_port = htons(NTPPORT); // 端口號,從主機字節(jié)序轉為網絡字節(jié)序
- if (inet_pton(AF_INET, NTPIPADDR, &toAddr.sin_addr) <= 0) { // 將主機IP地址從“點分十進制”字符串 轉化為 標準格式(32位整數(shù))
- printf("inet_pton failed!rn");
- goto do_cleanup;
- }
- ?
- // UDP socket 是 “無連接的” ,因此每次發(fā)送都必須先指定目標主機和端口,主機可以是多播地址
- retval = sendto(sockfd, NTP_Data, 48, 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
- if (retval < 0) {
- printf("sendto failed!rn");
- goto do_cleanup;
- }
- ?
- printf("send NTP message %ld done!rn",retval);
- for(uint8_t i = 0;i<48;i++)
- {
- printf("%02xt",(unsigned char)NTP_Data[i]);
- if( (i+1) % 8 == 0 )
- printf("rn");
- }
- struct sockaddr_in fromAddr = {0};
- socklen_t fromLen = sizeof(fromAddr);
- ?
- // UDP socket 是 “無連接的” ,因此每次接收時前并不知道消息來自何處,通過 fromAddr 參數(shù)可以得到發(fā)送方的信息(主機、端口號)
- retval = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&fromAddr, &fromLen);
- if (retval <= 0) {
- printf("recvfrom failed or abort, %ld, %d!rn", retval, errno);
- goto do_cleanup;
- }
- ?
- NTP_Time = buf[40]<<24 | buf[40+1]<<16|buf[40+2]<<8 |buf[40+3];
- timedata = NTP_Time - NTP_TIMESTAMP_DELTA;
- ?
- printf("timedata is %ldn",timedata);
- //response[retval] = '';
- printf("recv UDP message {%s} %ld done!rn", buf, retval);
- printf("peer info: ipaddr = %s, port = %drn", inet_ntoa(fromAddr.sin_addr), ntohs(fromAddr.sin_port));
- GetNTPFlag = false;
- ?
- for(uint8_t i = 0;i<48;i++)
- {
- printf("%02xt",(unsigned char)buf[i]);
- if( (i+1) % 8 == 0 )
- printf("rn");
- }
- do_cleanup:
- ?
- GetNTPFlag = false;
- printf("do_cleanup...rn");
- close(sockfd);
- ?
- printf("disconnect to AP ...rn");
- DisconnectWithHotspot(netId);
- printf("disconnect to AP done!rn");
- }
在oled_demo.c文件中增加獲取時間功能代碼。按下按鍵進入時間同步功能。
- sources = [
- "oled_demo.c",
- "oled_ssd1306.c",
- "timeconv.c",
- "envrionment_demo.c",
- "aht20.c",
- "wifi_connecter.c",
- "getNTP.c"
- ]
四、總結
-
wi-fi
+關注
關注
14文章
2146瀏覽量
124566 -
HarmonyOS
+關注
關注
79文章
1977瀏覽量
30256 -
HiSpark
+關注
關注
1文章
156瀏覽量
6938
發(fā)布評論請先 登錄
相關推薦
評論