W55RP20-EVB-MKR模块 MicroPython 实战 (8):NTP 从网络获取时间并实现自动同步
本文为 W55RP20-EVB-MKR模块 MicroPython 教程专项篇,基于官方最新固件编写,代码均经过实际验证,可直接烧录运行。 版权声明:本文为 WIZnet 官方原创技术文章,转载请注明出处。
前言
上一篇实战教程,我们已经完成了 W55RP20 芯片 DNS 域名解析与公网 IP 映射功能开发。
本篇内容我们聚焦嵌入式设备精准计时的核心技术 ——NTP 网络时间同步。
NTP(网络时间协议)是物联网领域通用的时间同步协议,默认基于 UDP 123 端口通信,可让设备自动获取全球标准 UTC 时间,解决本地时钟漂移、断电清零、手动校准繁琐等问题,非常适合嵌入式以太网设备的日志打点、定时任务、多设备时序同步场景。
W55RP20 集成硬件 TCP/IP 协议栈,搭配 MicroPython 开发环境,几行代码即可实现稳定 NTP 时间同步,无需关心底层 Socket 细节,自动完成时区转换与定时重同步防漂移。
- NTP 协议核心原理与时间戳换算机制
- W55RP20 通过公网 NTP 服务器获取标准时间
- 实现 UTC 时间转北京时间时区校准
- 本地走时 + 定时重同步防漂移实现
- NTP 请求异常处理与常见问题排查
- 嵌入式设备精准计时的工业级实现方案
系列教程学习路径
本专栏共 15 篇,循序渐进覆盖 W55RP20-EVB-MKR模块 MicroPython 开发全流程:
1.第 1 篇:静态 IP 配置与网络基础
2.第 2 篇:DHCP 自动联网与网络诊断
3.第 3 篇:TCP Client 客户端通信
4.第 4 篇:TCP Server 服务端通信
5.第 5 篇:UDP 单播数据通信
6.第 6 篇:UDP 组播/广播数据通信
7.第 7 篇:DNS 域名解析
8.第 8 篇:NTP 从网络获取时间(本文)
9.第 9 篇:HTTP Client 客户端请求
10.第 10 篇:HTTP Server 服务端搭建
11.第 11 篇:HTTP 协议与 OneNET 平台数据上云
12.第 12 篇:MQTT 协议基础通信验证
13.第 13 篇:MQTT 协议与阿里云平台对接
14.第 14 篇:MQTT 协议与 OneNET 平台对接
15.第 15 篇:MQTT 协议与 ThingSpeak 平台对接
16.第 16 篇:Modbus 工业协议通信
建议收藏本专栏,跟随教程逐步学习,所有代码均会同步更新至官方 Gitee 仓库。
目录
2. 烧录 W55RP20-EVB-MKR模块专属 MicroPython 固件
1. 准备工作
1.1 软件准备
所需软件均为免费版本,按要求下载安装即可,无需额外付费。
|
软件名称 |
版本要求 |
下载地址 |
说明 |
|---|---|---|---|
|
Thonny |
4.0 及以上 |
Thonny 官方下载 |
轻量级 MicroPython IDE,支持代码编辑、烧录与串口调试,新手友好 |
|
W55RP20-EVB-MKR模块 MicroPython 固件 |
最新稳定版 |
WIZnet 官方固件下载 |
专为 W55RP20-EVB-MKR模块 编写,已集成 WIZnet 硬件驱动与协议栈 |
1.2 硬件准备
W55RP20-EVB-MKR × 1- Micro USB 数据线(必须支持数据传输,不能使用纯充电线)× 1
- 标准网线 × 1
- 开启 DHCP 功能的路由器 / 交换机 × 1(用于获取网络参数,实现 DNS 解析)
W55RP20-EVB-MKR模块已集成以太网相关器件,无需额外焊接飞线,配合 RP2040 开发板可快速搭建开发环境,大幅降低接线错误和硬件故障概率。
2. 烧录 W55RP20-EVB-MKR模块专属 MicroPython 固件
W55RP20-EVB-MKR模块 完全兼容树莓派 MKR的 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-MKR模块连接分为两步,分别实现供电/调试和以太网连接,操作简单,无需复杂接线:
3.1.1 基础连接(供电+调试)
使用 Micro USB 数据线连接 RP2040 开发板与电脑,用于开发板供电、代码烧录和串口调试。
3.1.2 以太网连接
使用网线连接 W55RP20-EVB-MKR模块的以太网接口与路由器的 LAN 口(或直接连接电脑网口,需手动配置电脑 IP 与开发板同网段)。
3.1.3 模块与开发板接线
若使用分离式模块与开发板,需按以下引脚对应连接(SPI 通信):
【硬件预留】此处插入硬件连接示意图
3.2 Thonny 开发环境配置
打开 Thonny 软件,按以下步骤配置开发环境,确保代码能正常烧录和运行:
- 点击顶部菜单栏「运行」→「配置解释器」;
- 切换到「解释器」选项卡;
- 在「解释器」下拉列表中选择 MicroPython (通用);
- 在「端口」下拉列表中选择开发板对应的串口(通常显示为 Board CDC @ COMx);
- 勾选「运行代码前先重启解释器」和「同步设备的实时时钟」;
- 点击「确定」完成配置。

如果端口列表中没有出现开发板,请尝试:
重新插拔 USB 数据线;
更换支持数据传输的 USB 数据线;
关闭其他占用串口的软件(如串口助手、Arduino IDE 等);
重新烧录 MicroPython 固件;
安装树莓派 MKRUSB 驱动。
4. NTP 协议核心原理
4.1 NTP 协议简介
NTP(Network Time Protocol)网络时间协议,是嵌入式、物联网领域通用的时间同步协议,默认使用 UDP 123 端口 进行通信。设备通过向公网 NTP 服务器发送请求数据包,获取全球统一标准时间,解决本地时钟不准、时间漂移问题。
4.2 时间戳换算规则
- NTP 原始时间:起始年份 1900-01-01
- Unix 标准时间戳:起始年份 1970-01-01
- 固定时间偏移量:用于两种时间格式相互转换
4.3 时区说明
NTP 服务器默认返回 UTC 零时区 时间,北京时间为 UTC+8,程序内部自动增加 8 小时时差,直接输出本地标准时间。
4.4 NTP 工作流程
- 开发板通过 DHCP 自动获取 IP,完成网络联网;
- 构建标准 NTP 请求报文,通过 UDP 发送至 NTP 服务器;
- 服务器返回 48 字节标准时间数据包;
- 解析数据包提取 NTP 时间戳,转换为 Unix 时间;
- 程序计算时区偏差,格式化输出年月日时分秒;
- 本地循环走时,每分钟自动重同步,抑制时间漂移。
5. 核心代码解析
5.1 完整可运行代码
from wiznet_init import wiznet
import usocket
import struct
import time
# 初始化网络
nic = wiznet("W55RP20-EVB-Pico", dhcp=True)
print("IP:", nic.ifconfig()[0])
# NTP服务器(阿里云稳定IP)
NTP_IP = "120.25.115.20"
NTP_PORT = 123
# 1900-01-01 到 1970-01-01 的秒数
NTP_TO_UNIX_DELTA = 2208988800
def get_ntp_unix_time():
"""获取标准Unix时间戳(从1970-01-01开始的秒数)"""
try:
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM)
sock.settimeout(3)
msg = b'\x1b' + b'\x00' * 47
sock.sendto(msg, (NTP_IP, NTP_PORT))
data, addr = sock.recvfrom(48)
sock.close()
ntp_timestamp = struct.unpack("!I", data[40:44])[0]
return ntp_timestamp - NTP_TO_UNIX_DELTA
except Exception as e:
print("NTP同步失败:", e)
return None
def unix_to_datetime(ts):
"""
把Unix时间戳转为(年,月,日,时,分,秒)
时区:UTC+8 北京时间
"""
# 转为北京时间
t = ts + 8 * 3600
# 先算年份
year = 1970
days_in_year = 365
while True:
# 判断闰年
is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
if is_leap:
days_in_year = 366
else:
days_in_year = 365
year_seconds = days_in_year * 86400
if t < year_seconds:
break
t -= year_seconds
year += 1
# 再算月份
if is_leap:
month_days = [31,29,31,30,31,30,31,31,30,31,30,31]
else:
month_days = [31,28,31,30,31,30,31,31,30,31,30,31]
month = 1
for md in month_days:
month_seconds = md * 86400
if t < month_seconds:
day = t // 86400 + 1
t %= 86400
break
t -= month_seconds
month += 1
# 时分秒
hour = t // 3600
t %= 3600
minute = t // 60
second = t % 60
return (year, month, day, hour, minute, second)
# 首次同步
print("正在同步NTP时间...")
unix_ts = get_ntp_unix_time()
if not unix_ts:
print("首次同步失败,程序退出")
exit()
print("同步成功!")
last_sync_ts = unix_ts
last_sync_micros = time.time()
# 每秒更新,每分钟重连NTP
while True:
elapsed = int(time.time() - last_sync_micros)
current_ts = last_sync_ts + elapsed
dt = unix_to_datetime(current_ts)
print(f"{dt[0]}年{dt[1]:02d}月{dt[2]:02d}日 {dt[3]:02d}:{dt[4]:02d}:{dt[5]:02d}")
# 每分钟重新同步一次,防止飘移
if elapsed >= 60:
print("重新同步NTP...")
new_ts = get_ntp_unix_time()
if new_ts:
last_sync_ts = new_ts
last_sync_micros = time.time()
print("重新同步成功!")
time.sleep(1)
5.2 代码功能说明
- 依靠 wiznet_init 模块快速完成硬件初始化、DHCP 自动联网;
- 配置阿里云高可用 NTP 服务器,保证同步稳定性;
- 封装 NTP 请求函数,自动收发、解析 UDP 数据包;
- 完成时间戳换算、时区加 8 小时,输出标准北京时间;
- 本地软件秒级走时,保证断网也能继续计时;
- 每分钟主动重连 NTP 服务器,修正时间漂移;
- 增加异常捕获,网络波动时不会卡死程序。

6. 运行结果与测试验证
将代码复制到 Thonny,点击运行,串口输出如下:
IP Address: ('192.168.1.123', '255.255.255.0', '192.168.1.1', '202.96.134.33')
IP: 192.168.1.123
正在同步NTP时间...
同步成功!
2026年04月30日 10:45:49
2026年04月30日 10:45:50
2026年04月30日 10:45:51
设备正常联网、时间同步成功,秒级自动刷新,时间精准无误。
7. 常见问题一站式排查
NTP 同步超时 / 同步失败
- 检查网线连接,确认开发板可以正常访问外网;
- 路由器禁止 UDP 123 端口会导致失败,更换手机热点测试;
- 更换其他公共 NTP 服务器地址。
时间相差 8 小时
- 代码未做 UTC+8 时区补偿,检查时间转换函数。
每隔一段时间时间偏差变大
- 正常现象,本程序每分钟自动重同步,可自行修改同步周期。
Thonny 无法识别开发板
- 更换 USB 线、安装 MKR串口驱动、关闭占用串口软件。
8. WIZnet 硬件协议栈核心优势对比
为了更直观地了解 W5500 硬件协议栈芯片在 UDP 组播/广播通信中的价值,我们对比了目前主流的三种嵌入式以太网方案:
|
对比维度 |
W5500 硬件协议栈方案 |
外接 PHY 芯片方案 |
|---|---|---|
|
BOM 成本 |
中(MCU + 网络模块,无需额外器件) |
中高(MCU + PHY 芯片 + 外围器件) |
|
PCB 面积 |
小(模块集成度高,仅需预留模块安装空间) |
大(需预留芯片、布线空间及外围电路) |
|
开发难度 |
低(MicroPython 固件已封装底层,少量代码实现 UDP 组播/广播) |
中高(需调试协议栈、编写底层驱动,对研发能力要求高) |
|
网络稳定性 |
极高(WIZnet 专注硬件 TCP/IP 协议栈 25 年,抗干扰能力强,UDP 丢包率低) |
不定(依赖研发人员对协议栈和网络开发的掌握程度,UDP 易丢包) |
|
CPU 资源占用 |
0%(协议栈完全由硬件处理,不占用 MCU 资源,不影响数据发送频率) |
50%以上(协议栈运行在 MCU 上,占用大量 CPU 和内存,影响 UDP 发送效率) |
|
硬件 Socket 数量 |
W5500 8个独立硬件 Socket,支持多组播/广播同时进行 |
视 MCU 能力而定,理论支持多路拓展,但实际受 CPU 资源限制 |
|
网络吞吐量 |
W5500 最高 15Mbps,UDP 数据传输流畅,无明显延迟 |
视 MCU 能力而定,普遍低于硬件协议栈方案,多设备通信易卡顿 |
|
接口易用性 |
SPI 接口,接线简单,适配大多数 MCU,支持高速通信 |
需 MCU 带有 MII/RMII 等专用接口,适配性有限 |
|
部署难度 |
低(MicroPython 成熟固件,应用层协议均有库文件,多设备组网可快速部署) |
高(应用层协议需要手动移植开源库适配,调试成本高) |
9. 典型应用场景
- 物联网设备日志时间戳记录;
- 工业传感器定时采集、定时上报数据;
- 智能家居设备定时开关、时序控制;
- 多设备组网场景下统一时间基准;
- 嵌入式教学、NTP 协议原理实验;
- 无 RTC 硬件低成本精准计时方案。
10. 系列预告与资源获取
10.1 系列预告
下一篇将带来 HTTP Client 客户端请求 实战教程,讲解基于 W55RP20-EVB-MKR硬件协议栈实现网页请求、API 数据获取、JSON 数据解析,为后续设备上云、网络数据交互打下基础。
10.2 资源获取
更多推荐



所有评论(0)