GACRF500系列非接触式IC卡读写器使用手册.doc
第一章 GAC-RF500非接触式读写器简介1.1 概述 深圳市捷安凯科技有限公司是以开发IC卡终端设备和应用系统软件,智能控制、安防、射频识别系统为主导产品的高科技公司,GAC-RF500系列非接触式IC卡读写器是以Philips RC500为核心研制而成的非接触卡读写设备,完全内置天线,通过串口同PC机的连接,设备功能齐全、性能稳定,随机提供丰富的接口函数库,支持访问射频卡的全部功能,可满足用户二次开发的需要。目前该设备已广泛地应用于门禁、考勤、会员卡管理系统及高速公路、油站、停车场、公交、三表、餐饮等收费发卡系统中。主要特点:1、 采用了PHILIPS 最新的高度集成ISO1443A读卡芯片MF RC500,支持Mifare M1S50、M1S70、Mifare Light、Mifare UltraLight、Mifare Pro、Mifare DESFire、SHC1102卡的完全操作。2、 高速访问射频卡,通信速率为 106Kbit/s -424Kbit/s,数据加密和双向验证。3、 使用方便,通过RS232总线与PC机连接,波特率1200-115200自动侦测。4、 提供丰富的PC机接口函数库和演示程序,常用开发工具下详细的函数调用例程,可使二次开发变得轻而易举。5、 提供8位数码管显示、蜂鸣器和发光二级管指示。6、 提供了丰富的二次开发平台和范例。7、提供对其它厂商开发的函数库的支持。技术指标:1、支持MIFARE标准(ISO1443A)-发射频率:13.56MHz-访问卡速率:106Kbit/s - 424 Kbit/s2、接口功能:RS232口,波特率1200-115200自动侦测。3、 工作电源:DC5V ±5,500mA。4、 读写距离:0-80mm5、最大功耗:<1W6、环境温度:0507、相对湿度:30%95%8、重量:约 200克1.2 装箱单 GAC-RF500读写器 1台5V稳压直流电源 1个RS232通讯数据线(交叉线) 1条 配套软件CDROM盘 1张(根据需要提供)说明书(电子文档) 1本(根据需要提供)1.3 连接方式将RS232数据线的任意一端连接到计算机背后串行通讯端口,另一端插入读写器背后的接口中。1.4 用户软件 用户软件包括三个部分:演示软件、二次开发动态库、应用范例。、演示软件:提供了对PHILIPS公司的Mifare S50、S70、ML、UltraLight、MifarePRO/DESFIRE卡的读写,数值块初始化,加减,复位等卡片操作,以及对读写器的蜂鸣控制,密码下载。、二次开发动态库:提供了在WINDOWS 32位环境下动态库,可以在WIN98、WIN2000、WINNT、WIN_XP下用VC、Delphi、VB、VF、BP等常用开发工具调用,完全屏蔽烦琐的非接触式IC卡的底层通讯协议和操作。、应用范例:随盘提供了VB6、PB8、VFP3、VC6、BC+Builder等开发环境下的应用范例。、提供对其它厂商开发的函数库的支持,可以使用明华公司的非接触IC卡读写器库函数直接操作本设备。第二章、演示软件2.1 软件安装 运行随机提供的软件光盘中RF500文件夹中的setup.exe文件,根据提示选择安装目录即可完成完整,完成后将在您的桌面上添加一个名称为RF500Demo的图标。2.2 设备操作 端口设置:可选串口14,通讯速率为 1200115200 BPS。读写器在通讯成功后,如要更换串口或波特率,请先断开连接,然后选择新的串口和波特率再重新连接即可,如果连接失败,请关掉读写器电源再打开。产品信息:软件版本号、硬件版本号和产品序列号,进入系统后,自动显示演示软件版本号,并在连接成功后,读出硬件版本号和产品序列号。蜂鸣器控制:读写器按输入值鸣响,以10毫秒为计时单位,最大鸣响时间为2.55秒,最小响时间为10毫秒。显示方式控制:显示方式分为计算机控制和读写器控制两种。由计算机控制时,控制数据中每个字节的最高位(b7)取值决定该位数字后的小数点是否显示,第4位(b3b2b1b0)表示显示的内容,取值范围:0-9。在显示内容输入数据后,必须按“刷新”按钮才能在读写器上显示。由读写器控制时,显示模式又分为日期模式和时间模式。日期显示格式为“年-月-日”,时间显示格式为“时-分-秒”。数码管的显示亮度可调节,有效范围为015,0表示最暗,15表示最亮。自动卡型测试:通过寻卡的应答数据,判断卡片的类型,此功能谨供用户参考。操作界面如图1:(图1)2.3 密码操作 该功能将密码写入读写器的射频控制芯片的非易失安全存储区中,读写器断电后该密码将继续保存,该安全存储区为只写,不能通过任何手段读出。每台读写器可存放16套密码,每套密码由A密码和B密码组成。M1 S50卡有16个扇区,每个扇区均有独立的A、B密码控制,可用读写器中存放16套密码进行安全认证。M1 S50卡有40个扇区,对于前16个扇区,可用M1 S50卡的认证方式,对于大于16的扇区,必须重新装载密码。ML卡ML只有一套密码,在装载时必须使用扇区0进行下载。TOKEN卡,只有1个4字节的密码,在装载时必须通过扇区0进行下载,需要特别注意的是,TOKEN卡的密码不是直接装入射频控制芯片的安全存储区中,它只保存在读写器的RAM中,读写器断电后该密码将丢失。在进行密码操作时,可以单击菜单“密码操作”-> “从文件中装入密码”,将原来存储在文件中的密码数据读入操作界面中修改,单击菜单“下载密码”可以将密码下载到读写器中,也可以保存到文件中。注意:演示系统中的密码文件是采用二进制方式存放,未进行任何加密处理。(图2)2.4 数据操作 M1卡每次读出4个扇区的内容(如图3),如有不能读出的块,则提示“部分扇区不能读取”,且相应扇区不显示任何内容;能读出的扇区,以十六进制显示卡中数据。如果选择M1 S70的后8(32-39)扇区,则每次只能操作1个扇区,16块(如图4)。(图3)(图4)对于控制块采用密码A、控制字、密码B3段显示。如果要修改卡片的数据,请先修改用户界面上的数据,修改后的数据块用红色醒目显示,然后按下<写入>,将用户输入的数据写入卡中,写入成功后数据块恢复黑色显示。ML卡UltraLight卡和Token(SHC1102)卡,按下<读出>按钮将读出卡中所有单元的数据(如图5),如果要修改数据,直接在界面上修改,然后按下<写入>。 (图5)2.5 数值操作 M1卡的数据块可以通过可初始化值操作成为数值块,数值块采用特殊的数据结构保存,可以进行读值、初始化值、减值、加值操作。数值的有效值范围:4字节有符号整数。ML卡的第4、5块为数值块,可进行读值、初始化值、减值操作。数值的有效值范围:2字节无符号整数。操作如图6:(图6)2.6 读写测试将射频卡放在天线有效范围内,指定读/写地址,点击<执行操作>,如果选择了循环测试,则系统对该卡进行连续的读/写操作,直至用户点取<终止操作>按钮为止。否则系统只对卡进行一次操作。测试中系统同时将每个操作步骤调用的函数、操作结果及读出/写入的数据显示在列表框中。系统提供了对M1、ML、SHC1102、UltraLight卡的测试,在进行写测试时,建议不要对控制块、OTP配置区进行操作,这样容易造成卡片永久损坏。(图7)2.7 命令操作命令操作主要对Mifare PRO/DESFire进行操作,这两种卡上为CPU卡,对其操作要根据COS命令进行,操作流程如下:寻卡(request)à防冲突(anticoll)à选卡(select)à ATS à PPS à àHALT、RESET按照操作流程依序单击相应按钮。其中,PPS为指令传输,对于/DESFire,还增加了密码认证演示,如图8:DES/3DES加解密操作,作为工具提供。Cos指令执行、指令执行状态:在指令栏输入 要执行的cos指令,然后单击执行按钮执行指令,指令执行状态在执行结果列表中显示。可以单击清除按钮清除指令编辑框和指令执行列表中的数据。(图8)2.8 菜单和工具栏菜单提供了演示软件的全部功能操作,同时,通过工具栏(如图9),可以非常方便的使用常用操作,可以非常方便的切换不同卡型和操作扇区。(图9)第三章、非接触IC卡读写器库函数3.1 设备操作函数 int rf_init(int port,long baud=9600);功 能:初始化通讯端口参 数:port:串口通讯端口号 baud:串口通讯波特率,支持1200 115200,默认值为9600;返 回:成功则返回设备操作句柄int rf_exit(int icdev);功 能: 关闭通讯端口参 数:icdev:rf_init()返回的设备操作句柄返 回:成功则返回 0int rf_reset(int icdev,unsigned int _Msec);功 能:射频读写模块复位参 数:icdev:通讯设备标识符 unsigned int _Msec:复位时间,0500毫秒有效返 回:成功则返回 0 例:int st; st=rf_reset(icdev,60);int rf_beep(int icdev,unsigned int _Msec);功 能:蜂鸣参 数:icdev:通讯设备标识符 unsigned int _Msec:蜂鸣时限,单位是10毫秒返 回:成功则返回 0 例:int st; st=rf_beep(icdev,10); /*鸣叫100毫秒*/int rf_get_status(int icdev,unsigned char *_Status);功 能:取得读写器硬件版本号,如“GR05080001”参 数:icdev:通讯设备标识符 _Status:返回读写器硬件版本信息返 回:成功则返回 0 例:int st; unsigned char version16; st=rf_get_status(icdev,version);int rf_srd_snr(int icdev,int length,unsigned char *rec_buffer);功 能:取得读写器产品序列号参 数:icdev:通讯设备标识符 length:字符串长度,其值为16 rec_buffer:存放要读出的序列号字符串返 回:成功则返回 0 例:st=rf_srd_snr(icdev,16,buffer);int lib_ver(unsigned char *buff);功 能:读取软件版本号,与读写器无通讯参 数:buff:存放版本号的缓冲区返 回:成功则返回 0 例:unsigned char buffer12;st=lib_ver(buff);int rf_ctl_mode(int icdev,unsigned char mode);功 能:设置读写器数码管受控方式,关机后可保存设置值参 数:icdev:通讯设备标识符 mode:受控方式 0 数码管显示受计算机控制1 数码管显示受读写器控制(出厂设置) 显示模式由rf_disp_mode设置返 回:成功则返回 0 例:st=rf_ctl_mode(icdev,0x01)int rf_disp_mode(int icdev,unsigned char mode);功 能:设置读写器数码管显示模式,关机后可保存设置值参 数:icdev:通讯设备标识符 mode:显示模式0 日期,格式为“年-月-日(yy-mm-dd)”,BCD码1 时间,格式为“时-分-秒(hh-nn-ss)” ,BCD码返 回:成功则返回 0 例:st=rf_disp_mode(icdev,0x01);/设为显示时间int rf_disp8(int icdev,int disp_len,unsigned char *disp_str);功 能:在读写器数码管上显示数字参 数:icdev:通讯设备标识符 disp_len:显示字符串的长度,最长为8 disp_str:要显示的数据受读写器控制时,显示的日期/时间请参照rf_disp_mode()中定义的格式;受计算机控制时,显示方式由显示数据决定;每个字节的最高位为1表示本位数后的小数点亮,为0表示小数点灭。返 回:成功则返回 0 例:int st; unsigned char *datebuff=“99-05-20”; unsigned char *numbuff1=0x01,0x02,0x03,0x04,0x85,0x06,0x07,0x08; unsigned char *numbuff2=0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81; st=rf_ctl_mode(icdev,1); /显示受读写器控制 st=rf_disp_mode(icdev,0);/显示日期 st=rf_disp8(icdev,8,datebuff);/显示结果为“99-05-20” st=rf_ctl_mode(icdev,0); /显示受计算机控制 st=rf_disp8(icdev,8,numbuff1); /显示结果为“1234.5678” st=rf_disp8(icdev,8,numbuff2); /显示结果为“8.7.6.5.4.3.2.1.”int rf_gettime(int icdev,unsigned char *time);功 能:读取读写器日期、星期、时间参 数:icdev:通讯设备标识符 time:返回数据,长度为7个字节,格式为“年、星期、月、日、时、分、秒”返 回:成功则返回 0 例:int st; unsigned char datetime7; st=rf_gettime(icdev,datetime); /datetime为“0x99,0x04,0x05,0x20,0x13,0x30,0x10”, /表示99年星期四5月20日13时30分10秒int rf_gettimehex(int icdev,char *time);功 能:同rf_gettime()rf_gettime,用十六进制表示参 数:icdev:通讯设备标识符 time:长度为14个字节,均为数字返 回:成功则返回 0 例:int st; unsigned char datetime15; st=rf_gettime(icdev,datetime); /datetime为“99040520133010”, /表示99年星期四5月20日13时30分10秒int rf_setbright(int icdev,unsigned char bright);功 能:设置数码管显示亮度参 数:icdev:通讯设备标识符 bright:亮度值,015有效,0表示最暗,15表示最亮返 回:成功则返回 0 例:st=rf_setbright(icdev,10);int rf_settime(int icdev,unsigned char *time);功 能:设置读写器日期、星期、时间参 数:icdev:通讯设备标识符 time:长度为7个字节,格式为“年、星期、月、日、时、分、秒”返 回:成功则返回 0 例:int st; unsigned char datetime7=0x99,0x04,0x05,0x20,0x13,0x30,0x10; st=rf_settime(icdev,datetime);int rf_settimehex(int icdev,char *time);功 能:同rf_settime()rf_settime,用十六进制表示参 数:icdev:通讯设备标识符 time:长度为14个字节,均为数字返 回:成功则返回 0 例:int st; unsigned char *datetime=“99040520133010”; st=rf_settime(icdev,datetime); int rf_srd_eeprom(int icdev,int offset,int length,unsigned char *rec_buffer);功 能:读取读写器备注信息参 数:icdev:通讯设备标识符 offset:偏移地址(0383) length:读取信息长度(1384) rec_buffer:读取到的信息返 回:成功则返回 0 例:int st; unsigned char buffer100; st=rf_srd_eeprom(icdev,0,100,buffer);int rf_swr_eeprom(int icdev,int offset,int length,unsigned char* send_buffer);功 能:向读写器备注区中写入信息参 数:icdev:通讯设备标识符 offset:偏移地址(0383) length:读取信息长度(1384) rec_buffer:要写入的信息返 回:成功则返回 0 例:st=rf_swr_eeprom(icdev,10,”mwrf v3.0”);3.2 通用函数 int rf_request(int icdev,unsigned char _Mode,unsigned int *TagType);功 能:寻卡请求参 数:icdev:通讯设备标识符 _Mode:寻卡模式 Tagtype:卡类型值0x0004 M1 S50卡, 0x0012 M1 S70卡 0x0010 ML卡, 0x3300 华虹SHC1102卡 0x0008 MFPRO, 0x0044 MUL返 回:成功则返回 0 例: #define IDLE 0 int st; unsigned int tagtype2; st=rf_request(icdev,IDLE,tagtype);int rf_anticoll(int icdev,unsigned char _Bcnt,unsigned long *_Snr);功 能:防止卡冲突,返回卡的序列号参 数:icdev:通讯设备标识符 _Bcnt:预选卡所用的位数,标准值为0(不考虑序列号) _Snr:返回的卡序列号地址返 回:成功则返回 0 例:int st; unsigned long snr; st=rf_anticoll(icdev,0,&snr); 注:request指令之后应立即调用anticoll,除非卡的序列号已知。int rf_select(int icdev,unsigned long _Snr,unsigned char *_Size);功 能:从多个卡中选取一个给定序列号的卡参 数:icdev:通讯设备标识符 _Snr:卡序列号 _Size:指向返回的卡容量的数据返 回:成功则返回 0 例:int st; unsigned long snr=239474; unsigned char size4; st=rf_select(icdev,snr,size);int rf_load_key(int icdev,unsigned char _Mode,unsigned char _SecNr,unsigned char *_NKey);功 能:将密码装入读写模块RAM中参 数:icdev:通讯设备标识符 _Mode:装入密码模式,同密码验证模式 _SecNr:扇区号(015) _Nkey:写入读写器中的卡密码返 回:成功则返回 0 例:/key A and key B unsigned char tk6=0xa0,0xa1,0xa2,0xa3,0xa4,0xa5; /* 装入1扇区的0套A密码 */ if(rf_load_key(icdev,0,1,tk)!=0) printf("Load key error!"); rf_exit(icdev); int rf_load_key_hex(int icdev,unsigned char _Mode,unsigned char _SecNr,char *_NKey);功 能:向读写器中装入十六进制密码参 数:icdev:通讯设备标识符 _Mode:密码验证模式 _SecNr:扇区号(015) _Nkey:写入读写器中的卡密码返 回:成功则返回 0 例:/* 装入1扇区的A密码|0套 */ if(rf_load_key_Hex(icdev,0,1,"a0a1a2a3a4a5")!=0) printf("Load key error!"); rf_exit(icdev); exit(1); int rf_halt(int icdev);功 能:中止卡操作参 数:icdev:通讯设备标识符返 回:成功则返回0 例:st=rf_halt(icdev);int rf_read(int icdev,unsigned char _Adr,unsigned char *_Data);功 能:读取卡中数据 一次读一个块的数据,为16个字节; 参 数:icdev:通讯设备标识符 _Adr:M1S50卡块地址(063); M1S70 卡页地址(0255) _Data:读出数据返 回:成功则返回 0 例:int st; unsigned char data16; st=rf_read(icdev,4,data); /读M1卡块4的数据int rf_read_hex(int icdev,usigned char _Adr,unsigned char *_Data);功 能:同rf_read()rf_read参 数:icdev:通讯设备标识符 _Adr:同rf_read _Data:读出数据,数据以十六进制形式表示返 回:成功则返回0; 例:int st; unsigned char data32; st=rf_read_hex(icdev,2,data); / 读ML卡2页和3页的数据或M1卡的第二块数据。int rf_write(int icdev,unsingned char _Adr,unsigned char *_Data);功 能:向卡中写入数据 一次必须写一个块,为16个字节;参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Data:要写入的数据返 回:成功则返回0 例:int st; unsigned char data16=“1234567890123456” st=rf_write(icdev,4,data); /写M1卡块4的数据int rf_write_hex(int icdev,unsigned char _Adr,unsigned char *_Data)功 能:同rf_write()rf_write参 数:icdev:通讯设备标识符 _Adr:同rf_write _Data:要写入的数据返 回:成功则返回 0 例:int st; unsigned char write_buf33=" ffffffffffffffffffffffffffffffff" st=rf_write_hex(icdev,4,write_buf);3.3 M1卡专用操作函数 int rf_authentication(int icdev,char _Mode, char _SecNr);功 能:密码认证,用存储在读写器硬件中的密码认证指定的扇区参 数:icdev:通讯设备标识符 _Mode:装入密码模式,同密码验证模式 _SecNr:扇区号(015)返 回:成功则返回 0 例: /* 校验1扇区的A密码 */ if(rf_load_key(icdev,0,1)!=0) printf(" key error!"); rf_exit(icdev); int rf_authentication_2(int icdev,unsigned char _Mode, unsigned char KeyNr,unsigned char Adr);功 能:验证某一扇区密码参 数:icdev:通讯设备标识符 _Mode:密码验证模式_KeyNr:密码扇区号(015)Adr: 要验证的块地址返 回:成功则返回 0 例:int st; st=rf_authentication_2(icdev,0,0,128); 注:卡上每个扇区有A密码和B密码,可根据实际需要确定是否使用B密码,这由该扇区的存取控制位来决定。可用rf_load_key()来分别装入,只有装入后才能使用验证密码函数验证。主要用于验证扇区号大于15的扇区。int rf_initval(int icdev,unsigned char _Adr,unsigned long _Value);功 能:初始化块值参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Value:初始值返 回:成功则返回 0例:int st;unsigned long value;value=1000; /* 给value赋值*/st=rf_initval(icdev,1,value); /*将块1的值初始化为1000*/注:要对某一块进行读、减、加的操作,该块必须是值的格式,即曾使用初始化值的函数。int rf_increment(int icdev,unsigned char _Adr,unsigned long _Value);功 能:块加值参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Value:要增加的值返 回:成功则返回 0;例:int st;unsigned long value;value=10;st=rf_increment(icdev,1,value); /*将块1的值增加value*/int rf_decrement(int icdev,unsigned char _Adr,unsigned long _Value);功 能:块减值参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Value:要减的值返 回:成功则返回 0例:int st;unsigned long value;value=10;st=rf_decrement(icdev,1,value); /*将块1的值减少value*/int rf_readval(int icdev,unsigned char _Adr,unsigned long *_Value);功 能:读块值参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Value:读出值的地址返 回:成功则返回 0例:int st;unsigned long value;st=rf_readval(icdev,1,&value); /*读出块1的值,放入value*/int rf_restore(int icdev,unsigned char _Adr);功 能:回传函数,将EEPROM中的内容传入卡的内部寄存器参 数:icdev:通讯设备标识符 _Adr:要进行回传的块地址M1 S50卡块地址(163) M1 S70卡页地址(1255)返 回:成功返回0例:int st;st=rf_restore(icdev,1);注:用此函数将某一块(经rf_initval()函数初始化后)中的数值传入内部寄存器,然后用rf_transfer()函数将寄存器中数据再传送到另一块中去,实现块与块之间数值传送。rf_transfer函数仅在increment、decrement和restore命令之后调用int rf_transfer(int icdev,unsigned char _Adr);功 能:传送,将寄存器的内容传送到EEPROM中参 数:icdev:通讯设备标识符 _Adr:要传送的地址M1 S50卡块地址(163) M1 S70卡块地址(1255)返 回:成功返回0例:int st;st=rf_transfer(icdev,1);注:见rf_restore()的说明。3.4 M1卡高级函数 高级函数为几个低级函数的组合。int rf_card(int icdev,unsigned char _Mode,unsigned long *_Snr);功 能:寻卡,能返回在工作区域内某张卡的序列号,等同于rf_request()、rf_anticoll()、rf_select()三个函数的组合;参 数:icdev:通讯设备标识符 _Mode:寻卡模式mode_card _Snr:返回的卡序列号返 回:成功则返回 0 例:int st; unsigned long snr; st=rf_card(icdev,0,&snr); 注:选择IDLE模式,在对卡进行读写操作,执行rf_halt()rf_halt指令中止卡操作后,只有当该卡离开并再次进入操作区时,读写器才能够再次对它进行操作。int rf_HL_increment(int icdev,unsigned char _Adr,unsigned long _Value);功 能:块加值,并回写到原位,相当于执行rf_increment( )和rf_transfer( )两个函数。参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _Value:要增加的值返 回:成功则返回 0;例:int st;unsigned long value;value=10; st=rf_ HL_increment(icdev,1,value); /*将块1的值增加value,并回写*/int rf_HL_decrement(int icdev,unsigned char _Adr,unsigned long _Value);功 能:高级减值操作,块加值,并回写到原位,相当于执行rf_decrement ( )和rf_transfer( )两个函数。参 数:icdev:通讯设备标识符 _Adr:M1 S50卡块地址(163) M1 S70卡页地址(1255) _