RC500系列C51开发指南.docx
《RC500系列C51开发指南.docx》由会员分享,可在线阅读,更多相关《RC500系列C51开发指南.docx(24页珍藏版)》请在冰豆网上搜索。
RC500系列C51开发指南
RC500系列
MIFARE系列射频卡
C51开发指南
2002/01/10
版本1.1
目录
简介
第一章电子钱包两种存储形式的转换
第二章常用常量定义
第三章开发指南
第四章模块命令集
简介
本手册介绍了RC500系列MIFARE模块的接口命令,以及与其有关的常量定义和基本概念,并对每个命令给出了C51语言描述的调用示例。
本手册主要应用于将RC500系列模块嵌入到用户自己的主系统中,并用户系统由C51语言编写调试。
请详细参阅我们提供的C51语言编写的DEMO应用程序,相信对你的工作有所帮助。
请参阅《RC500系列MIFARE开发指南》。
一、标准通信命令
为方便用户开发,请用户尽量使用我们在DEMO目录中提供的标准通信函数Mf_sendcmd(),此命令已经过我们完整的测试。
用户只需了解此函数的入口、出口参数即可。
此函数采用全局数组write_buff存放入口、出口参数,用户亦可以按照自身的
实际要求,修改此函数。
调用格式:
unsignedcharcmd;
unsignedcharlength;
/*对cmd赋值*/
/*对length赋值*/
/*对write_buff赋值*/
unsignedcharstatus=Mf_sendcmd(cmd,length)
/*处理status以及出口参数write_buff*/
参数:
write_buff:
命令块数组,系统默认的参数传入、传出数组cmd:
是发给模块的命令码
length:
是命令块长度
返回状态:
参见“错误代码表”
MI_OK:
命令执行正确
MI_ERR:
命令执行错误
描述:
此命令用来与模块通讯。
调用前必须设置命令代码和命令块长度。
如是入口参数,则从write_buff数组传入(参见示例a.)
如是出口参数,则从write_buff数组取出(参见示例b.)
示例:
a.模块设备的控制(传入参数的情况)
unsignedcharstatus;
write_buff[0]=REDLED|BELL;
write_buff[1]=10;
write_buff[2]=20;
write_buff[3]=3;
status=Mf_sendcmd(ALARM,4);
说明:
灯控命令,命令码是ALARM,命令块长度是4,4个参数存放于
write_buff数组中,无回传参数
b.读取模块号(传出参数的情况)
unsignedcharstatus;
unsignedcharMcmNo;
status=Mf_sendcmd(MCMNO,0);
McmNo=write_buff[0];
说明:
读取模块号命令,命令码是MCMNO,命令块长度是0,有一个回传参数
第一章电子钱包两种存储形式的转换
Mifare1卡中电子钱包是一个LONG型数据,在内存中占用4字节。
在C51中这两种数据类型转换如下:
[1]数组转换到长整型
unsignedlonglongvalue;
unsignedcharvalue[4];
longvalue=0;
for(unsignedchari=0;i<4;i++)
{
longvalue+=value[i]<<(8*i);
}
[2]长整型转换到数组
unsignedlonglongvalue;
unsignedcharvalue[4];
longvalue=0x10203040;
for(unsignedchari=0;i<4;i++)
{
value[i]=(unsignedchar)(longvalue>>(8*i));
}
第二章常用常量定义
本指南预定义了几组用户需要用到的常量,定义如下:
2.1设备号定义#defineREDLED1#defineGREENLED2#defineBELL4
2.2呼叫方式定义#defineIDLE0#defineALL1
2.3命令返回码定义#defineMI_OK0
#defineMI_ERR1
2.4密码常量定义#defineKEYA0/*密码A*/#defineKEYB4/*密码B*/
2.5通信方式设置#defineRS2321#defineLDSTD0
2.6命令代码定义(CommandCode)#defineCONNECT0x00#defineMCMVER0x22#defineALARM0x7A
#defineMCMNO0xA1
#defineTRANSKEY0xA4
#defineAUTHMODE0xA9
#defineGETTYPE0xAA
#defineGETSNR0xAB
#defineREADBLOCK0xAC
#defineWRITEBLOCK0xAD
#defineWRITEKEY0xAE
#defineREADVALUE0xAF
#defineWRITEVALUE0xB0
#defineINCREMENTVALUE0xB1
#defineDECREMENTVALUE0xB2
#defineLOADKEY0xB4
#defineREQUEST0xB5
#defineANTICOLL0xB6
#defineSELECT0xB7
#defineAUTHENTICATION0xB8
#defineREAD0xB9
#defineWRTIE0xBA
#defineINCREMENT0xBB
#defineDECREMENT0xBC
#defineHALT0xBD
第三章开发指南
RC500系统模块提供了两组操作命令用于用户的开发工作:
高级指令和基础指令。
基础指令提供了RC500系列MIFARE读写器最基本的指令,适用于有特殊要求和极高
安全要求的用户。
使用基础指令开发难度较大,且需要对MIFARE射频卡有较深入的了解。
高级指令是为方便用户操作,将基础指令集成,提供了相对强大的功能,用高级指令集开发系统,开发速度快,总的执行时间短,易于用户维护。
常见的用户数据有两种:
通用数据和钱包数据。
通用数据指用户存放的文本数据、二进制数据,模块高级指令中提供的读写通用数据
的命令有两条:
READBLOCK(读),WRITEBLOCK(写)。
钱包数据是一个长整形数据(M1卡)或整形数据(ML10卡)。
对M1卡,模块高级
指令中提供了4条操作命令:
READVALUE(读),WRITEVALUE(写),INCREMENTVALUE(加),DECREMENTVALUE(减);对ML10卡,模块高级指令中
提供了3提供了3条操作命令:
READVALUE(读)、WRITEVALUE(写)、DECREMENTVALUE(减)。
在M1卡中,每个BLOCK都可以存放通用数据或钱包数据,但要注意的是在一个BLOCK中必须使用WRITEVALUE命令后,才能作为一个钱包数据进行加减读操作。
否则,会发生错误。
在ML10卡中,有两个专门的BLOCK存放钱包数据,其他BLOCK不能存放钱包数
据,操作钱包数据时不需传递钱包数据的地址(BLOCK号),在不需要钱包数据时,存放
钱包数据的BLOCK可以存放普通的数据。
利用高级指令开发应用系统时,对卡的操作请遵循以下的顺序:
1.加载密码
在系统上电后,如果每张卡的密码都一样,则只要向系统传递一次密码即可
系统采用M1卡时,可以有两个密码加载命令,TRANSKEY、LOADKEY。
建议使用
TRANSKEY。
对ML10卡,则只能使用LOADKEY命令传递密码。
参见以下《命令集》
2.系统可以通过GETTYPE命令来判定是否有卡进入操作区
当GETTYPE命令正确返回时,说明有卡进入操作区。
GETTYPE命令返回卡的类型
根据卡的不同类型,用户执行相应的操作。
3.读卡序列号(GETSNR)
GETSNR命令返回卡的序列号,用户应当保存卡的序列号,以作为读/写/加/减命令的参数。
4.读、写数据块,读、写、加、减电子钱包,修改密码
采用高级指令进行操作,模块在一个时刻只能处理一张卡,当有多张卡同时进入模
块的操作区时,模块不能有效处理每一张卡。
在需要同时处理多张卡时,应该采用基础指令集进行操作。
在对卡进行写、加、减操作时,模块都会返回该BLOCK当前的数值。
模块对M1卡和ML10卡的操作命令相同,但参数和参数的含义在某些命令中会有一些区别。
用户应当注意这些区别。
第四章模块的命令集
4.1通用命令
通用命令是一组对模块识别、测试、和声光控制的指令,共有四条这些命令适用于本公司生产的所有智能卡读写模块。
4.1.1模块设备的操作功能说明:
此命令用来控制模块所提供的三个基本设备:
红色LED,绿色LED,
蜂鸣器。
可以控制三个设备的打开时间、关闭时间、动作次数以及动作方式。
命令字:
ALARM调用示例:
unsignedcharmode;unsignedcharactiontime;unsignedcharintervaltime;unsignedcharcount;write_buff[0]=mode;write_buff[1]=actiontime;
write_buff[2]=intervaltime;
write_buff[3]=count;
unsignedcharstatus=Mf_sendcmd(ALARM,4);
参数:
mode:
设备号
是三个设备:
REDLED、GREENLED、BELL的或集
例如:
mode=REDLED|BELL
actiontime:
单次动作时间(设备打开时间)
单位是10ms
例如:
actiontime=15,则单次动作时间为15*10ms
intervaltime:
动作间歇时间(设备关闭时间)
单位是10ms
例如:
intervaltime=15,则动作间歇为15*10ms
count:
:
连续动作次数(设备打开次数)
返回值:
MI_OK,MI_ERR;
4.1.2联结功能说明:
此命令用来测试主系统与模块的连接是否正确
命令字:
CONNECT调用示例:
unsignedcharstatus=Mf_sendcmd(CONNECT,0);参数:
无返回值:
MI_OK,MI_ERR;
4.1.3读取模块号功能说明:
此命令用来读取模块的设备号。
命令字:
MCMNO
调用示例:
unsignedcharmcmno;
status=Mf_sendcmd(MCMNO,0);
mcmno=write_buff[0];
参数:
mcmno:
模块返回的模块代码mcmno=17170模块mcmno=20200模块mcmno=50500模块mcmno=70TEMIC模块
mcmno=90MEMORY模块
返回值:
MI_OK,MI_ERR;
4.1.4读取模块控制软件版本号功能说明:
此命令读取模块中的控制软件的版本号,如:
mcmver=“VER1.00A”命令字:
MCMVER调用示例:
unsignedcharmcmver[8];unsignedcharstatus=Mf_sendcmd(MCMVER,0);for(unsignedchari=0;i<8;i++){mcmver[i]=write_buff[i];
}
参数:
mcmver:
模块的控制软件版本号
返回值:
MI_OK,MI_ERR;
4.2高级指令高级指令是相对于基础指令集而言,高级指令集成了基础指令的功能,简化了模块的应用。
4.2.1密码认证方式功能说明:
此命令指定密码认证的方式,本命令仅适应于ML10。
命令字:
AUTHMODE调用示例:
unsignedcharmode;
write_buff[0]=mode;
unsignedcharstatus=Mf_sendcmd(AUTHMODE,1);
参数:
mode:
密码认证的方式
0:
用密码A认证
1:
用密码B认证
返回值:
MI_OK,MI_ERR;
4.2.2密码加载功能说明:
此命令将一个新密码加载到指定扇区此命令用于单密码系统,即每个扇区只用一组密码进行认证(密码B=密码A)。
命令字:
TRANSKEY调用示例:
unsignedcharsector;unsignedcharmima[6];
write_buff[0]=sector;
for(unsignedchari=0;i<6;i++)
{
write_buff[1+i]=mima[i];
}
unsignedcharstatus=Mf_sendcmd(TRANSKEY,7);
参数:
sector:
要加载密码的扇区的扇区号
mima[6]:
要加载的密码
返回值:
MI_OK,MI_ERR;
4.2.3读卡类型功能说明:
此命令用于检测卡并检测卡类型
命令字:
GETTYPE调用示例:
unsignedintcardtype;unsignedcharstatus=Mf_sendcmd(GETTYPE,0);
cardtype=write_buff[0];
cardtype+=write_buff[1]<<8;
参数:
cardtype:
卡类型
cardtype=0x0004Mifare1卡
cardtype=0x0010MifareLight10卡
返回值:
MI_OK,MI_ERR;
4.2.4读卡序列号
功能说明:
此命令读取卡的序列号,此序列号将在读/写命令中用作参数
命令字:
GETSNR
调用示例:
unsignedcharsnr[4];
status=Mf_sendcmd(GETSNR,0)
for(unsignedchari=0;i<4;i++)
{
snr[i]=write_buff[i];
}
参数:
snr[4]:
卡片序列号
返回值:
MI_OK,MI_ERR;
4.2.5读数据块
功能说明:
此命令从指定卡的指定数据块读出数据,
读数据块前必须先读出卡序列号,存放于snr中。
命令字:
READBLOCK
调用示例:
(ForM1卡)
unsignedcharBlockNo;
externunsignedcharsnr[4];
unsignedchardat[16];
write_buff[0]=BlockNo;
for(i=0;i<4;i++)
{
write_buff[1+i]=snr[i]
}
unsignedcharstatus=Mf_sendcmd(READBLOCK,5);
for(i=0;i<16;i++){dat[i]=write_buff[i];}调用示例(ForML10卡):
unsignedcharBlockNo;
externunsignedcharsnr[4];
unsignedchardat[4];
write_buff[0]=BlockNo;
for(i=0;i<4;i++)
{
write_buff[1+i]=snr[i]
}
unsignedcharstatus=Mf_sendcmd(READBLOCK,5);
for(i=0;i<4;i++){dat[i]=write_buff[i];}参数:
BlockNo:
“数据块”的地址snr[4]:
卡序列号。
通过GETSNR命令得到
dat[16]:
返回的16字节数据
返回值:
MI_OK,MI_ERR;
4.2.6写数据块
功能说明:
此命令将16字节(M1卡)或4字节(ML10卡)数据写入指定卡的指定数据块
中,如果写入成功,系统回读写入的数据。
写数据块前必须先读出卡序列号,存放于snr中
命令字:
WRITEBLOCK
返回值:
MI_OK,MI_ERR;
调用示例:
(ForM1卡)
unsignedcharBlockNo;
externunsignedcharsnr[4];
unsignedcharindata[16];
unsignedcharoutdata[16];
write_buff[0]=BlockNo;
for(unsignedchari=0;i<4;i++)
{
write_buff[1+i]=snr[i]
}
for(i=0;i<16;i++){write_buff[5+i]=indata[i];
}
unsignedcharstatus=Mf_sendcmd(READBLOCK,21);
for(i=0;i<16;i++){outdata[i]=write_buff[i];}参数:
BlockNo:
“数据块”的地址
snr[4]:
卡序列号。
通过GETSNR命令得到
indata[16]:
要写入的16字节数据
outdata[16]:
回读的16字节数据
调用示例:
(ForML10卡)
unsignedcharBlockNo;
externunsignedcharsnr[4];
unsignedcharindata[4];
unsignedcharoutdata[4];
write_buff[0]=BlockNo;
for(unsignedchari=0;i<4;i++)
{
write_buff[1+i]=snr[i]
}
for(i=0;i<4;i++){write_buff[5+i]=indata[i];
}
unsignedcharstatus=Mf_sendcmd(READBLOCK,9);
for(i=0;i<4;i++){outdata[i]=write_buff[i];}参数:
BlockNo:
“数据块”的地址
MifareLight中可以修改的BlockNo有
2,3,4,5,6,7,8,9,10,11
Block4,5常用作16位的“电子钱包”
Block6,7是密码A(6字节)和存取状态码(1字
节)以及存取状态码的反码(1字节)Block8,9是
密码B(6字节)和存取状态码(1字节)以及存取状
态码的反码(1字节)
snr[4]:
卡序列号。
通过GETSNR命令得到
indata[4]:
要写入的4字节数据
outdata[4]:
回读的4字节数据
4.2.7修改卡片密码
功能说明:
此命令将新密码写到指定扇区。
写密码前必须先读出卡序列号,存放于snr中。
此命令用于单密码系统
命令字:
WRITEKEY
返回值:
MI_OK,MI_ERR;
调用示例:
(ForM1卡)
unsignedcharsector;
unsignedcharmima[6];
write_buff[0]=sector;
for(unsignedchari=0;i<4;i++)
{
write_buff[1+i]=snr[i];
}
for(i=0;i<6;i++)
{
write_buff[5+i]=mima[i];
}
unsignedcharstatus=Mf_sendcmd(WRITEKEY,11);
参数:
sector:
指定扇区号
mima[6]:
6字节新密码
调用示例:
(ForML10卡)
unsignedcharkeyset;
unsignedcharmima[6];
unsignedcharkeyctr;
keyctr=D1WREN|D1RDEN|D2WREN|D2RDEN|KEYRWEN|VALUEWREN;
sector=0;
write_buff[0]=keyset;
for(unsignedchari=0;i<4;i++)
{
write_buff[1+i]=snr[i];
}
for(i=0;i<6;i++)
{
write_buff[5+i]=mima[i];
}
write_buff[11]=keyctr;
unsignedcharstatus=Mf_sendcmd(WRITEKEY,12);
参数:
keyset:
0修改密码A,1修改密码B
如果采用“高级指令”集操作,只有修改密码A有效
keyctr:
密码控制状态代码
密码控制状态代码是对密码权限的描述
密码控制状态代码有以下的权限:
D1WREN对“数据块”2,3可写
D1RDEN对“数据块”2,3可读
D2WREN对“数据块”10,11可写
D2RDEN对“数据块”10,11可读
KEYWREN对密码可写
VALUEWREN对16位“电子钱包”可写
有以下特殊情况:
1.密码永远不能读
2.对“电子钱包”一直可读(任意一组密码认证后)
3.对“电子钱包”一直可减(任意一组密码认证后)
mima[6]:
6字节新密码
4.2.8读电子钱包功能说明:
此命令从指定“电子钱包”读出当前“金额”。
命令字:
READVALUE
调用示例:
(ForM1卡)
unsignedcharsnr[4];unsignedcharBlockNo;unsignedcharcurvalue[4];BlockNo=4;
write_buff[0]=BlockNo;for(i=0;i<4;i++){
write_buff[1+i]=snr[i];
}
unsignedcharstatus=Mf_sendcmd(READVALUE,5);
for(i=0;i<4;i++){curvalue[i]=write_buff[i];}参数:
snr[4]:
要操作的卡的卡序列号BlockNo:
“电子钱包”的地址
curvalue[4]:
“电子钱包”当前的“金额”
返回值:
MI_OK,MI_ERR;
调用示例:
(ForML10