ZZ-D541SM 超高频 RFID 阅读器串口通信协议完全指南
基于实际项目踩坑经验整理,从零开始掌握这款工业级 RFID 阅读器的通信细节。
背景
在物联网和仓储管理场景中,超高频 RFID 技术被广泛用于远距离、批量化的资产追踪。ZZ-D541SM 是一款性价比不错的国产一体化超高频阅读器,支持 EPCglobal UHF Class 1 Gen2 / ISO 18000-6C 标准。
本文档是我在实际项目开发过程中,通过串口抓包和反复调试整理出来的协议详解,希望能帮到同样在使用这款设备的开发者。
设备接口参数
| 参数 | 值 | 说明 |
|---|---|---|
| 物理接口 | RS232 / USB 转串口 | DB9 母头或 USB 虚拟串口 |
| 波特率 | 115200 bps | 出厂默认,可配置 |
| 数据位 | 8 | — |
| 停止位 | 1 | — |
| 校验位 | 无 | None |
| 流控 | 无 | — |
| 设备地址 | 0x0001 | 默认地址 |
| 广播地址 | 0x0000 | 用于排查通信 |
踩坑提示: 如果 115200 通信失败,先别急着怀疑代码,试试 9600 / 19200 / 38400 等波特率。有时候厂家出货时会改默认值。
数据帧格式
标准帧结构
大多数命令都遵循这个标准帧格式:
1 | ┌─────────┬────────┬─────────────┬─────────┐ |
| 字段 | 长度 | 说明 |
|---|---|---|
| 帧头 | 2 字节 | 固定为 0x7E 0x55 |
| 长度 | 1 字节 | 数据域字节数 + CRC 字节数(即总长度 − 3) |
| 数据域 | N 字节 | 保留/地址 + 功能码 + 参数 + 负载 |
| CRC16 | 2 字节 | 小端序,CRC-16/X-25 |
长度计算示例(获取系统参数请求):
1 | 7E 55 09 00 00 01 00 F5 00 00 BD 91 |
⚠️ 盘点响应帧(特殊格式)
重要提醒:盘点标签响应帧的结构和标准帧不一样!第 3 字节是保留字段 0x00,不是长度字段。这是我在项目中踩的第一个大坑。
1 | ┌─────────┬────────┬────────┬──────────┬──────────┬────────┬──────────┬─────────────┬────────┐ |
盘点响应总长度 = 12(固定头) + 数据域长度(第 11 字节,索引 10) + 2(CRC)
1 | 总长度 = 12 + frame[10] + 2 |
响应状态码
| 状态码 | 含义 |
|---|---|
0x00 |
失败 / 错误 |
0x01 |
成功 / 正常 |
所有响应帧的第 8 字节(索引 7)固定为 0x1F,这是通用响应标识。
命令详解
1. 获取系统参数(0xF5)
请求帧
1 | 7E 55 09 00 00 01 00 F5 00 00 BD 91 |
| 字节 | 值 | 说明 |
|---|---|---|
| 0~1 | 7E 55 |
帧头 |
| 2 | 09 |
长度 = 9 |
| 3~4 | 00 00 |
保留/地址 |
| 5 | 01 |
子命令 |
| 6 | 00 |
保留 |
| 7~8 | F5 00 |
功能码 + 参数索引 |
| 9 | 00 |
附加数据 |
| 10~11 | BD 91 |
CRC-16 |
响应帧(成功)
1 | 7E 55 10 01 00 00 00 1F F5 00 01 00 01 00 00 00 00 9D 53 |
2. 蜂鸣器控制(0xF4)
控制阅读器的蜂鸣器开关,参数索引 0x01。
关闭蜂鸣器
1 | 7E 55 0D 00 00 01 00 F4 00 01 00 00 00 00 8F 54 |
开启蜂鸣器
1 | 7E 55 0D 00 00 01 00 F4 00 01 01 00 00 00 34 48 |
| 字节 | 值 | 说明 |
|---|---|---|
| 0~1 | 7E 55 |
帧头 |
| 2 | 0D |
长度 = 13 |
| 3~6 | 00 00 01 00 |
保留/地址 |
| 7~8 | F4 00 |
功能码 |
| 9 | 01 |
参数索引:蜂鸣器 |
| 10 | 00 / 01 |
参数值:0x00=关,0x01=开 |
响应帧(成功)
1 | 7E 55 0B 01 00 00 00 1F F4 00 00 00 BE E8 |
3. 设置天线功率(0xF0)
这个命令用于设置射频发射功率,直接影响读取距离。
数据域结构
| 偏移 | 说明 |
|---|---|
| 保留/地址 | 00 00 01 00(4 字节) |
| 功能码 | F0 00 |
| 功率 | dBm 原值(如 33 → 0x21,30 → 0x1E) |
| 天线端口 | 01(Ant1) |
| 频段参数 | 07 3B |
| 保留 | 00 00 00 00 |
| 设备标识 | D1 |
常用功率预设
| 目标功率 | 功率字节 | 完整请求帧 |
|---|---|---|
| 20 dBm | 0x14 |
7E 55 11 00 00 01 00 F0 00 14 01 07 3B 00 00 00 00 D1 6A E2 |
| 25 dBm | 0x19 |
7E 55 11 00 00 01 00 F0 00 19 01 07 3B 00 00 00 00 D1 B8 EF |
| 30 dBm | 0x1E |
7E 55 11 00 00 01 00 F0 00 1E 01 07 3B 00 00 00 00 D1 5A 06 |
| 33 dBm | 0x21 |
7E 55 11 00 00 01 00 F0 00 21 01 07 3B 00 00 00 00 D1 DF 98 |
设备射频功率范围为 0~33 dBm。功率字节 = dBm 十进制值。
响应帧(成功)
1 | 7E 55 0B 01 00 00 00 1F F0 00 00 00 52 9A |
⚠️ 响应为固定确认,不返回实际功率值。设置成功不代表射频已输出到目标 dBm,需结合现场读距验证。
4. 盘点标签(0x10)
这是最常用的命令,用于读取附近的 RFID 标签。
请求帧
1 | 7E 55 0B 00 00 01 00 10 00 01 00 01 F8 1E |
响应帧数据域(从字节 12 起)
1 | ┌──────────────┬────────────┬─────────────┬────────────┬─────────────┐ |
标签数量小端序:
01 00= 1 张,02 00= 2 张。
示例:单标签读取
1 | 7E 55 00 01 00 00 00 1F 10 00 0F 00 01 00 0C 13 59 22 80 65 79 24 14 35 14 20 03 8A B9 |
- 数据域长度
0x0F= 15 - EPC:
135922806579241435142003
示例:双标签读取
1 | 7E 55 00 01 00 00 00 1F 10 00 1C 00 02 00 0C 13 59 22 80 65 79 24 14 35 14 20 02 0C 13 59 22 80 65 79 24 14 35 14 20 03 79 6B |
- 数据域长度
0x1C= 28 - 标签 1:
135922806579241435142002 - 标签 2:
135922806579241435142003
EPC 解析规则
标签数据格式
每张标签:[EPC长度 1B] + [EPC数据 NB],长度常为 0x0C(12 字节)。
Code 规则
EPC Code = 各字节 Hex 直接拼接为大写字符串,不做十进制转换。
1 | 13 59 22 80 65 79 24 14 35 14 20 02 → 135922806579241435142002 |
.NET 解析代码
1 | using System; |
CRC-16 校验算法
本协议使用 CRC-16/X-25 校验算法:
- 多项式:
0x8408(反射) - 初始值:
0xFFFF - 最终异或:
0xFFFF - 输出: 小端序
- 计算范围: 长度字段 + 数据域(不含帧头
7E 55)
1 | using System; |
Web Demo 有效标签策略
配套项目 zz-d541sm-web-serial-demo 对「当前标签」采用以下策略(与单次盘点历史分离):
| 参数 | 值 | 说明 |
|---|---|---|
| 统计窗口 | 5 秒 | 滑动时间窗 |
| 有效判定 | ≥ 5 次 | 同一 EPC 在窗口内读取次数 |
| 界面刷新 | 每 5 秒 | 统一判定并更新列表 |
| 定时盘点 | ×100ms | 如输入 1 = 100ms,5 = 500ms |
推荐操作顺序: 连接 → 系统参数 → 设置功率(默认 33dBm)→ 盘点 / 定时盘点 → 蜂鸣器开关
完整命令速查表
请求帧
| 命令 | 功能码 | 完整帧(Hex) |
|---|---|---|
| 获取系统参数 | F5 |
7E 55 09 00 00 01 00 F5 00 00 BD 91 |
| 关闭蜂鸣器 | F4 |
7E 55 0D 00 00 01 00 F4 00 01 00 00 00 00 8F 54 |
| 开启蜂鸣器 | F4 |
7E 55 0D 00 00 01 00 F4 00 01 01 00 00 00 34 48 |
| 设置功率 20dBm | F0 |
7E 55 11 00 00 01 00 F0 00 14 01 07 3B 00 00 00 00 D1 6A E2 |
| 设置功率 25dBm | F0 |
7E 55 11 00 00 01 00 F0 00 19 01 07 3B 00 00 00 00 D1 B8 EF |
| 设置功率 30dBm | F0 |
7E 55 11 00 00 01 00 F0 00 1E 01 07 3B 00 00 00 00 D1 5A 06 |
| 设置功率 33dBm | F0 |
7E 55 11 00 00 01 00 F0 00 21 01 07 3B 00 00 00 00 D1 DF 98 |
| 盘点标签 | 10 |
7E 55 0B 00 00 01 00 10 00 01 00 01 F8 1E |
响应帧
| 命令 | 完整响应帧(Hex) |
|---|---|
| 获取系统参数(成功) | 7E 55 10 01 00 00 00 1F F5 00 01 00 01 00 00 00 00 9D 53 |
| 蜂鸣器控制(成功) | 7E 55 0B 01 00 00 00 1F F4 00 00 00 BE E8 |
| 天线功率设置(成功) | 7E 55 0B 01 00 00 00 1F F0 00 00 00 52 9A |
故障排查
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 无响应 | 波特率不匹配 | 尝试 9600 / 19200 / 38400 / 115200 |
port already open |
端口未关闭重复打开 | 断开后重连;Web 端使用已授权端口快速重连 |
| CRC 错误(盘点) | 按标准帧解析盘点响应 | 确认第 3 字节为 0x00,按专用格式解析 |
| 30dBm 读不到、33dBm 可以 | 功率不足或响应无回读 | 提高功率;响应帧不反映实际输出 |
| 读不到标签 | 距离 / 功率 / 协议 | 提高功率至 25~33 dBm;确认 Gen2 标签 |
| 蜂鸣器无反应 | 参数索引或值错误 | 对照开/关帧格式 |
命令码总表
系统控制
| 命令码 | 说明 |
|---|---|
0xF8 |
获取射频模块温度 |
0xF7 |
获取版本信息 |
0xF6 |
获取天线反射损耗 |
0xF5 |
读取系统工作参数 |
0xF4 |
设置系统工作参数(含蜂鸣器) |
0xF1 |
获取天线工作参数 |
0xF0 |
设置天线工作参数(含功率) |
0x04 |
软件复位 |
标签操作(ISO 18000-6C)
| 命令码 | 说明 |
|---|---|
0x10 |
盘点标签 |
0x11 |
自定义盘点标签 |
0x12 |
读取标签存储区 |
0x13 |
写入标签存储区 |
0x20 |
快速盘点标签 |
写在最后
这份协议文档是我在实际项目中踩坑后整理的,特别是盘点响应帧的特殊格式,差点让我调试了一整天。希望这篇文章能帮你少走一些弯路。
如果你也在做 RFID 相关的开发,欢迎在评论区交流。
文档版本记录
- V1.0 (2026-06-17) - 初版,基于串口抓包整理
- V1.1 (2026-06-18) - 补充盘点响应专用帧格式;蜂鸣器开/关;33dBm 功率;Web Demo 有效标签策略
声明: 本协议为设备厂商专有自定义协议,部分内容基于实际串口交互逆向整理。开启蜂鸣器帧由关闭帧参数取反推导,若与厂商文档不一致请以官方为准。