第 13 篇:W55RP20-EVB-Pico MicroPython 实战:MQTT 协议与阿里云 IoT 平台对接
本文为 W55RP20-EVB-Pico 模块 MicroPython 教程专项篇基于官方最新固件编写代码均经过实际验证可直接烧录运行。 版权声明本文为 WIZnet 官方原创技术文章转载请注明出处。前言上一篇教程中我们已经了解并完成了MQTT与MQTTX平台的开发实现了域名到公网 IP 的快速转换为设备访问云端服务器打下了网络基础。而在物联网设备云端接入、数据远程上报、平台集中管控的场景中MQTT 协议凭借轻量、稳定、低功耗的特性成为工业级物联网接入的标准方案。本文将带你快速上手 W55RP20-EVB-Pico 模块的 MicroPython 开发重点实现MQTT 协议与阿里云平台对接功能学完本文你将掌握MQTT 协议核心原理与发布 / 订阅工作机制阿里云 IoT 平台创建产品与设备全流程MQTT 接入域名、ClientID、用户名、密码生成规则W55RP20-EVB-Pico 以太网 MQTT 云端上报开发标准物模型 JSON 格式数据上报定时上报 云端实时监控联调测试MQTT 云端连接异常与故障一站式排查WIZnet 硬件协议栈在物联网上云场景的核心优势系列教程学习路径本专栏共 16 篇循序渐进覆盖 W55RP20-EVB-Pico 模块 MicroPython 开发全流程第 1 篇静态 IP 配置与网络基础第 2 篇DHCP 自动联网与网络诊断第 3 篇TCP Client 客户端通信第 4 篇TCP Server 服务端通信第 5 篇UDP 单播数据通信第 6 篇UDP 组播/广播数据通信第 7 篇DNS 域名解析第 8 篇NTP 从网络获取时间第 9 篇HTTP Client 客户端请求第 10 篇HTTP Server 服务端搭建第 11 篇HTTP 协议与 OneNET 平台数据上云第 12 篇MQTT 协议基础通信验证第 13 篇MQTT 协议与阿里云平台对接本文第 14 篇MQTT 协议与 OneNET 平台对接第 15 篇MQTT 协议与 ThingSpeak 平台对接第 16 篇Modbus 工业协议通信建议收藏本专栏跟随教程逐步学习所有代码均会同步更新至官方 Gitee 仓库目录1. 准备工作1.1 软件准备1.2 硬件准备2. 烧录 W55RP20-EVB-Pico 模块专属 MicroPython 固件3. 硬件连接与开发环境配置3.1 硬件连接3.1.1 基础连接供电调试3.1.2 以太网连接3.1.3 模块与开发板接线3.2 Thonny 开发环境配置4. MQTT 阿里云 IoT 核心原理4.1 MQTT 协议简介4.2 阿里云 IoT 接入流程4.3 核心优势5. 阿里云 IoT 平台配置流程6. 核心代码解析6.1 完整可运行代码6.2 代码关键步骤说明7. 运行结果与测试验证7.1 串口输出结果7.2 阿里云平台验证8. 常见问题一站式排查指南8.1 网络连接问题8.2 MQTT 连接失败8.3 上报失败9.W55RP20 核心优势对比10. 典型应用场景11. 系列预告与资源获取11.1 系列预告11.2 资源获取1. 准备工作1.1 软件准备所需软件均为免费版本按要求下载安装即可无需额外付费。软件名称版本要求下载地址说明Thonny4.0 及以上Thonny 官方下载轻量级 MicroPython IDE支持代码编辑、烧录与串口调试新手友好W55RP20-EVB-Pico 模块 MiscoPython驱动库最新稳定版WIZnet 官方固件/驱动库下载专为 W55RP20-EVB-Pico 模块编写已集成 WIZnet 硬件驱动、TCP/IP协议栈及MQTT客户端库串口调试助手如SecureCRT任意版本官方下载或第三方工具用于查看串口输出的运行日志、调试信息定位连接和数据上传问题阿里云IoT平台在线版阿里云IoT平台官网创建产品、注册设备获取MQTT连接参数查看上传的温湿度数据1.2 硬件准备W55RP20-EVB-Pico × 1Micro USB 数据线必须支持数据传输不能使用纯充电线× 1标准网线 × 1开启 DHCP 功能的路由器 / 交换机 × 1用于获取网络参数实现 DNS 解析W55RP20-EVB-Pico 模块已集成以太网相关器件无需额外焊接飞线配合 RP2040 开发板可快速搭建开发环境大幅降低接线错误和硬件故障概率。2. 烧录 W55RP20-EVB-Pico 模块专属 MicroPython 固件W55RP20-EVB-Pico 模块 完全兼容树莓派 Pico 的 UF2 固件烧录方式操作简单无需额外烧录器新手可快速上手按住 RP2040 开发板上的 BOOTSEL 按键不放使用 Micro USB 数据线连接开发板与电脑待电脑识别出名为 RPI-RP2 的 U 盘后松开 BOOTSEL 按键将下载好的 W5500_RP2040_firmware.uf2 固件文件拖拽到 U 盘中开发板会自动重启固件烧录完成。注意如果电脑没有识别出 RPI-RP2 U 盘请尝试更换 USB 数据线、重新插拔开发板或更换电脑 USB 接口优先使用 USB 2.0 接口。3. 硬件连接与开发环境配置3.1 硬件连接W55RP20-EVB-Pico 模块连接分为两步分别实现供电/调试和以太网连接操作简单无需复杂接线3.1.1 基础连接供电调试使用 Micro USB 数据线连接 RP2040 开发板与电脑用于开发板供电、代码烧录和串口调试。3.1.2 以太网连接使用网线连接 W55RP20-EVB-Pico 模块的以太网接口与路由器的 LAN 口或直接连接电脑网口需手动配置电脑 IP 与开发板同网段。3.1.3 模块与开发板接线若使用分离式模块与开发板需按以下引脚对应连接SPI 通信【硬件预留】此处插入硬件连接示意图3.2 Thonny 开发环境配置打开 Thonny 软件按以下步骤配置开发环境确保代码能正常烧录和运行点击顶部菜单栏「运行」→「配置解释器」切换到「解释器」选项卡在「解释器」下拉列表中选择 MicroPython (通用)在「端口」下拉列表中选择开发板对应的串口通常显示为 Board CDC COMx勾选「运行代码前先重启解释器」和「同步设备的实时时钟」点击「确定」完成配置。如果端口列表中没有出现开发板请尝试重新插拔 USB 数据线更换支持数据传输的 USB 数据线关闭其他占用串口的软件如串口助手、Arduino IDE 等重新烧录 MicroPython 固件安装树莓派 Pico USB 驱动。4. MQTT 阿里云 IoT 核心原理4.1 MQTT 协议简介MQTTMessage Queuing Telemetry Transport是基于发布 / 订阅模式的轻量级物联网通信协议基于 TCP 协议传输具备报文短小、带宽占用低、功耗小、稳定性强的特点是全球主流的物联网设备上云标准协议。4.2 阿里云 IoT 接入流程阿里云平台创建产品 → 定义物模型温度、湿度生成 MQTT 接入参数服务地址、ClientID、用户名、密码设备通过 W55RP20 联网 → 建立 MQTT 连接设备按照标准 JSON 格式上报属性数据阿里云平台接收数据 → 实时展示与存储。4.3 核心优势长连接保活网络波动自动重连发布 / 订阅模式支持多设备、多平台联动阿里云 IoT 提供设备管理、数据监控、告警、远程控制硬件协议栈独立处理网络MCU 零占用。5. 阿里云 IoT 平台配置流程登录阿里云 IoT 平台开通公共实例创建产品选择直连设备 → MQTT定义物模型CurrentTemperature温度CurrentHumidity湿度添加设备获取ProductKey、DeviceName、DeviceSecret使用阿里云官方工具生成 MQTT 连接参数记录接入域名、ClientID、用户名、密码、上报 Topic。6. 核心代码解析W55RP20-EVB-Pico 模块的 MicroPython 库已完整封装底层网络与 MQTT 功能对接阿里云仅需简单配置即可运行。6.1 完整可运行代码# main.py # W55RP20 阿里云 IoT —— 最终可用版 # import time import json import machine from machine import Timer from wiznet_init import wiznet from umqttsimple import MQTTClient # # 阿里云设备参数替换为你自己的 # MQTT_SERVER a1aOWUYIkcI.iot-as-mqtt.cn-shanghai.aliyuncs.com MQTT_PORT 1883 CLIENT_ID a1aOWUYIkcI.w55rp20_001|securemode2,signmethodhmacsha256,timestamp1777440363135| USERNAME w55rp20_001a1aOWUYIkcI PASSWORD 7258e816cdff5b27a6048cd90508e2686d7290b9d4083a91a56fc1e903a75523 PUB_TOPIC /sys/a1aOWUYIkcI/w55rp20_001/thing/event/property/post # 固定上报数据 FIX_TEMP float(25.0) FIX_HUMI float(50.0) client None tim Timer() # # 定时上报数据 # def send_data(timer): payload { id: 123, params: { CurrentTemperature: FIX_TEMP, CurrentHumidity: FIX_HUMI }, method: thing.event.property.post } try: payload_str json.dumps(payload) print(【调试】发送JSON:, payload_str) client.publish(PUB_TOPIC, payload_str) print(f✅ 上报成功: 温度{FIX_TEMP}°C, 湿度{FIX_HUMI}%) except Exception as e: print(❌ 上报失败:, e) def main(): global client print( W55RP20 阿里云 IoT 云端上报 ) # 以太网初始化带重试机制 print(【调试】以太网初始化中...) retry_count 0 while retry_count 5: try: nic wiznet(w55rp20-evb-pico, dhcpTrue) wait_count 0 while not nic.isconnected() and wait_count 20: print(f网络连接中... ({wait_count}/20)) time.sleep(0.5) wait_count 1 if nic.isconnected(): print(✅ 网络连接成功IP:, nic.ifconfig()[0]) break else: print(❌ 网络超时重试...) except Exception as e: print(f❌ 以太网异常: {e}重试...) retry_count 1 time.sleep(1) else: print(❌ 网络初始化失败设备重启...) machine.reset() # 连接阿里云 MQTT print(【调试】连接阿里云 MQTT...) try: client MQTTClient( client_idCLIENT_ID, serverMQTT_SERVER, portMQTT_PORT, userUSERNAME, passwordPASSWORD, keepalive60 ) client.connect() print(✅ 阿里云 MQTT 连接成功) except Exception as e: print(❌ MQTT 连接失败:, e) machine.reset() # 定时上报5 秒一次 print(【调试】启动 5 秒定时上报) tim.init(period5000, modeTimer.PERIODIC, callbacksend_data) # 主循环心跳保活 while True: client.check_msg() time.sleep(0.1) if __name__ __main__: main()#umqttsimple.py file import usocket as socket import ustruct as struct from ubinascii import hexlify class MQTTException(Exception): pass class MQTTClient: def __init__( self, client_id, server, port0, userNone, passwordNone, keepalive0, sslFalse, ssl_params{}, ): if port 0: port 8883 if ssl else 1883 self.client_id client_id self.sock None self.server server self.port port self.ssl ssl self.ssl_params ssl_params self.pid 0 self.cb None self.user user self.pswd password self.keepalive keepalive self.lw_topic None self.lw_msg None self.lw_qos 0 self.lw_retain False def _send_str(self, s): self.sock.write(struct.pack(!H, len(s))) self.sock.write(s) def _recv_len(self): n 0 sh 0 while 1: b self.sock.read(1)[0] n | (b 0x7F) sh if not b 0x80: return n sh 7 def set_callback(self, f): self.cb f def set_last_will(self, topic, msg, retainFalse, qos0): assert 0 qos 2 assert topic self.lw_topic topic self.lw_msg msg self.lw_qos qos self.lw_retain retain def connect(self, clean_sessionTrue): self.sock socket.socket() addr socket.getaddrinfo(self.server, self.port)[0][-1] self.sock.connect(addr) if self.ssl: import ussl self.sock ussl.wrap_socket(self.sock, **self.ssl_params) premsg bytearray(b\x10\0\0\0\0\0) msg bytearray(b\x04MQTT\x04\x02\0\0) sz 10 2 len(self.client_id) msg[6] clean_session 1 if self.user is not None: sz 2 len(self.user) 2 len(self.pswd) msg[6] | 0xC0 if self.keepalive: assert self.keepalive 65536 msg[7] | self.keepalive 8 msg[8] | self.keepalive 0x00FF if self.lw_topic: sz 2 len(self.lw_topic) 2 len(self.lw_msg) msg[6] | 0x4 | (self.lw_qos 0x1) 3 | (self.lw_qos 0x2) 3 msg[6] | self.lw_retain 5 i 1 while sz 0x7F: premsg[i] (sz 0x7F) | 0x80 sz 7 i 1 premsg[i] sz self.sock.write(premsg, i 2) self.sock.write(msg) # print(hex(len(msg)), hexlify(msg, :)) self._send_str(self.client_id) if self.lw_topic: self._send_str(self.lw_topic) self._send_str(self.lw_msg) if self.user is not None: self._send_str(self.user) self._send_str(self.pswd) resp self.sock.read(4) assert resp[0] 0x20 and resp[1] 0x02 if resp[3] ! 0: raise MQTTException(resp[3]) return resp[2] 1 def disconnect(self): self.sock.write(b\xe0\0) self.sock.close() def ping(self): self.sock.write(b\xc0\0) def publish(self, topic, msg, retainFalse, qos0): pkt bytearray(b\x30\0\0\0) pkt[0] | qos 1 | retain sz 2 len(topic) len(msg) if qos 0: sz 2 assert sz 2097152 i 1 while sz 0x7F: pkt[i] (sz 0x7F) | 0x80 sz 7 i 1 pkt[i] sz # print(hex(len(pkt)), hexlify(pkt, :)) self.sock.write(pkt, i 1) self._send_str(topic) if qos 0: self.pid 1 pid self.pid struct.pack_into(!H, pkt, 0, pid) self.sock.write(pkt, 2) self.sock.write(msg) if qos 1: while 1: op self.wait_msg() if op 0x40: sz self.sock.read(1) assert sz b\x02 rcv_pid self.sock.read(2) rcv_pid rcv_pid[0] 8 | rcv_pid[1] if pid rcv_pid: return elif qos 2: assert 0 def subscribe(self, topic, qos0): assert self.cb is not None, Subscribe callback is not set pkt bytearray(b\x82\0\0\0) self.pid 1 struct.pack_into(!BH, pkt, 1, 2 2 len(topic) 1, self.pid) # print(hex(len(pkt)), hexlify(pkt, :)) self.sock.write(pkt) self._send_str(topic) self.sock.write(qos.to_bytes(1, little)) while 1: op self.wait_msg() if op 0x90: resp self.sock.read(4) # print(resp) assert resp[1] pkt[2] and resp[2] pkt[3] if resp[3] 0x80: raise MQTTException(resp[3]) return # Wait for a single incoming MQTT message and process it. # Subscribed messages are delivered to a callback previously # set by .set_callback() method. Other (internal) MQTT # messages processed internally. def wait_msg(self): res self.sock.read(1) # self.sock.setblocking(True) if res is None: return None if res b: raise OSError(-1) if res b\xd0: # PINGRESP sz self.sock.read(1)[0] assert sz 0 return None op res[0] if op 0xF0 ! 0x30: return op sz self._recv_len() topic_len self.sock.read(2) topic_len (topic_len[0] 8) | topic_len[1] topic self.sock.read(topic_len) sz - topic_len 2 if op 6: pid self.sock.read(2) pid pid[0] 8 | pid[1] sz - 2 msg self.sock.read(sz) self.cb(topic, msg) if op 6 2: pkt bytearray(b\x40\x02\0\0) struct.pack_into(!H, pkt, 2, pid) self.sock.write(pkt) elif op 6 4: assert 0 return op # Checks whether a pending message from server is available. # If not, returns immediately with None. Otherwise, does # the same processing as wait_msg. def check_msg(self): self.sock.setblocking(False) return self.wait_msg()#wiznet_init.py import network import time try: from machine import Pin, WIZNET_PIO_SPI except ImportError: WIZNET_PIO_SPI None Pin None _DEFAULTS { # Auto-construct boards (no explicit PIO SPI) w5100s-evb-pico: {}, w5500-evb-pico: {}, w6100-evb-pico: {}, w5100s-evb-pico2: {}, w5500-evb-pico2: {}, w6100-evb-pico2: {}, # W55RP20 — single SPI (PIO SPI) w55rp20-evb-pico: {baudrate: 31250000, sck: 21, cs: 20, mosi: 23, miso: 22, reset: 25}, # W6300 — QSPI QUAD(io0..io3) w6300-evb-pico: {baudrate: 31250000, sck: 17, cs: 16, io0: 18, io1: 19, io2: 20, io3: 21, reset: 22}, w6300-evb-pico2: {baudrate: 31250000, sck: 17, cs: 16, io0: 18, io1: 19, io2: 20, io3: 21, reset: 22}, } _AUTO { w5100s-evb-pico, w5500-evb-pico, w6100-evb-pico, w5100s-evb-pico2,w5500-evb-pico2,w6100-evb-pico2, } _SINGLE {w55rp20-evb-pico} # PIO single-SPI _QSPI {w6300-evb-pico, w6300-evb-pico2} def _pin(x): return x if isinstance(x, Pin) else Pin(x) def wiznet(board, *, dhcpTrue, spiNone, csNone, resetNone, **kw): board board.strip().lower() if board not in _DEFAULTS: raise ValueError(Unsupported board: {}.format(board)) cfg _DEFAULTS[board].copy() cfg.update(kw) # Manual override path: if spi is provided, use it directly if spi is not None: if cs is None or reset is None: raise ValueError(When passing custom spi, also pass cs and reset) nic network.WIZNET6K(spi, cs, reset) else: if board in _AUTO: nic network.WIZNET6K() elif board in _SINGLE: if WIZNET_PIO_SPI is None or Pin is None: raise RuntimeError(WIZNET_PIO_SPI/Pin not available on this port) required [sck, cs, mosi, miso, reset] missing [k for k in required if k not in cfg] if missing: raise ValueError(Missing pins for W55RP20 single-SPI: , .join(missing)) spi WIZNET_PIO_SPI( baudratecfg.get(baudrate, 31250000), sck_pin(cfg[sck]), cs_pin(cfg[cs]), mosi_pin(cfg[mosi]), miso_pin(cfg[miso]), ) nic network.WIZNET6K(spi, _pin(cfg[cs]), _pin(cfg[reset])) elif board in _QSPI: if WIZNET_PIO_SPI is None or Pin is None: raise RuntimeError(WIZNET_PIO_SPI/Pin not available on this port) for k in [sck,cs,io0,io1,io2,io3]: if k not in cfg: raise ValueError(Missing pin {} for W6300 QSPI.format(k)) spi WIZNET_PIO_SPI( baudratecfg.get(baudrate, 31250000), sck_pin(cfg[sck]), cs_pin(cfg[cs]), io0_pin(cfg[io0]), io1_pin(cfg[io1]), io2_pin(cfg[io2]), io3_pin(cfg[io3]), ) nic network.WIZNET6K(spi, _pin(cfg[cs]), _pin(cfg.get(reset, cfg[cs]))) else: raise ValueError(Unexpected board mapping) # Bring up (if supported) try: nic.active(True) except AttributeError: pass if dhcp: try: nic.ifconfig(dhcp) except Exception: pass else: ip cfg.get(ip); sn cfg.get(sn); gw cfg.get(gw); dns cfg.get(dns, gw or 8.8.8.8) if not (ip and sn and gw): raise ValueError(Static mode requires ip/sn/gw) nic.ifconfig((ip, sn, gw, dns)) while not nic.isconnected(): print(Waiting for the network to connect...) time.sleep(1) print(MAC Address:, :.join(%02x % b for b in nic.config(mac))) print(IP Address:, nic.ifconfig()) return nic6.2 代码关键步骤说明以太网初始化带自动重试 超时保护确保网络稳定MQTT 连接使用阿里云标准接入格式支持 HMACSHA256 加密JSON 物模型上报严格匹配阿里云格式平台可直接解析定时上报硬件定时器 5 秒上报一次不占用主线程心跳保活check_msg()维持长连接避免掉线。7. 运行结果与测试验证7.1 串口输出结果 W55RP20 阿里云 IoT 云端上报 【调试】以太网初始化中... 网络连接中... (3/20) ✅ 网络连接成功IP: 192.168.1.118 【调试】连接阿里云 MQTT... ✅ 阿里云 MQTT 连接成功 【调试】启动 5 秒定时上报 【调试】发送JSON: {id:123,params:{CurrentTemperature:25.0,CurrentHumidity:50.0},method:thing.event.property.post} ✅ 上报成功: 温度25.0°C, 湿度50.0%7.2 阿里云平台验证进入阿里云 IoT 平台 → 设备 → 物模型数据可看到温度、湿度实时刷新日志服务可查看完整上报报文与时间。8. 常见问题一站式排查指南8.1 网络连接问题问题现象排查步骤无法联网1. 检查物理连接确认网线两端插紧观察接口指示灯正常常亮/规律闪烁熄灭则换网线重插2. 检查路由器状态确保路由器正常供电、已联网用手机/电脑测试同一路由器网络3. 检查DHCP功能登录路由器后台开启DHCP重启路由器和设备后重试。获取不到IP1. 查看IP获取状态确认是否为DHCP分配异常2. 检查DHCP地址池地址池已满则释放闲置IP或扩大范围3. 切换静态IP测试与路由器同网段如网关192.168.1.1IP设为192.168.1.100-254配置正确子网掩码255.255.255.0和网关重启设备重试。8.2 MQTT 连接失败问题现象排查步骤域名错误确认MQTT接入域名地域节点正确需包含cn-shanghai无拼写错误、遗漏节点或多余空格核对代码中域名后重新连接。参数错误ClientID、用户名、密码需通过阿里云官方工具生成不可手动填写/修改重新生成正确参数替换代码中错误内容后重试。时间错误在设备代码中添加NTP时间同步功能确保设备本地时间与阿里云服务器一致同步成功后重启MQTT连接。8.3 上报失败问题现象排查步骤Topic 错误1. 确认使用阿里云系统Topic格式严格遵循/sys/[产品ID]/[设备ID]/post无遗漏字段、无自定义名称2. 核对设备Topic权限确保拥有发布权限权限不足则在阿里云平台开启。JSON 格式错误1. 上报JSON格式需与阿里云物模型标识符完全一致无字段遗漏、拼写/大小写错误2. 确保JSON结构完整无逗号、引号、括号错误通过串口打印上报数据对照物模型逐一核对。物模型未定义1. 提前在阿里云平台创建对应物模型CurrentTemperature温度、CurrentHumidity湿度2. 确保物模型属性标识符、数据类型与设备代码中上报配置完全一致区分大小写。9.W55RP20 核心优势对比为了让你更直观地了解 W55RP20 的价值我们对比了目前主流的三种嵌入式以太网方案对比维度W55RP20 集成方案外接 PHY 芯片 方案外接 串口转以太网模块 方案BOM 成本低单芯片中高MCU 模块 外围器件高PCB 面积小仅需网口电路大需预留芯片和布线空间高开发难度低一行代码联网中高调试协议栈、编写驱动低网络稳定性极高WIZnet 专注硬件 TCP/IP 协议栈 25 年不定对于研发人员要求高熟悉协议栈与网络开发才能调试稳定不定视研发公司能力水平CPU 资源占用0%协议栈网络处理完全由硬件完成50% 以上协议栈完全运行在 MCU 上占用相关资源0%硬件 Socket 数量8 个独立硬件 Socket视 MCU 能力而定理论支持多路拓展一般为单路透传网络吞吐量最高 15Mbps视 MCU 能力而定约 3-5Mbps接口易用性单芯片集成要 MCU 带有 MII/RMII 等接口TTL 接口部署难度低MicroPython 成熟固件应用层协议绝大部分均有库文件可灵活添加部署高应用层协议需要手动移植开源库适配视模块集成情况无集成的功能需要自我封包拆包10. 典型应用场景W55RP20 芯片集成以太网功能结合其工业级稳定性非常适合以下应用场景1.工业数据采集网关简化现场部署实现传感器数据的稳定上传2.远程监控终端用于工厂、机房、变电站等环境的设备状态远程监控3.串口转网口设备将传统 RS232/RS485 串口设备快速升级为以太网设备4.智能楼宇节点用于照明、空调、门禁等楼宇设备的网络控制5.工业 PLC 扩展模块为 PLC 增加以太网通信能力实现远程编程和数据采集11. 系列预告与资源获取11.1 系列预告下一篇教程MQTT 协议与 OneNET 平台对接将讲解中移物联网 OneNET 云平台接入、MQTT 连接、属性上报与指令控制实现多平台兼容的物联网上云方案。11.2 资源获取本文完整代码WIZnet 官方 Gitee 仓库W55RP20 芯片手册WIZnet 官方资料网址如果本文对你有帮助欢迎点赞、收藏、关注你的支持是我们持续更新的动力如有任何问题欢迎在评论区留言我们会第一时间回复。