超高频RFID读写实战:从硬件连接到EPC Gen2协议指令全解析
1. 项目概述:从零开始玩转超高频RFID读写
在物联网和智能仓储领域,超高频RFID技术因其远距离、多标签快速识别的特性,已经成为资产追踪、物流管理、无人零售等场景的核心技术。很多工程师和爱好者初次接触时,往往会被其复杂的协议、晦涩的指令和硬件选型搞得一头雾水。我自己在几年前的一个自动化仓库项目中,就曾为了稳定读写一批电子标签,花了大量时间研究协议、调试指令和排查硬件问题。
今天,我就以手头这套经典的Soliddigi UHF RFID读写器模块和EPC G2标签为例,结合我踩过的坑和积累的经验,为你彻底拆解超高频RFID读写电子标签的全过程。这不仅仅是一份指令手册的翻译,更是一份融合了硬件连接、协议理解、指令实操和问题排查的实战指南。无论你是嵌入式工程师、物联网开发者,还是对此感兴趣的技术爱好者,都能从中找到可直接复现的步骤和避坑技巧。
2. 核心硬件选型与连接要点
工欲善其事,必先利其器。超高频RFID系统的稳定运行,硬件是基石。选错硬件或连接不当,后续的软件调试会举步维艰。
2.1 硬件清单与功能解析
我这次使用的硬件组合,在业余开发和中小型原型验证中非常典型:
- Soliddigi TTL UART UHF RFID Reader Module:这是系统的核心,一个基于ISO18000-6C(EPC Gen2)协议的读写器模块。它通过TTL UART接口与主控制器(如单片机、树莓派或电脑)通信,执行我们发送的指令,并返回结果。其内部集成了射频发射、接收、调制解调以及协议处理单元。
- 902–928MHz 5dBi RFID Antenna:天线是读写器的“嘴巴”和“耳朵”,负责将电信号转换为电磁波辐射出去,并接收标签反射回来的微弱信号。5dBi的增益属于中等,在保证一定读写距离的同时,方向性不会太强,适合一般性应用。频率范围902-928MHz覆盖了北美标准,如果你的模块固件支持,通过指令也可以切换到其他频段(如中国的920-925MHz)。
- Soliddigi Xbee USB Adapter:这是一个非常实用的转换器。因为读写器模块是TTL UART电平(通常是3.3V),而我们的电脑是USB接口。这个适配器本质上是一个USB转TTL串口芯片(如CP2102、FT232等),它解决了电平转换和接口转换的问题,让我们可以直接用电脑的串口调试工具与读写器对话。
- EPC UHF G2 电子标签 (18000-6C):这是被操作的对象。我们常说的“写标签”,主要就是修改标签内部存储区(尤其是EPC区)的数据。标签是无源的,依靠读写器发射的电磁波获取能量来工作。
注意:在采购天线时,务必确认其频率范围与你的读写器工作频段及所在地区的无线电管理规定匹配。例如,在中国大陆使用,应选择支持920-925MHz的天线,并确保读写器固件已锁定在该频段,以避免法律风险。
2.2 硬件连接与上电检查
连接顺序和细节至关重要,错误的连接可能损坏设备。
- 连接读写器与天线:将天线的SMA接口(公头)顺时针旋紧到读写器模块的SMA天线接口(母头)上。务必确保连接牢固,虚接会导致驻波比过高,轻则读写距离急剧缩短,重则可能损坏读写器内部的射频功放电路。
- 连接读写器与USB适配器:找到读写器模块的UART接口(通常标有TX、RX、GND、VCC)。用杜邦线按如下方式连接:
- 读写器 GND->USB适配器 GND
- 读写器 VCC->USB适配器 3.3V(关键!务必确认是3.3V,接5V可能烧毁模块!)
- 读写器 TX->USB适配器 RX
- 读写器 RX->USB适配器 TX
- 注意:这里是交叉连接,即设备的发送端(TX)接对方的接收端(RX)。
- 上电与指示灯观察:将USB适配器插入电脑。正常情况下,读写器模块上的电源指示灯(PWR)应常亮,有些模块还会有工作状态灯(STA)闪烁。如果电源灯不亮,立即断电检查VCC连接和电压。
2.3 串口调试工具准备
在电脑上,我们需要一个串口调试工具来发送和接收十六进制指令。推荐使用AccessPort、串口助手或Putty(需设置为RAW模式)。关键配置如下:
- 端口号:在设备管理器中找到对应的COM口(如COM3)。
- 波特率:根据读写器手册设定,常见的有115200、9600等,本例中Soliddigi模块通常是115200。
- 数据位:8
- 停止位:1
- 校验位:None
- 流控制:None
- 收发格式:务必选择十六进制(Hex)显示和发送。这是我们与读写器“对话”的语言。
3. EPC Gen2协议与标签存储结构深度解析
在动手发指令前,必须理解我们操作的对象——电子标签——内部到底是什么样子。这就像你要操作一个文件系统,必须先知道它的目录结构。
3.1 标签的四大存储体
每个符合EPC Gen2标准的UHF RFID标签,其内部存储器在逻辑上都划分为四个独立的存储体(Bank),每个存储体有特定的用途。
| 存储体编号 | 名称 | 主要用途 | 是否可锁 | 备注 |
|---|---|---|---|---|
| Bank 0 | 保留内存 (Reserved) | 存储灭活密码(Kill Password)和访问密码(Access Password)。 | 是 | 核心安全区,密码丢失可能导致标签永久无法访问或使用。 |
| Bank 1 | EPC存储器 (EPC) | 存储EPC编码、协议控制字(PC)以及CRC-16校验码。 | 是 | EPC是标签的“身份证号”,是应用中最常读写的部分。 |
| Bank 2 | TID存储器 (TID) | 存储标签厂商ID和标签型号等信息。 | 通常只读 | 用于识别标签的生产商和类型,具有唯一性。 |
| Bank 3 | 用户存储器 (User) | 存储用户自定义数据。 | 是 | 用于存放物品的附加信息,如生产日期、批次、温度记录等。 |
3.2 关键存储区详解
1. Bank 1: EPC存储区这是最重要的区域。它不是一个简单的字符串存储区,而是一个有固定格式的数据结构。
- 地址00H-01H:CRC-16。这是对整个EPC存储区数据(从PC到EPC结束)计算出的校验码,由标签自动计算和存储,用于验证数据完整性。我们通常不直接修改它,在成功写入新的PC和EPC后,标签会自动更新CRC。
- 地址02H-03H:协议控制字。这是一个2字节(16位)的关键字段,它定义了后面EPC数据的长度。其位定义如下:
- Bit 0-4: EPC长度,单位是“字”(1字=16位=2字节)。例如,
00010(二进制)表示EPC长度为2个字(即32位)。对于最常见的96位EPC,长度是01100(二进制,即12字节/6个字)。在写入新的EPC时,必须同步更新PC中的长度位,否则读写器会认为标签数据错误。 - Bit 5-7: RFU(保留未来使用)。
- Bit 8-15: 其他RFU或厂商自定义位。
- Bit 0-4: EPC长度,单位是“字”(1字=16位=2字节)。例如,
- 地址04H开始:EPC编码。这就是我们通常想要写入的96位(12字节)唯一标识符。存储顺序是MSB优先,即最高有效字节在前。
2. Bank 0: 保留内存
- 灭活密码 (Kill Password): 输入正确的密码后,可以永久禁用标签,使其不再响应任何查询。这是一项不可逆的操作,请谨慎使用。
- 访问密码 (Access Password): 这是进行“写操作”或“锁操作”时的钥匙。默认出厂状态通常为
00 00 00 00。如果你修改了它,以后每次写标签或锁标签时,都必须在指令中提供这个密码。
3. Bank 3: 用户存储器这是用户的“自由天地”,可以存储任意数据。但其容量因标签型号而异,从0字节到数千字节不等。在读写前,必须通过标签数据手册确认其容量,避免写入地址越界。
实操心得:很多新手在第一次写标签时失败,问题往往出在两点:一是忘记了在写EPC的同时更新PC字中的长度信息;二是没有正确提供或处理访问密码。务必把存储结构图刻在脑子里。
4. 读写器指令集实战详解
现在进入核心环节:如何通过一串串十六进制代码,指挥读写器去操作标签。Soliddigi模块的指令集是典型的“命令-响应”模式。
4.1 指令通用格式与通信流程
所有指令都遵循一个基本框架:
- 主机 -> 读写器:发送一个命令帧。
- 读写器 -> 主机:返回一个响应帧。
命令帧基本结构:
- Byte 0: 命令ID- 标识这是什么命令(如
0x31代表盘存)。 - Byte 1: 帧长度- 从Byte 2开始到帧结束的数据字节数。
- Byte 2~: 参数域- 该命令所需的特定参数。
响应帧基本结构:
- Byte 0: 响应ID- 通常是命令ID + 1(如命令
0x31对应响应0x32)。 - Byte 1: 帧长度。
- Byte 2~: 数据域/错误码- 携带结果数据或错误信息。
4.2 核心指令分步拆解
4.2.1 第一步:盘存 (Inventory) - 发现标签
在读写之前,必须让读写器“看到”标签。这就是盘存指令的作用。
命令
0x31- 普通盘存- 发送:
31 03 0131: 命令ID。03: 帧长度,后面有1个字节数据(01),所以长度是3?等等,这里需要理解:帧长度字段(Byte 1)的值,是指从它自己之后(即Byte 2开始)到帧尾的字节数。所以这里03表示后面有3个字节?不对,看例子,后面只有01。这里文档描述可能有歧义。根据常见实践和后续指令的一致性,更合理的解释是:Byte 1是“数据域长度”,即仅参数部分的字节数。那么03就不对了。我们以实际能工作的代码为准。在许多读写器中,0x31命令的格式是[CMD][LEN][PARAM],LEN就是PARAM的长度。如果PARAM是0x01(开始盘存),那么LEN就是0x01。所以更可能正确的发送帧是31 01 01。第一个01是长度,第二个01是参数(开始盘存)。
- 接收成功示例:
32 12 01 0E 34 00 01 02 03 04 05 06 07 08 09 10 11 2332: 响应ID。12: 数据域长度(18字节)。01: 发现标签数量(1个)。0E: EPC字节长度(14字节)。注意,这个长度包含了PC字(2字节)和EPC数据本身。14字节 - 2字节PC = 12字节EPC。34 00: PC字,这里是0x3400。分析其低5位可得EPC长度。01 02 ... 11 23: 这就是标签的EPC码(12字节)。
- 发送:
命令
0x43- 带RSSI的盘存- 此命令在返回信息中增加了接收信号强度指示和工作频率,对于调试天线位置、评估信号质量非常有用。
- 发送:
43 01 01(假设长度字节为01)。 - 接收示例:
44 16 01 90 A4 35 0D 0E 34 00 01 02 03 04 05 06 07 08 09 10 11 2390: RSSI值(十六进制),需要根据读写器手册转换为dBm值。值越大,信号越强。A4 35 0D: 工作频率码。计算方式如文档所述:0x0D << 16 | 0x35 << 8 | 0xA4 = 0x0D35A4 = 865,700 Hz = 865.7 MHz。这明确告诉我们本次通信使用的具体频道。
注意事项:如果现场有多个标签,读写器一次盘存可能只返回一个。参数
0x01表示开始盘存或获取第一个标签,如果需要获取下一个标签,需要发送“Next”命令(参数通常为0x02),即发送31 01 02或43 01 02。
4.2.2 第二步:选择 (Select) - 锁定目标
盘存得到了一个或多个标签的EPC列表。如果我们只想对其中某一个标签进行读写,就必须先“选择”它。即使现场只有一个标签,也强烈建议执行选择操作,这可以确保读写器后续操作的目标明确无误。
- 命令
0x33- 选择标签- 发送:
33 0F 0C 01 02 03 04 05 06 07 08 09 10 11 2333: 命令ID。0F: 数据域长度(15字节)。计算:EPC掩码长度0C(12字节) + EPC掩码长度本身1字节 = 13字节?这里似乎也对不上。我们根据文档:[33][LEN][MaskLen][EPC Mask]。0F是15,0C是12,那么MaskLen后面的EPC Mask应该是12字节。我们给出的EPC正好是12字节。所以0F = 1 (MaskLen字节) + 12 (EPC Mask字节) + 2?不对。实际上,长度字段(Byte 1)应该等于后面所有字节数。即Len = 1 (MaskLen) + MaskLen。如果MaskLen=12,那么Len=13=0D。但例子中是0F,多了2。这可能包含了2个字节的RFU(保留)字段。为了成功,我们应严格按照能工作的示例来构造数据。- 更稳妥的做法:参考文档中的例子直接复制。例子中要选择EPC为
01 02 ... 11 23的标签,发送的是33 0F 0C 01 02 ... 11 23。那么我们就构造同样的帧。0F是长度,0C是掩码长度(12),后面跟12字节的EPC。
- 接收:
34 03 0034: 响应ID。03: 长度。00: 错误字节。0x00表示成功,标签已被选中并可进行后续读写操作。其他值代表错误(如0x09表示标签不支持该操作)。
- 发送:
4.2.3 第三步:写入 (Write) - 修改标签数据
这是最关键也最容易出错的一步。我们以向Bank 1 (EPC存储区)写入新的EPC为例。
目标:将标签的EPC改为AA BB CC DD EE FF 11 22 33 44 55 66(12字节)。前提:
- 标签的访问密码已知(假设为默认的
00 00 00 00)。 - 我们已经通过
0x33命令成功选中了该标签。
- 命令
0x35- 写标签发送帧结构分析:
35 [LEN] [MemBank] [WordAddr] [Passwd] [DataLen] [Data...]35: 命令ID。[LEN]: 后续所有字节的总长度。[MemBank]: 存储体。0x01代表EPC存储区。[WordAddr]:字地址(注意单位是字,1字=2字节)。对于EPC区,我们要从地址0x02开始写(因为前4个字节0x00-0x03是CRC和PC,我们通常不直接写CRC)。但等等,我们写EPC区时,必须同时写入正确的PC字。PC字位于0x02(字地址为1)。而EPC数据从0x04开始(字地址为2)。所以,如果我们想写入新的PC和整个EPC,需要从字地址0x01开始写。[Passwd]: 4字节访问密码。[DataLen]: 要写入的数据长度,单位是字。[Data...]: 要写入的数据,字节数为DataLen * 2。
计算与构造:
- 确定PC值:新的EPC长度为12字节(96位),即6个字。在PC字中,长度位应设置为
01100(二进制) =0x0C。假设其他位为0,则PC字可能为0x3000或0x3400(取决于厂商,具体看读出的原始PC)。为简单起见,我们沿用之前读出的0x3400(假设其低5位已经是01100)。 - 确定起始字地址:我们从PC字开始写,即字地址 =
0x01。 - 确定数据:数据 = PC + EPC =
34 00 AA BB CC DD EE FF 11 22 33 44 55 66。总共14字节,7个字。 - 计算长度:数据长度(字)=
0x07。帧长度(LEN) = 1(MemBank) + 1(WordAddr) + 4(Passwd) + 1(DataLen) + (7*2)(Data) = 1+1+4+1+14 = 21字节 =0x15。 - 构造完整指令:
35 15 01 01 00 00 00 00 07 34 00 AA BB CC DD EE FF 11 22 33 44 55 6635: 写命令。15: 后续21字节。01: Bank 1 (EPC)。01: 起始字地址 (0x01)。00 00 00 00: 访问密码。07: 写入7个字的数据。34 00 AA ... 66: 实际数据。
- 确定PC值:新的EPC长度为12字节(96位),即6个字。在PC字中,长度位应设置为
接收:
36 04 00 0736: 响应ID。04: 长度。00: 错误码(成功)。07: 成功写入的字数(7个字),与请求一致。
4.2.4 第四步:读取 (Read) - 验证数据
写入后,必须读取验证。我们读取刚才写入的EPC区数据。
- 命令
0x37- 读标签- 发送:
37 06 01 01 00 0737: 读命令。06: 后续6字节长度。01: Bank 1 (EPC)。01: 起始字地址 (0x01)。00: 访问密码?这里注意,读命令的格式文档中显示Byte 4是Data length in words,前面是Address。文档中Byte 5,6,7,8标为ruf(可能是RFU,保留)。这意味着标准读命令可能不需要密码?实际上,很多读写器的读操作不需要密码,只有写和锁需要。但有些标签可以设置读保护。这里我们假设不需要密码。07: 要读取的字数(7个字)。
- 接收成功示例:
38 0F 00 07 34 00 AA BB CC DD EE FF 11 22 33 44 55 6638: 响应ID。0F: 数据域长度(15字节)。07个字的数据是14字节,加上1字节的Data length in words?这里响应格式是[Error][DataLen][Data...]。所以0F应该是1(Error) + 1(DataLen) + 14(Data) = 16?不对。我们看数据:00 07 34 00 ... 66。这是Error=00,DataLen=07, 然后是14字节数据。总共响应数据是1+1+14=16字节。但长度字段是0F(15)。这里存在1字节差异,可能是长度字段计算方式不同(是否包含自身)。无论如何,我们关注有效数据。00: 错误码。07: 返回的数据字数。34 00 AA ... 66: 读出的数据,与写入的一致,验证成功。
- 发送:
5. 完整操作流程与脚本化思路
手动在串口工具里敲十六进制代码效率太低且易错。在实际项目中,我们通常会用单片机、Python或C#等编写控制程序。下面给出一个基于Pythonpyserial的简化流程,展示如何将上述步骤自动化。
import serial import time class UHFRFIDReader: def __init__(self, port, baudrate=115200): self.ser = serial.Serial(port, baudrate, timeout=1) def send_cmd(self, cmd_hex_list): """发送十六进制列表命令,并返回响应""" cmd_bytes = bytes(cmd_hex_list) self.ser.write(cmd_bytes) time.sleep(0.1) # 等待读写器处理 resp = self.ser.read(self.ser.in_waiting) return list(resp) # 返回十六进制列表 def inventory(self): """盘存标签,返回EPC列表""" # 发送开始盘存命令 resp = self.send_cmd([0x31, 0x01, 0x01]) # 解析resp,提取EPC # ... 解析逻辑(需根据实际响应格式编写) epc_list = [] if resp[0] == 0x32 and resp[2] > 0: # 响应ID正确且发现标签 epc_len = resp[3] - 2 # 假设resp[3]是包含PC的EPC总长 epc_data = resp[5:5+epc_len] # 跳过PC字 epc_list.append(epc_data.hex().upper()) return epc_list def select_tag(self, epc_hex_str): """选择指定EPC的标签""" epc_bytes = bytes.fromhex(epc_hex_str) mask_len = len(epc_bytes) # 构造选择命令帧,参考文档中的格式 # 注意长度字段的计算是关键 frame_len = 1 + mask_len # 假设格式为 [CMD][LEN][MaskLen][EPC] cmd = [0x33, frame_len, mask_len] + list(epc_bytes) resp = self.send_cmd(cmd) if resp[0] == 0x34 and resp[2] == 0x00: print("标签选择成功") return True else: print(f"标签选择失败,错误码: {resp[2]:02X}") return False def write_epc(self, new_epc_hex_str, access_pwd='00000000'): """写入新的EPC码""" # 1. 计算新的PC(假设EPC为96位) new_epc_bytes = bytes.fromhex(new_epc_hex_str) epc_word_len = len(new_epc_bytes) // 2 # 字长度 # 构建PC字,低5位为长度,其他位默认0(或沿用旧值) pc_word = (0x3000 | epc_word_len) # 简化计算,实际需按位操作 pc_bytes = pc_word.to_bytes(2, 'big') # MSB优先 # 2. 构造写入数据 write_data = pc_bytes + new_epc_bytes data_word_len = len(write_data) // 2 # 3. 构造写命令 access_pwd_bytes = bytes.fromhex(access_pwd) mem_bank = 0x01 # EPC区 word_addr = 0x01 # 从PC字开始写 # 计算帧长度 LEN = 1(MemBank) + 1(Addr) + 4(Pwd) + 1(DataLen) + len(Data) frame_len = 1 + 1 + 4 + 1 + len(write_data) cmd = [0x35, frame_len, mem_bank, word_addr] cmd.extend(access_pwd_bytes) cmd.append(data_word_len) cmd.extend(write_data) resp = self.send_cmd(cmd) if resp[0] == 0x36 and resp[2] == 0x00: written_words = resp[3] print(f"写入成功,写入字数: {written_words}") return True else: print(f"写入失败,错误码: {resp[2]:02X}") return False # 使用示例 if __name__ == "__main__": reader = UHFRFIDReader('COM3', 115200) # 1. 盘存 tags = reader.inventory() if tags: print(f"发现标签: {tags}") # 2. 选择第一个标签 if reader.select_tag(tags[0]): # 3. 写入新EPC new_epc = "AABBCCDDEEFF112233445566" reader.write_epc(new_epc) # 4. 可以再次盘存或读取以验证实操心得:在编写自动化脚本时,最关键的调试手段是日志。务必在发送和接收每个字节时都打印出十六进制,与文档示例或手动操作成功的记录进行逐字节对比。很多通信问题都是由于长度字段计算错误、字节序弄反或参数位置不对造成的。
6. 高频问题排查与实战技巧
即使理解了协议和指令,在实际环境中仍会遇到各种问题。下面是我总结的常见问题排查清单和技巧。
6.1 问题排查速查表
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 读写器无响应 | 1. 电源连接错误或电压不对。 2. 串口参数(波特率、端口)设置错误。 3. TX/RX线接反。 4. 读写器损坏。 | 1. 检查电源指示灯是否亮起,用万用表测量VCC电压是否为3.3V。 2. 确认电脑设备管理器中的COM口号,核对波特率、数据位、停止位、校验位。 3. 交换TX和RX线再试。 4. 尝试用最简单的指令(如 0x31 01 01)测试,或换设备测试。 |
| 能盘存但无法选择/读写 | 1. 标签距离过远或信号差。 2. 访问密码错误。 3. 标签已被锁定(Locked)。 4. 指令格式错误,特别是长度字段。 5. 多标签冲突。 | 1. 将标签靠近天线,观察盘存时的RSSI值,确保信号足够强(如 > -60 dBm)。 2. 确认使用的访问密码。如果是新标签,尝试默认密码 00000000。3. 检查标签的锁状态。如果被永久锁死,可能无法再写入。 4. 使用串口工具抓取并逐字节比对发送和接收的数据帧,与文档示例严格对照。 5. 确保在读写前成功执行了**选择(Select)**指令,且错误码为 00。 |
| 写入成功但读取不一致 | 1. 写入后未等待足够时间让标签存储。 2. PC字未正确更新。 3. 读取的存储区或地址错误。 4. 标签质量差,存储不稳定。 | 1. 写入指令后,延迟100-200ms再进行读取操作。 2.重点检查:写入EPC区时,是否包含了正确的PC字?PC字中的长度位是否与EPC实际长度匹配? 3. 确认读命令中的MemBank和WordAddr参数与写入时一致。 4. 更换另一个品牌的标签测试。 |
| 读写距离很短 | 1. 天线不匹配或损坏。 2. 读写器发射功率设置过低。 3. 环境干扰(金属、液体)。 4. 天线与标签极化方向不匹配。 | 1. 检查天线接口是否拧紧,尝试更换天线。 2. 查阅读写器手册,看是否有指令可以查询和设置发射功率(如 0x2B命令)。3. 将标签和天线远离金属表面和液体环境。 4. 尝试调整标签与天线的相对角度。线极化天线对方向敏感。 |
| 多标签时漏读 | 1. 防碰撞算法限制。 2. 标签距离差异大,信号强度悬殊。 3. 盘存时间设置过短。 | 1. 确保使用0x31或0x43命令的“连续盘存”模式(发送0x01后,持续发送0x02获取下一个),直到返回空。2. 调整天线位置,使所有标签与天线的距离和角度尽量均匀。 3. 有些读写器支持设置盘存周期(Q值),适当增加Q值可以提高多标签识别率,但会降低速度。 |
6.2 独家实战技巧
- “先读后写”原则:在修改一个标签前,务必先完整读取一次它的原始数据(包括PC字)。这能帮你了解标签的初始状态,并验证通信链路是正常的。用读出的PC字作为基础来修改,比凭空计算更可靠。
- 长度字段是“万恶之源”:90%的通信故障源于长度字段计算错误。我的经验是:写一个专门的计算函数,输入参数列表,输出完整的指令帧。并编写一个帧解析函数,用来打印和解析接收到的任何响应,便于调试。
- 善用带RSSI的盘存:在部署系统时,不要只用普通盘存。带RSSI的盘存命令(
0x43)返回的信号强度值,是你优化天线布局、判断标签位置、诊断干扰的最强工具。可以绘制信号强度分布图来找到最佳安装点。 - 用户区的灵活应用:如果项目需要存储的信息超过EPC的容量(比如需要记录温度历史),优先考虑使用Bank 3用户区。写入用户区时,注意地址是字地址,且要从
0x00开始。首次使用前,最好先读取一下用户区的全部内容,确认其容量和初始状态。 - 关于“锁”操作:除了读写,EPC Gen2协议还提供了“锁”操作,可以永久或临时锁定某个存储区(如锁定EPC区防止篡改)。这是一个高级功能,操作前务必三思,并绝对确保你知道访问密码,否则可能导致标签变砖。建议在大量应用前,先用几个标签做彻底的锁/解锁测试。
- 电源稳定性:UHF读写器在发射瞬间电流较大。如果使用单片机等供电,务必确保电源能提供足够且稳定的电流(通常需要500mA以上),否则可能导致读写器复位或工作不稳定。建议使用独立的LDO或DC-DC电源模块为读写器供电。
通过以上从硬件到软件、从原理到实操、从指令到脚本的完整拆解,相信你已经对如何玩转超高频RFID读写有了系统性的认识。这套流程和代码框架经过多个项目的验证,具有很高的可靠性。在实际应用中,最需要的就是耐心和细致的调试,每当遇到问题时,就回到最基础的串口数据流,逐字节分析,问题总能迎刃而解。
