全网你能看到最全的 RFID 整体技术介绍!
标签数据格式内部分区
超高频 RFID 的标签芯片需要符合 EPC C1Gen2 标准(简称 Gen2 协议),也就是说所有的超高频 RFID 标签芯片内部存储结构大致一样。 如图所示,标签芯片的存储区分为四个区(Bank)分别是 Bank 0 保留区(Reserved)、Bank 1 电子编码区(EPC)、Bank 2 厂商编码区(TID)、 Bank 3 用户区(User)。
1.Reserved 区:(密码区) :存储 Kill Password(灭活口令)和 Access Password(访问口令)。
2.EPC 区: 存储 EPC 号码等。
3.TID 区: 存储标签识别号码,每个 TID 号码应该是唯一的。
4.User 区: 存储用户定义的数据。
此外还有各区块的 Lock(锁定)状态位等用到的也是存储性质的单元。
各厂家不同的电子标签,采用的存储介质,各个数据区大小和接口方式均不同。
其中 Bank 0 保留区又称密码区,内部有两组 32 比特密码,分别是访问密码(Access Password)和灭活密码(Kill Password),灭活密码俗称杀死密码。 当使用锁定命令后,需要通过访问密码才可以对芯片的一些区域进行读写。当需要杀死芯片的时候,通过杀死密码可以将芯片彻底杀死。
Bank 1 为电子编码区,是大家最熟悉的 EPC 区。根据 Gen2 协议,最先获得标签的信息是 EPC 信息,之后才能访问其他存储区进行访问。EPC 区分为三个部分:
CRC16 校验部分共 16 比特,通信时负责校验阅读器获得的 EPC 是否正确。
PC 部分(Protocol Control)共 16 比特,控制 EPC 的长度,其前 5 比特的二进制数乘以 16 为 EPC 长度,如 96 比特 EPC 时的 PC=3000,其前 5 个比特为 00110,对应十进制为 6,乘以 16 为 96Bit。 根据协议要求,PC 可以等于 0000 到 F100,相当于 EPC 的长度为 0、32 比特、64 比特直到 496 比特。但是一般情况下超高频 RFID 应用中 EPC 的长度在 64 比特到 496 比特之间,也就是说 PC 值在 2800 到 F100 之间。在平时的应用中经常有人搞不清楚 EPC 中 PC 的作用,会卡在 EPC 长度的设置上从而带来很多麻烦。
EPC 部分,这部分才是最终用户从应用层获得的芯片电子编码。
Bank 2 为厂商编码区,每颗芯片都有自己的唯一编码。
CRC 1 单位 PC 1 单位 EPC 6 单位
Bank 3 为用户存储区,该存储区根据协议规定最小空间为 0,但是多数芯片为了方便客户应用,增加了用户存储空间,最常见的存储空间为 128 比特或 512 比特。
在了解了标签的存储区之后,需要进一步了解 Gen2 的几个操作命令即读(Read)、写(Write)、锁(Lock)、杀(Kill)。Gen2 的命令很简单,操作命令只有 4 个,且标签的存储区状态只有两种:锁定、未锁定。
因为读写命令都与数据区是否锁定相关,我们先从锁命令讲起。锁命令对四个存储区共有 4 个分解命令分别是锁定(Lock)、解锁(Unlock)、永久锁定(Permanent Lock)、永久解锁(Permanent Unlock),只要访问密码非全 0 即可进行锁定命令。对应四个区的操作如下表所示。
代码
使用库:micropython-mfrc522
import mfrc522
from os import uname
def do_read():
if uname()[0] == 'WiPy':
rdr = mfrc522.MFRC522("GP14", "GP16", "GP15", "GP22", "GP17")
elif uname()[0] == 'esp8266':
rdr = mfrc522.MFRC522(0, 2, 4, 5, 14)
else:
raise RuntimeError("Unsupported platform")
print("")
print("Place card before reader to read from address 0x08")
print("")
try:
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print("New card detected")
print(" - tag type: 0x%02x" % tag_type)
print(" - uid : 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
print("")
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print("Address 8 data: %s" % rdr.read(8))
rdr.stop_crypto1()
else:
print("Authentication error")
else:
print("Failed to select tag")
except KeyboardInterrupt:
print("Bye")
附录
https://blog.csdn.net/watch361/article/details/136949087
RFID —— 充值消费系统:https://blog.csdn.net/weixin_44935259/article/details/111392684
RFID 卡在学校就餐管理系统中的应用设计:https://www.xatrm.com/cjxxxjsjsfz/113096.jhtml