本帖最后由 流行科技 于 2024-2-27 11:36 编辑
基础任务一:完成主控板W5500初始化
初始化其本身是有例程的主要还是库的选择,我们在Arduino下选择库还需要注意。
最开始可能是这样的Ping库,这个还需要自己去修改了,很麻烦。
有老哥提供了一个可以ping的库,地址是:
https://github.com/masterx1981/Ethernet/tree/master/
如果看官方的里面,目前更新到了2.02版本。里面是没有这个库的。
有人提交了问题,但是目前好像没有回应。测试时候可以参考ICMP_PING这个库给的案例。
- #include <SPI.h>
-
- #include <Dns.h>
-
- #include <Ethernet.h>
-
- #include <EthernetICMP.h>
-
-
-
- byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
-
- IPAddress ip(192,168,1,155);
-
- IPAddress pingAddr(192,168,1,3);
-
-
-
- DNSClient dnClient;
-
- SOCKET pingSocket = 0;
-
- EthernetICMPPing ping(pingSocket, (uint16_t)random(0, 255));
-
-
-
- void ping_ip(const IPAddress &pingAddr1)
-
- {
-
- EthernetICMPEchoReply echoReply = ping(pingAddr1, 4);
-
- char buffer [256];
-
- if (echoReply.status == SUCCESS)
-
- {
-
- sprintf(buffer,
-
- "Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d",
-
- echoReply.data.seq,
-
- echoReply.addr[0],
-
- echoReply.addr[1],
-
- echoReply.addr[2],
-
- echoReply.addr[3],
-
- REQ_DATASIZE,
-
- millis() - echoReply.data.time,
-
- echoReply.ttl);
-
- }
-
- else
-
- {
-
- sprintf(buffer, "Echo request failed; %d", echoReply.status);
-
- }
-
- Serial.println(buffer);
-
- delay(500);
-
- }
-
-
-
- void ping_site() {
-
- dnClient.begin(Ethernet.dnsServerIP());
-
- const char domains[20] = { "www.baidu.com"};
-
- IPAddress dstip;
-
-
-
- if (dnClient.getHostByName(domains, dstip) == 1) {
-
- Serial.print(domains);
-
- Serial.print(" = ");
-
- Serial.println(dstip);
-
- ping_ip(dstip);
-
- } else{
-
- Serial.println(F("dns lookup failed"));
-
- }
-
-
-
- }
-
-
-
- void setup()
-
- {
-
- Serial.begin(9600);
-
- while (!Serial)
-
- ;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ethernet.init(17);
-
-
-
-
-
- Ethernet.begin(mac, ip);
-
-
-
-
-
-
-
- }
-
-
-
- void loop()
-
- {
-
-
-
- ping_ip(pingAddr);
-
- }
Ping网站的时候还是获取到网站的IP地址,然后进行PING的。
用wireshark看ping自己主机,就是这样的。
基础任务二:主控板建立TCPIP或UDP服务器
这部分我们先看UDP协议,UDP他也是有例子的,我们可以查看下。
-
- #include <Ethernet.h>
-
- #include <EthernetUdp.h>
-
-
-
-
-
-
-
- byte mac[] = {
-
- 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
-
- };
-
- IPAddress ip(192, 168, 2, 177);
-
-
-
- unsigned int localPort = 8888;
-
-
-
-
-
- char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
-
- char ReplyBuffer[] = "acknowledged";
-
-
-
-
-
- EthernetUDP Udp;
-
-
-
- void setup() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ethernet.init(17);
-
-
-
-
-
- Ethernet.begin(mac, ip);
-
-
-
-
-
- Serial.begin(9600);
-
- while (!Serial) {
-
- ;
-
- }
-
-
-
-
-
- if (Ethernet.hardwareStatus() == EthernetNoHardware) {
-
- Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
-
- while (true) {
-
- delay(1);
-
- }
-
- }
-
- if (Ethernet.linkStatus() == LinkOFF) {
-
- Serial.println("Ethernet cable is not connected.");
-
- }
-
-
-
-
-
- Udp.begin(localPort);
-
- }
-
-
-
- void loop() {
-
-
-
- int packetSize = Udp.parsePacket();
-
- if (packetSize) {
-
- Serial.print("Received packet of size ");
-
- Serial.println(packetSize);
-
- Serial.print("From ");
-
- IPAddress remote = Udp.remoteIP();
-
- for (int i=0; i < 4; i++) {
-
- Serial.print(remote[i], DEC);
-
- if (i < 3) {
-
- Serial.print(".");
-
- }
-
- }
-
- Serial.print(", port ");
-
- Serial.println(Udp.remotePort());
-
-
-
-
-
- Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
-
- Serial.println("Contents:");
-
- Serial.println(packetBuffer);
-
-
-
-
-
- Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
-
- Udp.write(ReplyBuffer);
-
- Udp.endPacket();
-
- }
-
- delay(10);
-
- }
这部分还比较好理解,主要就是创建一个UDP服务,端口是8888,通过电脑软件也建一个UDP服务连接他。
连接目标机器的IP地址和端口。
连接上之后会有反馈。接收信息也会打印的。
网络分析就是看数据段,数据是吻合的。
进阶任务:从NTP服务器同步时间
本身我们的arduino上面就有NTP服务器获取时间的例程,所以我在基础上稍微修改了下,显示了日期和时间。
-
-
-
-
- #include <SPI.h>
-
- #include <Ethernet.h>
-
- #include <EthernetUdp.h>
-
-
-
-
-
-
-
- byte mac[] = {
-
- 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
-
- };
-
-
-
- unsigned int localPort = 8888;
-
-
-
- const char timeServer[] = "ntp1.aliyun.com";
-
-
-
- const int NTP_PACKET_SIZE = 48;
-
-
-
- byte packetBuffer[NTP_PACKET_SIZE];
-
-
-
-
-
- EthernetUDP Udp;
-
-
-
- void setup() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ethernet.init(17);
-
-
-
-
-
- Serial.begin(9600);
-
- while (!Serial) {
-
- ;
-
- }
-
-
-
-
-
- if (Ethernet.begin(mac) == 0) {
-
- Serial.println("Failed to configure Ethernet using DHCP");
-
-
-
- if (Ethernet.hardwareStatus() == EthernetNoHardware) {
-
- Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
-
- } else if (Ethernet.linkStatus() == LinkOFF) {
-
- Serial.println("Ethernet cable is not connected.");
-
- }
-
-
-
- while (true) {
-
- delay(1);
-
- }
-
- }
-
- Udp.begin(localPort);
-
- }
-
-
-
- void loop() {
-
- sendNTPpacket(timeServer);
-
-
-
-
-
- delay(1000);
-
- if (Udp.parsePacket()) {
-
-
-
- Udp.read(packetBuffer, NTP_PACKET_SIZE);
-
-
-
-
-
-
-
-
-
- unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
-
- unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
-
-
-
-
-
- unsigned long secsSince1900 = highWord << 16 | lowWord;
-
-
-
- unsigned long n=0,d=0,total_d=0,rz=0;
-
- uint32_t p_year_total_sec;
-
- uint32_t r_year_total_sec;
-
- uint16_t y=0,r=0,yr=0;
-
- uint8_t yf=0;
-
- signed long long yd=0;
-
-
-
- Serial.print("Seconds since Jan 1 1900 = ");
-
- Serial.println(secsSince1900);
-
-
-
-
-
- Serial.print("Unix time = ");
-
-
-
- const unsigned long seventyYears = 2208988800UL;
-
-
-
- unsigned long epoch = secsSince1900 - seventyYears;
-
-
-
- Serial.println(epoch);
-
-
-
-
-
- Serial.print("The UTC time is ");
-
-
-
- n = epoch;
-
- total_d = epoch/(86400);
-
- d=0;
-
- p_year_total_sec=86400*365;
-
- r_year_total_sec=86400*366;
-
- while(n>=p_year_total_sec)
-
- {
-
- if((1970+r)%400==0 || ((1970+r)%100!=0 && (1970+r)%4==0))
-
- {
-
- n = n -(r_year_total_sec);
-
- d = d + 366;
-
- }
-
- else
-
- {
-
- n = n - (p_year_total_sec);
-
- d = d + 365;
-
- }
-
- r+=1;
-
- y+=1;
-
-
-
- }
-
-
-
- y += 1970;
-
-
-
- Serial.print(y);
-
- Serial.print('/');
-
-
-
- yd=0;
-
- yd = total_d - d;
-
-
-
- yf=1;
-
- while(yd>=28)
-
- {
-
-
-
- if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12)
-
- {
-
- yd -= 31;
-
- if(yd<0)break;
-
- rz += 31;
-
- }
-
-
-
- if (yf==2)
-
- {
-
- if (y%400==0 || (y%100!=0 && y%4==0))
-
- {
-
- yd -= 29;
-
- if(yd<0)break;
-
- rz += 29;
-
- }
-
- else
-
- {
-
- yd -= 28;
-
- if(yd<0)break;
-
- rz += 28;
-
- }
-
- }
-
- if(yf==4 || yf==6 || yf==9 || yf==11 )
-
- {
-
- yd -= 30;
-
- if(yd<0)break;
-
- rz += 30;
-
- }
-
- yf += 1;
-
-
-
- }
-
-
-
- Serial.print(yf);
-
- Serial.print('/');
-
-
-
- yr = total_d-d-rz;
-
-
-
- yr += 1;
-
-
-
-
-
- Serial.print(yr);
-
- Serial.print(' ');
-
-
-
- Serial.print((epoch % 86400L) / 3600+8);
-
- Serial.print(':');
-
- if (((epoch % 3600) / 60) < 10) {
-
-
-
- Serial.print('0');
-
- }
-
- Serial.print((epoch % 3600) / 60);
-
- Serial.print(':');
-
- if ((epoch % 60) < 10) {
-
-
-
- Serial.print('0');
-
- }
-
- Serial.println(epoch % 60);
-
- }
-
-
-
- delay(1000);
-
- Ethernet.maintain();
-
- }
-
-
-
-
-
- void sendNTPpacket(const char * address) {
-
-
-
- memset(packetBuffer, 0, NTP_PACKET_SIZE);
-
-
-
-
-
- packetBuffer[0] = 0b11100011;
-
- packetBuffer[1] = 0;
-
- packetBuffer[2] = 6;
-
- packetBuffer[3] = 0xEC;
-
-
-
- packetBuffer[12] = 49;
-
- packetBuffer[13] = 0x4E;
-
- packetBuffer[14] = 49;
-
- packetBuffer[15] = 52;
-
-
-
-
-
-
-
- Udp.beginPacket(address, 123);
-
- Udp.write(packetBuffer, NTP_PACKET_SIZE);
-
- Udp.endPacket();
-
- }
最常用的国内NTP服务器
http://ntp1.aliyun.com
http://ntp.tencent.com
http://edu.ntp.org.cn
不修改服务器也是可以的。
其可以直接获取到时间
https://www.beijing-time.org/shijianchuo/
可以通过上面的时间戳通过网站验证我们转换是否正确。
北京时间加8小时既可。
终极任务二:使用外部存储器,组建简易FTP文件服务器
最后一个任务我们用国内的Wiznet供应商提供的代码,完成FTP服务器搭建。
在VScode下构建好这个FTP Server案例。
构建完成后我们只需要把这个uf2文件拖到板子上。
启动fileZilla软件创建FTP连接。
连接成功后可以看到正常列出了文件,同时可以上传和下载里面的文件。
串口也是有打印信息的。
|