YZXPG开发笔记 (基于ModuleAPI C# SDK)
初探射频识别技术
1. RFID简介
RFID (Radio Frequency Identification) 自动识别技术的一种,通过无线射频进行非接触双向数据通信,利用无线射频方式对记录媒体(电子标签或射频卡)进行读写。
标签存储器分区 分为Reserved,EPC(电子产品代码),TID(标签识别号)和User(四个独立的存储区块(Bank)。
RESERVED区:8byte,前4byte为摧毁密码KillTag(filter, killpwd);,后4byte为访问密码ParamSet("AccessPassword", accesspwd);,默认值为:0000 0000 (摧毁密码) 0000 0000 (访问密码)。
TID区:12byte大小,“永久可读,不可改写”, 出厂已经写入,为标签的唯一标识符,电子标签的产品类识别号,每个生产厂商的TID号都会不同。
EPC区:识别标签对象的电子产品码。
USER区:该存贮器的长度由各个电子标签的生产厂商确定,USER区可以写入用户自定义的数据(以16进制形式)。
1.1 锁bank
| Reserved | EPC | TID | USER | |
|---|---|---|---|---|
| 锁定 | 1 | 1 | 永久锁定 | 1 |
| 解锁 | 1 | 1 | 1 | |
| 永久锁定 | 1 | 1 | 1 | |
| 永久解锁 | 1 | 1 | 1 |
1.2 读bank
| Reserved锁定 | EPC锁定 | TID | USER锁定 | |
|---|---|---|---|---|
| 有访问密码 | 1 | 永久可读 | 永久可读 | 1 |
| 无访问密码 | 0 | 0 |
| Reserved未锁定 | EPC未锁定 | TID | USER未锁定 | |
|---|---|---|---|---|
| 有访问密码 | 1 | 永久可读 | 永久可读 | 1 |
| 无访问密码 | 0 | 0 |
1.3 写bank
| Reserved锁定 | EPC锁定 | TID | USER锁定 | |
|---|---|---|---|---|
| 有访问密码 | 1 | 1 | 不可改写 | 1 |
| 无访问密码 | 0 | 0 | 0 |
| Reserved未锁定 | EPC未锁定 | TID | USER未锁定 | |
|---|---|---|---|---|
| 有访问密码 | x | x | 不可改写 | x |
| 无访问密码 | 1 | 1 | 1 |
2. 部分代码块
当使用设备的网口进行连接的时候,Create函数的第一个参数也可能是设备的IP地址,当设备仅有一个天线端口时(例如一体机或者发卡器),Create函数的第三个参数为1,请根据设备的实际天线端口数确定第三个参数的值。
// 实际天线端口设置
int antnum = 1;
rdr = Reader.Create("com3", ModuleTech.Region.NA, antnum);
2.1 锁 EPC bank
在调用LockTag方法锁定存储区域前一定要设置AccessPassword参数,否则操作会失败。初始化标签的访问密码可以通过WriteTagMemWords方法进行操作。
private void btnLockTag_Click(object sender, EventArgs e)
{
TagReadData target = PreTagOp();
if (target == null)
return;
Gen2TagFilter filter = new Gen2TagFilter(target.EPC.Length * 8, target.EPC, MemBank.EPC, 32, false);
try
{
Gen2LockAct[] act = new Gen2LockAct[1];
act[0] = Gen2LockAct.EPC_LOCK;
uint accesspwd = 0x12345678;
rdr.ParamSet("AccessPassword", accesspwd);
rdr.LockTag(filter, new Gen2LockAction(act));
accesspwd = (uint)0;
rdr.ParamSet("AccessPassword", accesspwd);
MessageBox.Show("操作成功");
}
catch (ModuleException mex)
{
MessageBox.Show("操作失败:" + mex.ToString());
return;
}
}
2.2 读 TID bank
private void btnReadTID_Click(object sender, EventArgs e)
{
TagReadData target = PreTagOp();
if (target == null)
return;
Gen2TagFilter filter = new Gen2TagFilter(target.EPC.Length * 8, target.EPC, MemBank.EPC, 32, false);
try
{
ushort[] rdata = rdr.ReadTagMemWords(filter, MemBank.TID, 0, 6);
string readdatastr = "";
for (int i = 0; i < rdata.Length; ++i)
readdatastr += rdata[i].ToString("X4"); // 10进制转16进制 默认补0来凑够位数
Console.WriteLine(readdatastr);
MessageBox.Show("操作成功");
}
catch (ModuleException mex)
{
MessageBox.Show("操作失败:" + mex.ToString());
return;
}
}
2.3 写 EPC bank
2.3.1 访问密码的设置分为两种情况:
- 当所操作区域被锁定时,必须设置和标签一致的访问密码操作才能成功
- 当所操作区域未被锁定时,可以设置访问密码为0,或则不设置访问密码,
读写器默认采用0作为访问密码
private void btnWriteEPC_Click(object sender, EventArgs e)
{
TagReadData target = PreTagOp();
if (target == null)
return;
Gen2TagFilter filter = new Gen2TagFilter(target.EPC.Length * 8, target.EPC, MemBank.EPC, 32, false);
try
{
uint accesspwd = (uint)0;
rdr.ParamSet("AccessPassword", accesspwd);
rdr.WriteTag(filter, new TagData(ByteFormat.FromHex("002433B2DDD9014000000011")));
MessageBox.Show("操作成功");
}
catch (ModuleException mex)
{
MessageBox.Show("操作失败:"+mex.ToString());
return;
}
}
2.4 初始化标签
标签出厂时默认的访问密码都是全0
private void btnInitTag_Click(object sender, EventArgs e)
{
TagReadData target = PreTagOp();
if (target == null)
return;
Gen2TagFilter filter = new Gen2TagFilter(target.EPC.Length * 8, target.EPC, MemBank.EPC, 32, false);
try
{
uint accesspwd = (uint)0;
rdr.ParamSet("AccessPassword", accesspwd);
byte[] wepc = ByteFormat.FromHex("000000000000000000000001");
rdr.WriteTag(filter, new TagData(wepc));
ushort[] killpwd = new ushort[2];
killpwd[0] = 0x8765;
killpwd[1] = 0x4321;
rdr.WriteTagMemWords(filter, MemBank.RESERVED, 0, killpwd);
ushort[] w_accesspwd = new ushort[2];
w_accesspwd[0] = 0x1234;
w_accesspwd[1] = 0x5678;
rdr.WriteTagMemWords(filter, MemBank.RESERVED, 2, w_accesspwd);
Gen2LockAct[] act = new Gen2LockAct[3];
act[0] = Gen2LockAct.ACCESS_LOCK;
act[1] = Gen2LockAct.KILL_LOCK;
act[2] = Gen2LockAct.EPC_LOCK;
accesspwd = 0x12345678;
rdr.ParamSet("AccessPassword", accesspwd);
Gen2TagFilter filter2 = new Gen2TagFilter(wepc.Length * 8, wepc, MemBank.EPC, 32, false);
rdr.LockTag(filter2, new Gen2LockAction(act));
accesspwd = (uint)0;
rdr.ParamSet("AccessPassword", accesspwd);
MessageBox.Show("操作成功");
}
catch (ModuleException mex)
{
MessageBox.Show("操作失败:" + mex.ToString());
return;
}
}
文献参考
RFID EPC Gen2 Memory Bank Layout Including TID, User:
rfid4u.com/rfid-epc-ge…
RFID干货专栏|20 芯片构造、分区、TID: news.rfidworld.com.cn/2022_03/afd…
射频识别技术百度百科:
baike.baidu.com/item/%E5%B0…