RFID实验报告(防碰撞试验)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验八:防碰撞功能
一、实验目的:
1、理解M1卡的状态转换;理解rf_request用IDLE或ALL模式寻卡的区别;理解rf_halt函数的功能。
2、理解RFID技术的防碰撞处理。
3、设计一个能够同时读取多张M1卡的程序。
二、实验准备:
1、M1卡的状态转换图
2、rf_request函数
int rf_request(HANDLE icdev,unsigned char _Mode,unsigned __int16 *TagType); 功能:寻卡请求
参数:icdev:rf_usbinit()返回的设备描述符
_Mode:U寻卡模式
0 IDLE mode, 只有处在IDLE 状态的卡片才响应读写器的命令。
1 ALL mode, 处在IDLE 状态和HALT 状态的卡片都将响应读写器的命令。
Tagtype:卡类型值,(Mifare std. 1k: 0x0004, UltraLight: 0x0044, FM005:
0x0005,Mifare std. 4k: 0x0002, SHC1122: 0x3300)
返回值: = 0: 成功 <>0: 失败
例: #define IDLE 0x00
int st;
unsigned int *tagtype;
st=rf_request(icdev,IDLE,tagtype);
3、rf_halt函数
int rf_halt(HANDLE icdev);
功能:中止对该卡操作,执行这个指令后,在重新复位之前,不能再对卡进行通讯,除非rf_request()的寻卡模式为ALL。
参数:icdev:rf_usbinit()返回的设备描述符
返回值: =0: 成功 <>0: 失败
例: st=rf_halt(icdev);
三、设计要求:
能够同时读取多个M1卡中某块的内容,并将其显示出来。
四、实验内容:
1、用Microsoft Visual C++新建一个工程(MFC AppWizard[exe]),应用程序类型是基本对话框,应用程序向导创建完成之后,系统进入到对话框编译页面的主页面,用控件设计对话框,对话框的设计如下图所示:
2、编写程序。
(1)、由于本次试验只有一个退出按钮,没有其它按钮,所以需要让定时器在程序启动时就开始工作,我把启动定时器、连接设备和装载密码的代码放在了初始
化程序里面了,代码如下:
BOOL CFpzDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
SetTimer(1,1000,NULL);//定义时钟1,时间间隔为1s
SetTimer(2,5000,NULL);//定义时钟2,时间间隔为5s
icdev=rf_usbinit();//返回的设备描述符
if (icdev>0) //如果设备连接成功。
{
m_list.AddString("设备连接成功!");//在列表框中显示设备连接成功
rf_beep(icdev,50);//控制蜂鸣器,蜂鸣时间50毫秒
unsigned char status[19];
st=rf_get_status(icdev,status);//返回读写器版本信息,长度为18字节
if (st==0) //如果设备连接成功。
{
m_list.AddString((char*)status);//在列表框中显示版本号
}
else
{
m_list.AddString("获取版本号失败!");//在列表框中显示"获取版本号失败!"
}
unsigned char key[6]={0xff,0xff,0xff,0xff,0xff,0xff};
st=rf_load_key(icdev,0,sector,key);/*向读写器装载指定扇区的新密码(不与卡片进行通讯),密码类型为 KEY A */
if(st==0)
{
m_list.AddString("load key right!");//在列表框中显示"load key right!"
}
else
{
m_list.AddString("load key fail!");//在列表框中显示"load key fail!"
}
}
else
{
m_list.AddString("连接失败!");//在列表框中显示"连接失败!"
}
(2)、定时器执行的代码如下:
void CFpzDlg::OnTimer(UINT nIDEvent)
{
switch(nIDEvent)
{
case 1: //1号定时器应该处理的事情
{
unsigned char size;
unsigned long snr;
unsigned __int16 tagtype;
rf_request(icdev,0,&tagtype);//发送寻卡命令
rf_anticoll(icdev,0,&snr);//激活读写器的防冲突队列。
st=rf_select(icdev,snr,&size);//用指定的序列号选择卡片,将卡片的容量返回给PC机。
if (st==0)
{
m_list.AddString("读卡成功!");//在列表框中显示"读卡成功!"
}
else
{
m_list.AddString("读卡失败");//在列表框中显示"读卡失败"
}
st=rf_authentication(icdev,0,sector);//验证1号扇区密码
if (st!=0)
{
m_list.AddString("验证密码失败!");//在列表框中显示"验证密码失败!"
}
else
m_list.AddString("验证密码成功!");//在列表框中显示"验证密码成功!"
unsigned char databuff[17];
ZeroMemory(databuff,17);
st=rf_read(icdev,sector*4,databuff);/*从1扇区0块中读出数据*/
if(st==0)
{
m_list.AddString((char*)databuff);//把读出的数据显示在列表框中
}
rf_halt(icdev);//将读过数据的卡片设为“Halt”模式。
CDialog::OnTimer(nIDEvent);
}
break;
case 2: //2号定时器应该处理的事情
{
m_list.ResetContent();//每隔5s清理一下列表框
}
break;
}
}
五、实验效果.
(1)不放卡时,运行程序显示如下: (2)放四张卡时,运行程序显示如下:
六、实验心得。
通过本次实验,我对读写器的防碰撞过程有了清楚的认识,明白了读写器“同时”读多个卡片的原理。
同时,我明白了rf_card()函数和rf_request()、anticoll()、 select()三个函数之间的关系,以及明白了使用rf_card()函数时,如果模式选择为 0则在对卡进行读写操作完毕后,就会执行rf_halt(),且只能当该卡离开并再次进入操作区域时,读写器才能够再次操作它。