W5500-EVB-PICO通过SNTP获取网络时间(十一)

news2024/11/18 8:37:15

前言

        上一章我们用W5500_EVB_PICO 开发板做Ping数据测试IP检测连通性,那么本章我们进行W5500_EVB_PICO SNTP的测试。

什么是NTP?

        NTP(Network Time Protocol)网络时间协议基于UDP,用于网络时间同步的协议,使网络中的计算机时钟同步到UTC,再配合各个时区的偏移调整就能实现精准同步对时功能。提供NTP对时的服务器有很多,比如微软的NTP对时服务器,利用NTP服务器提供的对时功能,可以使我们的设备时钟系统能够正确运行。

NTP报文格式

NTP报文格式如上图所示,它的字段含义参考如下:

LI 闰秒标识器,占用2个bit

VN 版本号,占用3个bits,表示NTP的版本号,现在为3

Mode 模式,占用3个bits,表示模式

stratum(层),占用8个bits

Poll 测试间隔,占用8个bits,表示连续信息之间的最大间隔

Precision 精度,占用8个bits,,表示本地时钟精度

Root Delay根时延,占用8个bits,表示在主参考源之间往返的总共时延

Root Dispersion根离散,占用8个bits,表示在主参考源有关的名义错误

Reference Identifier参考时钟标识符,占用8个bits,用来标识特殊的参考源    

参考时间戳,64bits时间戳,本地时钟被修改的最新时间。

原始时间戳,客户端发送的时间,64bits。

接受时间戳,服务端接受到的时间,64bits。

传送时间戳,服务端送出应答的时间,64bits。

认证符(可选项)

连接方式

开发板和主机都接在路由器LAN口

获取网络时间测试

1.相关代码

        我们打开例程中库文件的sntp_client.c文件,可以看到两个有关于ntp的两个函数,分别是SNTP_init函数和SNRTP_run函数,SNTP_init函数第一个参数是socket号,第二参数是获取时间的服务器ip,第三个参数是所要获取时间的时区(中国是东八区,sntp.c文件中能找到对应编号),第四个参数是缓存buf;然后SNTP_run的函数是传入一个datetime结构类型的参数,结构体里面有相应的参数。

void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf)
{
    NTP_SOCKET = s;

    NTPformat.dstaddr[0] = ntp_server[0];
    NTPformat.dstaddr[1] = ntp_server[1];
    NTPformat.dstaddr[2] = ntp_server[2];
    NTPformat.dstaddr[3] = ntp_server[3];
    time_zone = tz;
    data_buf = buf;
    uint8_t Flag;
    NTPformat.leap = 0;           /* leap indicator */
    NTPformat.version = 4;        /* version number */
    NTPformat.mode = 3;           /* mode */
    NTPformat.stratum = 0;        /* stratum */
    NTPformat.poll = 0;           /* poll interval */
    NTPformat.precision = 0;      /* precision */
    NTPformat.rootdelay = 0;      /* root delay */
    NTPformat.rootdisp = 0;       /* root dispersion */
    NTPformat.refid = 0;          /* reference ID */
    NTPformat.reftime = 0;        /* reference time */
    NTPformat.org = 0;            /* origin timestamp */
    NTPformat.rec = 0;            /* receive timestamp */
    NTPformat.xmt = 1;            /* transmit timestamp */
    Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag
    memcpy(ntpmessage,(void const*)(&Flag),1);
}
int8_t SNTP_run(datetime *time)
{
    uint16_t RSR_len;
    uint32_t destip = 0;
    uint16_t destport;
    uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
    switch(getSn_SR(NTP_SOCKET))
    {
    case SOCK_UDP:
        if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
        {
            if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE;   // if Rx data size is lager than TX_RX_MAX_BUF_SIZE
            recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
            get_seconds_from_ntp_server(data_buf,startindex);
            time->yy = Nowdatetime.yy;
            time->mo = Nowdatetime.mo;
            time->dd = Nowdatetime.dd;
            time->hh = Nowdatetime.hh;
            time->mm = Nowdatetime.mm;
            time->ss = Nowdatetime.ss;
            ntp_retry_cnt=0;
            close(NTP_SOCKET);
            return 1;
        }
        if(ntp_retry_cnt<0xFFFF)
        {
            if(ntp_retry_cnt==0)//first send request, no need to wait
            {
                sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
                ntp_retry_cnt++;
            }
            else // send request again? it should wait for a while
            {
                if((ntp_retry_cnt % 0xFFF) == 0) //wait time
                {
                    sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
#ifdef _SNTP_DEBUG_
                    printf("ntp retry: %d\r\n", ntp_retry_cnt);
#endif
                    ntp_retry_cnt++;
                }
            }
        }
        else //ntp retry fail
        {
            ntp_retry_cnt=0;
#ifdef _SNTP_DEBUG_
            printf("ntp retry failed!\r\n");
#endif
            close(NTP_SOCKET);
        }
        break;
    case SOCK_CLOSED:
        socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0);
        break;
    }
    // Return value
    // 0 - failed / 1 - success
    return 0;
}

         datetime类型结构体

typedef struct _datetime
{
    uint16_t yy;
    uint8_t mo;
    uint8_t dd;
    uint8_t hh;
    uint8_t mm;
    uint8_t ss;
} datetime;

2.测试现象

编译烧录完成之后打开串行监视器,复位一下W5500_EVB_PICO,然后串口上就会开始打印网络配置信息,然后开始获取时间,看到串口上一秒打印一次时间,表示成功。

相关连接:

本章例程链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/956445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何高效进行测试用例评审

1.用例评审的目的 为了减少测试人员执行阶段做无效工作&#xff0c;执行无效case&#xff0c;提交无效缺陷&#xff08;可以友情提醒研发同学&#xff0c;讲到自己负责的相关模块时&#xff0c;注意下是否存在异议点&#xff09;为了避免三方&#xff08;产品、研发、测试&…

多项式求逆

已知 F F F&#xff0c;求 G G G 考虑倍增 F ( x ) ∗ H ( x ) ≡ 1 ( m o d x n / 2 ) F(x) * H(x) \equiv 1 \pmod{x^{n/2}} F(x)∗H(x)≡1(modxn/2) F ( x ) ∗ G ( x ) ≡ 1 ( m o d x n / 2 ) F(x) * G(x) \equiv 1 \pmod{x^{n/2}} F(x)∗G(x)≡1(modxn/2) 假设 H H…

噪声的产生机理和来源

引言&#xff1a;噪声广泛存在于自然界&#xff0c;上节揭示了噪声的本质&#xff0c;噪声按照噪声携带能量的强弱分为功率型噪声和信号型噪声&#xff0c;功率型噪声持续时间短&#xff0c;能量强&#xff0c;对设备的寿命具有很大的影响&#xff0c;而信号型噪声顾名思义来源…

不想出门?那就把“自然”搬进家里吧!

为自然主题房间寻找灵感&#xff1a; 简单创意 以自然为主题的房间将自然灵感的色调&#xff08;棕色、灰色、米色、白色、蓝色和绿色&#xff09;与皮革、木材、黄麻和藤条等纹理相结合。就像真实的户外一样&#xff0c;它也懂得平衡的力量。户外&#xff1a; 每一片树丛&…

云备份——第三方库简单介绍并使用(上)

目录 一&#xff0c;Jsoncpp库序列化和反序列化 二&#xff0c;bundle文件压缩库 2.1 文件压缩 2.2 文件解压 一&#xff0c;Jsoncpp库序列化和反序列化 首先我们需要先了解一下json是什么&#xff0c;json是一种数据交换格式&#xff0c;采用完全独立于编程语言的文本格式来…

开学有哪些电容笔值得买?平价电容笔排行榜

苹果的原装Pencil&#xff0c;无疑是一款性能出色的电容笔&#xff0c;但它的价格也很高&#xff0c;如果不小心弄丢了或者弄坏了&#xff0c;那就太让人心痛。再说了&#xff0c;一支价值不菲的电容笔&#xff0c;要是不是用于专业绘画&#xff0c;实在是大材小用。不过&#…

01. 二进制原理

道家阴阳启发了莱布尼茨提出二进制&#xff01; 1. 为什么是二进制&#xff1f; 1.1 二进制与硬盘&#xff08;磁盘&#xff09; 硬盘也叫磁盘&#xff0c;它内部是排列整齐的一个个小磁体。 磁盘上面有“电刷”&#xff0c;磁盘可以转动&#xff0c;“电刷”也可以上下移动…

Python 带参数的装饰器

首先我们定义一个可以打印日志的装饰器&#xff1a; def log(func):def wrapper(*args, **kwargs):print(call %s(): % func.__name__)return func(*args, **kw)return wrapper它接受一个函数作为输入&#xff0c;再返回一个函数。我们使用一下这个装饰器 log def now():prin…

【esp32】解决以太网+mqtt堆栈溢出问题 报错 no mem for receive buffer

本文主要记录了 esp32 + 以太网 +mqtt 功能时遇到的堆栈溢出的情况,千里之堤毁于蚁穴,开发过程的不细心导致多付出了一天多的时间,记录于此,共勉 📋 个人简介 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。😎📝 个人主页:欢迎访问我的 Ethernet_Comm 博…

一文看懂DETR(二)

训练流程 1.输入图像经过CNN的backbone获得32倍下采样的深度特征&#xff1b; 2.将图片给拉直形成token&#xff0c;并添加位置编码送入encoder中&#xff1b; 3.将encoder的输出以及Object Query作为decoder的输入得到解码特征&#xff1b; 4.将解码后的特征传入FFN得到预测特…

Rethinking the Role of Demonstrations: What Makes In-Context LearningWork?

背景 这篇论文主要验证了prompt demos对模型的作用是什么&#xff0c;主要几个方面的影响&#xff1a; 1.prompt demo的input和label的映射关系对结果影响非常小&#xff0c;模型没有从mapping关系中学到太多信息。这是比较反直觉的 2.模型从input输入的数据空间和label输出的…

VR全景与家居行业碰撞在一起,会迸发怎样的火花?

元宇宙的热度一直在持续&#xff0c;由于前几年疫情反复&#xff0c;很多人只能居家办公&#xff0c;这也让很多线下实体行业非常难做&#xff0c;元宇宙的兴起可以带动线下行业把生意做起来&#xff0c;那么家居行业、元宇宙、VR全景这些元素碰撞在一起&#xff0c;会迸发出怎…

从Instagram到TikTok:利用社交媒体平台实现业务成功

自 2000年代初成立和随后兴起以来&#xff0c;社交媒体一直被大大小小的品牌用作高度针对性的营销工具&#xff0c;自 Facebook推出近二十年以来&#xff0c;这些网站继续彻底改变企业处理广告的方式。 在这篇博文中&#xff0c;我们将讨论订阅企业应该如何从整体上对待社交媒…

秋云qiun chart 使用echart配置格式化柱形图数据

dataLabel数据文字格式化 <!-- seriesTemplate是config-echarts.js中对应图表类型定义好的series模板 &#xff0c;如果每个series的formatter都不一样&#xff0c;则format需要定义在chartData.series中&#xff0c;不能使用seriesTemplate --> <!-- formatter…

Java 面试 - Redis

Redis Redis 是基于键值对的非关系型数据库。Redis 拥有string、hash、list、set、zset等多种数据结构, redis具有惊人的读写性能, 其优秀的持久化机制是的它在断电和机械故障时也不会发生数据丢失, 可以用于热点数据存放, 还提供了键过期、发布订阅、食物、流水线、LUA脚本等多…

在node项目中通过jsencrypt实现内容加密

上来肯定先引入第三方依赖 npm install jsencrypt然后 我们创建一个js文件 叫 rsaEncrypt.js 参考代码如下 import JSEncrypt from jsencrypt/bin/jsencrypt.min// 密钥对生成 http://web.chacuo.net/netrsakeypairconst publicKey MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k…

echarts的click事件

目录 前言 一、click事件 前言 在使用echarts的过程中&#xff0c;最常用的则是不同系列所对应的click返回参数的不同 一、click事件 在以下图中&#xff0c;其实是两个不同系列的数据&#xff0c;一个是图中的钟表&#xff0c;一个是下面的图 const option {grid: {left: …

Visual Studio软件_MSC_VER值(MSVC编译器版本)的获取方法

本文介绍查看Visual Studio软件_MSC_VER值的方法。 _MSC_VER是微软公司推出的C/C 编译器——MSVC编译器的一个内置宏&#xff0c;其值表示当前Visual Studio软件中MSVC编译器的具体版本。不同的Visual Studio软件版本对应着不同的MSVC编译器版本——无论是不同发布年份的版本&…

RT-Thread程序内存分布

一般MCU包含的存储空间有&#xff1a;片内Flash与片内RAM&#xff0c;RAM相当于内存&#xff0c;Flash相当于硬盘。 编译器会将一个程序分类分为好几个部分&#xff0c;分别存储在MCU不同的存储区。 Keil工程在编译完之后&#xff0c;会有相应的程序占用的空间提示信息。 lin…

螺旋矩阵、旋转矩阵、矩阵Z字打印

螺旋矩阵 #include <iostream> #include <vector> void display(std::vector<std::vector<int>>&nums){for(int i 0; i < nums.size(); i){for(int j 0; j < nums[0].size(); j){std::cout<<nums[i][j]<< ;}std::cout<<…