ISO18000-6C协议UHF6C超高频RFID读写C#源码

- UHF6C超高频标签一般分为四个独立的存储区:保留区、EPC区、TID区、用户区;
- 保留区:8个字节,前4个字节为摧毁密码(通常不使用),后4个字节为访问密码(用于写入数据和锁定操作),默认值为:00 00 00 00(摧毁密码)00 00 00 00(访问密码);
- TID区:12字节,只可读不可写,出厂时已写入,为标签的唯一标识符和电子标签的产品类别识别号 ;
- EPC区:用于识别标签对象的电子产品码,EPC与TID不同,用户可手动写入修改。EPC数据结构中,第一个字为校验位,第二个字为长度控制,之后为数据存储位置。在盘点时,根据长度控制位显示EPC长度。实际写入时,起始地址为1,校验位自动计算,无需手动填写 ;
- 用户区:存储长度由各电子标签生产商确定,用户可在此区域写入自定义数据,注意有的标签此区大小为0字节。

本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bNxwiQR&ft=t&id=989384493672
一、函数声明
//外部函数声明:让设备发出声响--------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdbeep", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdbeep(Int32 xms);//xms单位为毫秒 //读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限-----------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号 //获取设备型号----------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdgetdevicemodelandver")]
static extern byte pcdgetdevicemodelandver(byte[] modelstr, byte[] modelstrlen, byte[] deviceverstr);//获取感应模块信息----------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdgetuhfdevinfo")]
static extern byte pcdgetuhfdevinfo(byte infotype,byte[] modelstr, byte[] modelstrlen);//清空EPC缓存-------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2infobufclear")]
static extern byte uhfg2infobufclear();//单次寻卡-----------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2inventory")]
static extern byte uhfg2inventory();//连续寻卡-----------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2inventorystart")]
static extern byte uhfg2inventorystart();//停止连续寻卡-------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2inventorystop")]
static extern byte uhfg2inventorystop();//从读卡器EPC缓存中读出卡号-------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2infobufget")]
static extern byte uhfg2infobufget(byte[] rssi, byte[] pc, byte[] epcbuf);// 预设选卡参数--------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2selectset")]
static extern byte uhfg2selectset(byte target, byte action, byte membank, byte ptr, byte masklen,byte[] mask);// 预设选卡模式---------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2selectmode")]
static extern byte uhfg2selectmode(byte mode);// 读卡----------------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2read")]
static extern byte uhfg2read(byte[] accesspwd, byte membank, byte wordaddr, byte wordlen, byte[] pc, byte[] epcbuf,byte[] piccdata);// 写卡----------------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2write")]
static extern byte uhfg2write(byte[] accesspwd, byte membank, byte wordaddr, byte wordlen, byte[] pc, byte[] epcbuf, byte[] piccdata);//设定或锁定数据区的访问权限-------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2lockuserdata")]
static extern byte uhfg2lockuserdata(byte[] accesspwd, byte rightsflag, byte[] pc, byte[] epcbuf);//设定或锁定TID的访问权限-------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2locktid")]
static extern byte uhfg2locktid(byte[] accesspwd, byte rightsflag, byte[] pc, byte[] epcbuf);//设定或锁定EPC的访问权限-------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2lockepc")]
static extern byte uhfg2lockepc(byte[] accesspwd, byte rightsflag, byte[] pc, byte[] epcbuf);//设定或锁定普通密码的访问权限-----------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2lockaccesspwd")]
static extern byte uhfg2lockaccesspwd(byte[] accesspwd, byte rightsflag, byte[] pc, byte[] epcbuf);//设定或锁定卡销毁密码的访问权限---------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2lockkillpwd")]
static extern byte uhfg2lockkillpwd(byte[] accesspwd, byte rightsflag, byte[] pc, byte[] epcbuf);//卡销毁,无法恢复-----------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2kill")]
static extern byte uhfg2kill(byte[] killpwd, byte[] pc, byte[] epcbuf);//获取 Query------------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2queryget")]
static extern byte uhfg2queryget(byte[] drflag, byte[] mflag, byte[] trext, byte[] sel, byte[] session, byte[] target, byte[] q);//设置 Query------------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2queryset")]
static extern byte uhfg2queryset(byte drflag, byte mflag, byte trext, byte sel, byte session, byte target, byte q);//设置工作地区---------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2regionset")]
static extern byte uhfg2regionset(byte regionindex);//获取信道---------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2channelget")]
static extern byte uhfg2channelget(byte[] chindex);//设置信道---------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2channelset")]
static extern byte uhfg2channelset(byte chindex);//设置跳频---------------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2afhset")]
static extern byte uhfg2afhset(byte isafh);//设置发射连续载波--------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2carrierset")]
static extern byte uhfg2carrierset(byte iscarrier);//获取发射功率--------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2powerget")]
static extern byte uhfg2powerget(byte[] rfpower);//设置发射功率--------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2powerset")]
static extern byte uhfg2powerset(Int32 rfpower);//获取接收解调器参数--------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2demodulatorget")]
static extern byte uhfg2demodulatorget(byte[] mixergindex, byte[] ifgindex, byte[] thrd);//设置接收解调器参数--------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2demodulatorset")]
static extern byte uhfg2demodulatorset(byte mixergindex, byte ifgindex, Int32 thrd);//测试射频输入端阻塞信号----------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2blockingtest")]
static extern byte uhfg2blockingtest(byte[] chindexl, byte[] chindexh,byte[] jmr, byte[] jmrlen );//测试信道 RSSI------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "uhfg2channelrssitest")]
static extern byte uhfg2channelrssitest(byte[] chindexl, byte[] chindexh, byte[] rssi, byte[] rssilen);
二、单次寻卡并返回EPC
private void button3_Click(object sender, EventArgs e)
{listBox1.Items.Clear();textBox3.Text = "";uhfg2infobufclear();byte status = uhfg2inventory();byte[] rssi = new byte[1];byte[] pc = new byte[2];byte[] epcbuf = new byte[12];Double i = 0;Double mw;if (status == 0){do {status = uhfg2infobufget(rssi, pc, epcbuf);if (status == 0 || status == 1){if (rssi[0] < 128){i = rssi[0];}else { i = -1 - (rssi[0] ^ 255); }mw = Math.Pow(10, (i / 10));string dispstr = "RSSI:" + rssi[0].ToString("X02") + " 等于输入信号强度:" + i.ToString() + "dBm(" + string.Format("{0:0.000000000}", mw) + "mW),信号路径损耗补偿值PC:" + pc[1].ToString("X02") + pc[0].ToString("X02") + ",EPC:";string epcstr = "";for (int j = 0; j < 12; j++){epcstr = epcstr + epcbuf[j].ToString("X02") + " ";dispstr = dispstr + epcbuf[j].ToString("X02");}textBox3.Text = dispstr;listBox1.Items.Add(dispstr);if (comboBox4.SelectedIndex == 1) { textBox4.Text = epcstr; }}}while (status==1);MessageBox.Show("寻卡成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{MessageDispInfo(status);}
}
三、连续寻卡并返回EPC
private void button5_Click(object sender, EventArgs e)
{if (button5.Text == "连续寻卡 (用于大量卡同时感应)"){ listBox1.Items.Clear();textBox3.Text = "";uhfg2infobufclear();byte status = uhfg2inventorystart();if (status == 0 || status == 8){button5.Text = "停止连续寻卡"; timer1.Enabled = true;button3.Enabled = false;button6.Enabled = false;button7.Enabled = false;button9.Enabled = false;button10.Enabled = false;button11.Enabled = false;button12.Enabled = false;}}else{timer1.Enabled = false;byte status = uhfg2inventorystop();button5.Text = "连续寻卡 (用于大量卡同时感应)";button3.Enabled = true;button6.Enabled = true;button7.Enabled = true;button9.Enabled = true;button10.Enabled = true;button11.Enabled = true;button12.Enabled = true;}
}private void timer1_Tick(object sender, EventArgs e)
{byte[] rssi = new byte[1];byte[] pc = new byte[2];byte[] epcbuf = new byte[12];byte status;Double i = 0;Double mw;do{System.Windows.Forms.Application.DoEvents();status = uhfg2infobufget(rssi, pc, epcbuf); //从读卡器缓冲中读出卡号if (status == 0 || status == 1){pcdbeep(20);if (rssi[0] < 128){i = rssi[0];}else { i = -1 - (rssi[0] ^ 255); }mw = Math.Pow(10, (i / 10));string dispstr = "RSSI:" + rssi[0].ToString("X02") + " 等于输入信号强度:" + i.ToString() + "dBm(" + string.Format("{0:0.000000000}", mw) + "mW),信号路径损耗补偿值PC:" + pc[1].ToString("X02") + pc[0].ToString("X02") + ",EPC:";string epcstr = "";for (int j = 0; j < 12; j++){epcstr = epcstr + epcbuf[j].ToString("X02");}dispstr = dispstr + epcstr;textBox3.Text = dispstr;bool addlist = true;if (listBox1.Items.Count > 0){for (int j = 0; j < listBox1.Items.Count; j++){string liststr = listBox1.Items[j].ToString().Trim();if (liststr.Substring(liststr.Length - 24, 24) == epcstr){addlist = false;}}}if (addlist) { listBox1.Items.Add(dispstr); }}}while (status == 1);
}
四、读取卡内数据
private void button9_Click(object sender, EventArgs e)
{byte[] accesspwd = new byte[4];if (checkhexstr(textBox5.Text.Trim(), 4, accesspwd) == false){MessageBox.Show("十六进制认证密钥输入错误,请输入 4 字节16进制认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox5.Select();return;}byte wordlen = (byte)numericUpDown_wordlen.Value;if(wordlen>16){MessageBox.Show("长度不能大于16个字!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);numericUpDown_wordlen.Select();return;}byte wordaddr = (byte)numericUpDown_wordaddr.Value;byte[] pc = new byte[2];byte[] epcbuf = new byte[12];byte[] piccdata = new byte[32];byte status = uhfg2read(accesspwd,(byte)comboBox7.SelectedIndex, wordaddr, wordlen, pc, epcbuf, piccdata);if (status == 0 || status == 12 || status == 13){textBox7.Text = pc[1].ToString("X02") + pc[0].ToString("X02");string epcstr = "";for (int j = 0; j < 12; j++) {epcstr = epcstr + epcbuf[j].ToString("X02")+" ";}textBox8.Text = epcstr;if (status == 0) {string datastr = "";for (int j = 0; j < wordlen*2; j++){datastr = datastr + piccdata[j].ToString("X02") + " ";}textBox6.Text = datastr;MessageBox.Show("读卡成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{MessageDispInfo(status);}}else{MessageDispInfo(status);}
}
五、写数据到卡内
private void button10_Click(object sender, EventArgs e)
{byte[] accesspwd = new byte[4];if (checkhexstr(textBox5.Text.Trim(), 4, accesspwd) == false){MessageBox.Show("十六进制认证密钥输入错误,请输入 4 字节16进制认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox5.Select();return;}byte wordlen = (byte)numericUpDown_wordlen.Value;if (wordlen > 16){MessageBox.Show("长度不能大于16个字!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);numericUpDown_wordlen.Select();return;}byte[] piccdata = new byte[32];if (checkhexstr(textBox6.Text.Trim(), wordlen * 2, piccdata) == false){MessageBox.Show("十六进制写入数据输入错误,请输入"+ (wordlen*2).ToString() +" 字节16进制写卡数据!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox6.Select();return;}byte wordaddr = (byte)numericUpDown_wordaddr.Value;byte[] pc = new byte[2];byte[] epcbuf = new byte[12];byte status = uhfg2write(accesspwd, (byte)comboBox7.SelectedIndex, wordaddr, wordlen, pc, epcbuf, piccdata);if (status == 0 || status == 12 || status == 14){textBox7.Text = pc[1].ToString("X02") + pc[0].ToString("X02");string epcstr = "";for (int j = 0; j < 12; j++){epcstr = epcstr + epcbuf[j].ToString("X02") + " ";}textBox8.Text = epcstr;if (status == 0){MessageBox.Show("写卡成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{MessageDispInfo(status);}}else{MessageDispInfo(status);}
}
