【得捷电子Follow me第4期】任务综合帖(从入门任务到终极任务)
[复制链接]
任务演示视频
第四期我购买了下面三个模块,分别是:
W5500-EVB-Pico,一片四色墨水屏(2.66" EPD, SPECTRA B/W/R/Y, W.IT),墨水屏驱动板(EXT3 - EPD EXTENSION BOARD).
-
W5500-EVB-Pico:这可能是一款基于W5500芯片的开发板。W5500是一款以太网控制器,通常用于嵌入式系统,以便这些系统能够连接到局域网或广域网。EVB(Evaluation Board)通常是评估板的意思,用于评估芯片的性能或功能。Pico可能指的是这款开发板的尺寸较小,适合用在空间有限的应用场景中。
-
四色墨水屏(2.66" EPD, SPECTRA B/W/R/Y, W.IT):
- 2.66" EPD:EPD(Electronic Paper Display)是电子纸显示器的缩写,是一种模仿纸张显示效果的技术。这种屏幕在显示内容时不消耗电力,只有在刷新内容时才需要电力。2.66"指的是这种屏幕的尺寸。
- SPECTRA B/W/R/Y:这可能指的是这款墨水屏能够显示黑白红黄四种颜色。传统的EPD通常是黑白的,但近年来,彩色EPD也开始出现,它们能够显示更多的颜色。
- W.IT:这可能是墨水屏制造商或品牌的标识,但具体含义需要查看相关的产品文档或资料。
-
墨水屏驱动板(EXT3 - EPD EXTENSION BOARD):这是一个用于驱动和控制墨水屏的电路板。它通常包含必要的电路和元件,以便与微处理器或微控制器通信,并控制墨水屏的显示内容。EXT3可能是这款驱动板的型号或标识。
下面是这三个实物图片,后面外加一个OLED(0.96寸)。
从上至下,第一个是墨水屏,中间的是墨水屏驱动板,第三个是W5500+RP2040主板。
下面开始了解模块与资料。
先从主板开始,功能引脚定义:
原理图:
下面正式开始任务:
入门任务:驱动墨水屏
思路:
- 硬件连接:
- 首先,墨水屏的驱动板(EXT3 - EPD EXTENSION BOARD)与RP2040之间的接口连接。SPI(Serial Peripheral Interface)接口用于数据传输,以及电源和地线连接。
- 电源线(如VCC, GND, VCOM等)都已正确连接,并根据墨水屏规格书的要求提供适当的电压。
- 软件开发:
- 编写用于RP2040的驱动程序。使用C语言,并可能使用MicroPython(嵌入式编程环境。
- 驱动程序实现与墨水屏通信的协议,通常是SPI协议。需要发送正确的命令和数据序列来初始化屏幕、设置显示模式、传输图像数据等。
使用的环境是Arduino,安装好相对应的驱动与库。
软件界面:
代码:
#include <Arduino.h>
#include "PDLS_EXT3_Basic_BWRY.h"
//#include "hV_HAL_Peripherals.h"
//#include "hV_Configuration.h"
Screen_EPD_EXT3 myScreen(eScreen_EPD_EXT3_266_BWRY, boardRaspberryPiPico_RP2040);
void displayPaletteBWRY()
{
uint16_t y = 20;
myScreen.setOrientation(ORIENTATION_LANDSCAPE);
myScreen.selectFont(Font_Terminal16x24);
myScreen.gText(30, y, "DJ Hell World!", myColours.yellow);
y += myScreen.characterSizeY()+20;
myScreen.selectFont(Font_Terminal12x16);
myScreen.gText(30, y, "EEWORLD Follow me 4.", myColours.red);
y += myScreen.characterSizeY()+12;
y += myScreen.characterSizeY();
myScreen.selectFont(Font_Terminal12x16);
myScreen.gText(30, y, "EEWORLD,DigiKey!");
y += myScreen.characterSizeY();
myScreen.flush();
}
void setup()
{
Serial.begin(115200);
delay(500);
pinMode(LED_BUILTIN, OUTPUT);
myScreen.begin();
Serial.println("DISPLAY_PALETTE_BWRY... ");
myScreen.clear();
displayPaletteBWRY();
}
void loop()
{
//digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
//delay(1000); // wait for a second
// digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
// delay(1000); // wait for a second
}
视频:
硬件连接介绍,与驱动显示FM4的介绍:
硬件连接:
f179052801721548125e22f663e30c14
驱动得捷FM4英文:
a3ea901faeca822d8947be94f894b0a5
下面是墨水屏整体视频:
得捷第四期Fm4驱动墨水屏
任务一:
以下是实现这一任务的基本步骤和考虑点:
1. W5500初始化与静态IP配置
首先,需要对W5500进行初始化,并为其配置一个静态IP地址。这通常涉及以下几个步骤:
- 上电复位:确保W5500在上电后处于已知状态。
- 设置Socket模式:配置W5500的工作模式,通常是TCP/IP模式。
- 配置静态IP:为W5500设置一个静态IP地址、子网掩码、默认网关和DNS服务器地址。
- 设置MAC地址:如果需要,也可以配置W5500的MAC地址。
配置通过串行通信提供的库函数来完成。
2. 实现局域网内电脑与W5500的相互ping通
一旦W5500配置完成,能够在局域网内的电脑上ping通W5500的IP地址,并且W5500也能响应ping请求。验证网络连接的基本功能。
3. W5500 ping通互联网站点
要测试W5500是否能够访问互联网,尝试让它ping一个公共的IP地址或域名。将验证W5500是否能够通过默认网关访问互联网。
遇到的超时问题点:
后面通过终于弄通了。
代码:
#include <SPI.h>
#include <Ethernet.h>
// 网卡mac地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3 };
// 静态ip地址、DNS服务、网关、子网掩码
// byte ip[] = { 192, 168, 1, 168 };
IPAddress ip(192, 168, 1, 168);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
void setup() {
// 配置串口
Serial.begin(115200);
while (!Serial) {
; // 等待串口连接
}
// 静态IP设置
Serial.println("Ethernet Begin");
Ethernet.init(17);
Ethernet.begin(mac, ip, myDns, gateway, subnet);
// 输出网卡mac地址、IP地址、子网掩码、DNS、网关
Serial.print("My Mac address: ");
byte macBuffer[6]; // 设置mac地址存储buff
Ethernet.MACAddress(macBuffer); // 读取mac地址
for (byte octet = 0; octet < 6; octet++) {
Serial.print(macBuffer[octet], HEX);
if (octet < 5) {
Serial.print('-');
}
}
Serial.println("");
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
Serial.print("My subnet: ");
Serial.println(Ethernet.subnetMask());
Serial.print("My DNS address: ");
Serial.println(Ethernet.dnsServerIP());
Serial.print("My GateWay address: ");
Serial.println(Ethernet.gatewayIP());
}
void loop() {
}
任务二:
先在百度中找步骤与参考方向如下:
- 在W5500上建立TCP服务器:
- 配置W5500的Socket以监听指定的端口(这里使用的是8888)。
- 设置Socket为TCP模式,并绑定到相应的IP地址和端口。
- 使Socket进入监听状态,等待客户端的连接请求。
- 编写TCP服务器处理程序:
- 当客户端连接时,接受连接请求。
- 读取客户端发送的数据。
- 发送“Hello, client!”字符串作为对客户端的响应。
- 将接收到的数据通过串口输出,并在OLED显示屏上显示。
- 编写TCP客户端应用程序:
- 在局域网内的PC上编写一个TCP客户端应用程序。
- 让客户端连接到W5500的IP地址和端口8888。
- 发送数据到服务器,并接收来自服务器的响应。
- 使用抓包软件分析交互报文:
- 配置抓包软件(如Wireshark)以捕获与W5500相关的网络流量。
- 运行TCP客户端应用程序并触发与服务器的交互。
- 在抓包软件中查看和分析TCP握手过程、数据传输以及服务器和客户端之间的通信报文。
输出结果:
代码:
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3};
IPAddress ip(192, 168, 1, 168);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(8888);
bool alreadyConnected = false; // whether or not the client was connected previously
void printConnectionInformation()
{
Serial.print("[INFO] IP Address: ");
Serial.println(Ethernet.localIP());
Serial.print("[INFO] Subnet Mask: ");
Serial.println(Ethernet.subnetMask());
Serial.print("[INFO] Gateway: ");
Serial.println(Ethernet.gatewayIP());
Serial.print("[INFO] DNS: ");
Serial.println(Ethernet.dnsServerIP());
}
void setup()
{
Serial.begin(115200);
delay(5000);
Serial.println("System is begin!");
Ethernet.init(17);
if (Ethernet.begin(mac) == 0) // 看看DHCP是否能动态分配ip给Arduino
{
Serial.println("connt get ip by dhcp!");
Ethernet.begin(mac, ip, myDns, gateway, subnet); // DHCP不能动态分配,就静态设置ip给Arduino
}
// Ethernet.init(17);
// Ethernet.begin(mac, ip, myDns, gateway, subnet);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware)
{
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true)
{
delay(1); // do nothing, no point running without Ethernet hardware
}
}
while (Ethernet.linkStatus() == LinkOFF)
{
Serial.println("Ethernet cable is not connected.");
delay(500);
}
// give the Ethernet shield a second to initialize:
// delay(1000);
printConnectionInformation();
server.begin();
}
void loop()
{
EthernetClient client = server.available();
// when the client sends the first byte, say hello:
if (client)
{
if (!alreadyConnected)
{
// clear out the input buffer:
client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
alreadyConnected = true;
}
if (client.available() > 0)
{
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
server.write(thisChar);
// echo the bytes to the server as well:
Serial.write(thisChar);
}
}
}
进阶任务:从NTP服务器(注意数据交互格式的解析)同步时间,获取时间送显示屏(串口)显示。
继续参考步骤:
要从NTP服务器同步时间并在显示屏上显示,你首先需要使用UDP协议与NTP服务器通信。NTP协议使用的是UDP端口123。NTP消息格式是复杂的,但幸运的是,我们只需要关注其中的时间戳字段来获取时间。
以下是一个简化的步骤,描述如何从一个NTP服务器同步时间,并将时间转换为本地时间(假设你所在的时区是UTC+8),然后通过串口发送到显示屏:
- 初始化UDP客户端:
- 设置UDP Socket。
- 配置W5500的IP地址和子网掩码。
- 设置目标NTP服务器的IP地址和端口号(time.nist.gov的IP地址和端口123)。
- 发送NTP请求:
- 创建一个NTP请求数据包,它通常是一个48字节的消息,前16个字节是NTP头,后面跟着32字节的填充。
- 发送这个请求到NTP服务器。
- 接收NTP响应:
- 等待并接收来自NTP服务器的响应。
- 解析响应数据包,获取时间戳字段。
- 转换时间:
- NTP时间戳是自1900年1月1日以来的秒数,我们需要将其转换为人类可读的格式(年、月、日、时、分、秒)。
- 考虑到NTP服务器返回的是UTC时间,我们需要将时间转换为本地时间(UTC+8)。
- 通过串口发送时间:
- 将转换后的本地时间格式化为字符串。
- 通过串口发送这个字符串到显示屏。
硬件连接:
开发平台是以 Visual Studio Code开发。
软件界面截图:
#include <SPI.h>
#include <Ethernet.h>
#include <U8x8lib.h>
#define U8LOG_WIDTH 16
#define U8LOG_HEIGHT 8
uint8_t u8log_buffer[U8LOG_WIDTH * U8LOG_HEIGHT];
U8X8LOG u8x8log;
U8X8_SSD1306_128X64_NONAME_4W_SW_SPI u8x8(10, 11, 40, 9, 8);
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
IPAddress staticIP(192, 168, 1, 18);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int localPort = 8888; // local port to listen for UDP packets
const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
EthernetUDP Udp;
void printConnectionInformation()
{
Serial.print("[INFO] IP Address: ");
Serial.println(Ethernet.localIP());
Serial.print("[INFO] Subnet Mask: ");
Serial.println(Ethernet.subnetMask());
Serial.print("[INFO] Gateway: ");
Serial.println(Ethernet.gatewayIP());
Serial.print("[INFO] DNS: ");
Serial.println(Ethernet.dnsServerIP());
u8x8log.print("ip=");
u8x8log.println(Ethernet.localIP());
u8x8log.print("Mask=");
u8x8log.println(Ethernet.subnetMask());
u8x8log.print("DNS=");
u8x8log.println(Ethernet.dnsServerIP());
}
void setup()
{
Serial.begin(115200);
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8log.begin(u8x8, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
u8x8log.setRedrawMode(1); // 0: Update screen with newline, 1: Update screen for every char
if (Ethernet.begin(mac) == 0) // 看看DHCP是否能动态分配ip给Arduino
{
Ethernet.begin(mac, staticIP, myDns, gateway, subnet); // DHCP不能动态分配,就静态设置ip给Arduino
}
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware)
{
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true)
{
delay(1); // do nothing, no point running without Ethernet hardware
}
}
while (Ethernet.linkStatus() == LinkOFF)
{
Serial.println("Ethernet cable is not connected.");
delay(500);
}
// give the Ethernet shield a second to initialize:
delay(1000);
printConnectionInformation();
Udp.begin(localPort);
}
// send an NTP request to the time server at the given address
void sendNTPpacket(const char *address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); // NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void loop()
{
int hour, min, sec;
char cur_time[9];
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if (Udp.parsePacket())
{
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = ");
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
hour = (epoch % 86400L) / 3600+8;
min = (epoch % 3600) / 60;
sec = epoch % 60;
sprintf(cur_time, "%02d:%02d:%02d", hour, min, sec);
Serial.println(cur_time);
u8x8log.print("Time=");
u8x8log.println(cur_time);
delay(10000);
Ethernet.maintain();
}
}
视频:
7bcfe85c6009bcad03cfd5765d8708d8
终级任务
二选一,本次是使用的是外部存储器,组建简易FTP文件服务器,并能正常上传下载文件,选择了任务2,建立ftp服务器。
开发平台是
-
MicroPython环境搭建:
- 在你的硬件平台上刷入MicroPython固件。
- 使用一个串口终端连接到你的硬件平台。
- 确认MicroPython环境正常工作。
使用THonny软件程序给开发上传程序软件:
代码:
import socket
import network
import uos
import gc
from time import localtime
from machine import Pin,SPI
import time
def w5x00_init():
#spi init
spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
nic = network.WIZNET5K(spi,Pin(17),Pin(20)) #spi,cs,reset pin
nic.active(True)#network active
nic.ifconfig(('192.168.1.10','255.255.255.0','192.168.1.1','8.8.8.8'))#Set static network address information
while not nic.isconnected():
time.sleep(1)
print(nic.regs())#Print register information
#Print network address information
print("IP Address:",nic.ifconfig()[0])
print("Subnet Mask:",nic.ifconfig()[1])
print("Gateway:",nic.ifconfig()[2])
print("DNS:",nic.ifconfig()[3])
return nic
month_name = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
def send_list_data(path, dataclient, full):
try: # whether path is a directory name
for fname in uos.listdir(path):
dataclient.sendall(make_description(path, fname, full))
except: # path may be a file name or pattern
pattern = path.split("/")[-1]
path = path[:-(len(pattern) + 1)]
if path == "": path = "/"
for fname in uos.listdir(path):
if fncmp(fname, pattern) == True:
dataclient.sendall(make_description(path, fname, full))
def make_description(path, fname, full):
if full:
stat = uos.stat(get_absolute_path(path,fname))
file_permissions = "drwxr-xr-x" if (stat[0] & 0o170000 == 0o040000) else "-rw-r--r--"
file_size = stat[6]
tm = localtime(stat[7])
if tm[0] != localtime()[0]:
description = "{} 1 owner group {:>10} {} {:2} {:>5} {}\r\n".format(
file_permissions, file_size, month_name[tm[1]], tm[2], tm[0], fname)
else:
description = "{} 1 owner group {:>10} {} {:2} {:02}:{:02} {}\r\n".format(
file_permissions, file_size, month_name[tm[1]], tm[2], tm[3], tm[4], fname)
else:
description = fname + "\r\n"
return description
def send_file_data(path, dataclient):
with open(path, "r") as file:
chunk = file.read(512)
while len(chunk) > 0:
dataclient.sendall(chunk)
chunk = file.read(512)
def save_file_data(path, dataclient, mode):
with open(path, mode) as file:
chunk = dataclient.read(512)
while len(chunk) > 0:
file.write(chunk)
chunk = dataclient.read(512)
def get_absolute_path(cwd, payload):
# Just a few special cases "..", "." and ""
# If payload start's with /, set cwd to /
# and consider the remainder a relative path
if payload.startswith('/'):
cwd = "/"
for token in payload.split("/"):
if token == '..':
if cwd != '/':
cwd = '/'.join(cwd.split('/')[:-1])
if cwd == '':
cwd = '/'
elif token != '.' and token != '':
if cwd == '/':
cwd += token
else:
cwd = cwd + '/' + token
return cwd
# compare fname against pattern. Pattern may contain
# wildcards ? and *.
def fncmp(fname, pattern):
pi = 0
si = 0
while pi < len(pattern) and si < len(fname):
if (fname[si] == pattern[pi]) or (pattern[pi] == '?'):
si += 1
pi += 1
else:
if pattern[pi] == '*': # recurse
if (pi + 1) == len(pattern):
return True
while si < len(fname):
if fncmp(fname[si:], pattern[pi+1:]) == True:
return True
else:
si += 1
return False
else:
return False
if pi == len(pattern.rstrip("*")) and si == len(fname):
return True
else:
return False
def ftpserver():
DATA_PORT = 13333
ftpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
datasocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ftpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
datasocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ftpsocket.bind(socket.getaddrinfo("0.0.0.0", 21)[0][4])
datasocket.bind(socket.getaddrinfo("0.0.0.0", DATA_PORT)[0][4])
ftpsocket.listen(1)
datasocket.listen(1)
datasocket.settimeout(10)
msg_250_OK = '250 OK\r\n'
msg_550_fail = '550 Failed\r\n'
try:
dataclient = None
fromname = None
while True:
cl, remote_addr = ftpsocket.accept()
cl.settimeout(300)
cwd = '/'
try:
# print("FTP connection from:", remote_addr)
cl.sendall("220 Hello, this is the ESP8266.\r\n")
while True:
gc.collect()
data = cl.readline().decode("utf-8").rstrip("\r\n")
if len(data) <= 0:
print("Client disappeared")
break
command = data.split(" ")[0].upper()
payload = data[len(command):].lstrip()
path = get_absolute_path(cwd, payload)
print("Command={}, Payload={}, Path={}".format(command, payload, path))
if command == "USER":
cl.sendall("230 Logged in.\r\n")
elif command == "SYST":
cl.sendall("215 UNIX Type: L8\r\n")
elif command == "NOOP":
cl.sendall("200 OK\r\n")
elif command == "FEAT":
cl.sendall("211 no-features\r\n")
elif command == "PWD":
cl.sendall('257 "{}"\r\n'.format(cwd))
elif command == "CWD":
try:
files = uos.listdir(path)
cwd = path
cl.sendall(msg_250_OK)
except:
cl.sendall(msg_550_fail)
elif command == "CDUP":
cwd = get_absolute_path(cwd, "..")
cl.sendall(msg_250_OK)
elif command == "TYPE":
# probably should switch between binary and not
cl.sendall('200 Transfer mode set\r\n')
elif command == "SIZE":
try:
size = uos.stat(path)[6]
cl.sendall('213 {}\r\n'.format(size))
except:
cl.sendall(msg_550_fail)
elif command == "QUIT":
cl.sendall('221 Bye.\r\n')
break
elif command == "PASV":
addr = nic.ifconfig()[0]
cl.sendall('227 Entering Passive Mode ({},{},{}).\r\n'.format(
addr.replace('.',','), DATA_PORT>>8, DATA_PORT%256))
dataclient, data_addr = datasocket.accept()
# print("FTP Data connection from:", data_addr)
elif command == "LIST" or command == "NLST":
if not payload.startswith("-"):
place = path
else:
place = cwd
try:
send_list_data(place, dataclient, command == "LIST" or payload == "-l")
cl.sendall("150 Here comes the directory listing.\r\n")
cl.sendall("226 Listed.\r\n")
except:
cl.sendall(msg_550_fail)
if dataclient is not None:
dataclient.close()
dataclient = None
elif command == "RETR":
try:
send_file_data(path, dataclient)
cl.sendall("150 Opening data connection.\r\n")
cl.sendall("226 Transfer complete.\r\n")
except:
cl.sendall(msg_550_fail)
if dataclient is not None:
dataclient.close()
dataclient = None
elif command == "STOR":
try:
cl.sendall("150 Ok to send data.\r\n")
save_file_data(path, dataclient, "w")
cl.sendall("226 Transfer complete.\r\n")
except:
cl.sendall(msg_550_fail)
if dataclient is not None:
dataclient.close()
dataclient = None
elif command == "APPE":
try:
cl.sendall("150 Ok to send data.\r\n")
save_file_data(path, dataclient, "a")
cl.sendall("226 Transfer complete.\r\n")
except:
cl.sendall(msg_550_fail)
if dataclient is not None:
dataclient.close()
dataclient = None
elif command == "DELE":
try:
uos.remove(path)
cl.sendall(msg_250_OK)
except:
cl.sendall(msg_550_fail)
elif command == "RMD":
try:
uos.rmdir(path)
cl.sendall(msg_250_OK)
except:
cl.sendall(msg_550_fail)
elif command == "MKD":
try:
uos.mkdir(path)
cl.sendall(msg_250_OK)
except:
cl.sendall(msg_550_fail)
elif command == "RNFR":
fromname = path
cl.sendall("350 Rename from\r\n")
elif command == "RNTO":
if fromname is not None:
try:
uos.rename(fromname, path)
cl.sendall(msg_250_OK)
except:
cl.sendall(msg_550_fail)
else:
cl.sendall(msg_550_fail)
fromname = None
else:
cl.sendall("502 Unsupported command.\r\n")
# print("Unsupported command {} with payload {}".format(command, payload))
except Exception as err:
print(err)
finally:
cl.close()
cl = None
finally:
datasocket.close()
ftpsocket.close()
if dataclient is not None:
dataclient.close()
nic = w5x00_init()
ftpserver() #直接跑这个就成功建立服务器了
遇到问题点:
首先是缺少库文件:
第二是没有办法使用FTP+IP访问:
使用总结:
使用PICO W5500模块与得捷第四期平台结合,体验深刻。PICO W5500作为一款以太网控制器,其高度集成和易用性给项目带来了极大的便利。在得捷第四期的应用中,W5500的稳定性和性能表现优秀,使得网络通信更加可靠。
在使用过程中,我感受到了PICO W5500的易用性。虽然我在这个过程中遇到了很多的问题,但是在通过学习和请教朋友,最终完成这个FM4,后面我会继续研究这个板块,加深。
总的来说,PICO W5500是一款性能优异、易于使用的以太网控制器,与得捷第四期平台的结合为我们的项目带来了显著的便利和优势。
附件:
缺少SOCKET包文件:
静太IP:
墨水屏:
终极任务二:
|