开发者学堂课程【嵌入式之 RFID 开发与应用2020版:RFID 选卡操作】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/665/detail/11122
RFID 选卡操作
内容介绍:
一、S50 卡内部结构
二、存储结构
此次需要用到另一个代码,就是对数据块的操作,如果只是一个 ID 卡,获取完卡号就结束了。但是如果是 IC 卡,主要目的是为了往卡片里面存入重要的数据,拿它来存什么东西并不重要,因为它是提供了 1000 个字节的空间,可以拿它来存任何东西。在对卡片进行写入操作之前,先来看一下 S50 卡的内部结构。
一、S50 卡内部结构
1.主要指标
容量为 8K 位 EEPROM
分为 16 个扇区,每个扇区为 4 块,每块 16 个字节,以块为存取单位
每个扇区有独立的一组密码及访问控制
每张卡有唯一序列号,为 32 位
具有防冲突机制,支持多卡操作
无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
数据保存期为 10 年,可改写 10 万次,读无限次
工作温度: -20℃-50℃(湿度为 90%)
工作频率:1 3.56MHZ
通信速率: 106 KBPS
读写距离: 10 cm 以内(与读写器有关)
二、存储结构
1、扇区介绍
M1卡分为 16 个扇区,每个扇区由 4 块((块 0、块 1、块 2、块 3)组成,(也将16 个扇区的 64 个块按绝对地址编号为 0~63,存贮结构如下图所示:
每一块都是连续操作的,它并不是说 0~3 然后有 0~3 然后有 0~3,它是 0~63。,0~63 号因为 16 个扇区每个扇区 4 个块,那么乘起来就是 64 块。
从扇区 0~15,lock 从 0~63,每一个扇区里面都有 4 个块,这4块里面真正用户可以任意读写的是块应该是前三块,即 block0、block1 和 block2。Block3 的部分是不建议用户经常去进行操作的,或者存放用户数据的,因为第三块它是一个权限管理,在里面存放了当前三块的操作权限,比如说管理的密码(A 密码和 B 密码)。然后还有包括存取的权限,就是哪些可以读、哪些可以写,哪些是可读可写、哪些是既可不可读也不可写,就是关于它的权限的管理。还有一点就是每一块都有 16 个字节,它之所以分扇区,其实是可以为每一个扇区设定一个功能,第一个功能于食堂就餐,第二个扇区用于图书馆借书,第三个扇区是用小卖部购物,分区域融资一卡多用。
2.具体操作
第 0 扇区的块 0(即绝对地址 О 块),它用于存放厂商代码,已经固化,不可更改。
每个扇区的块 0、块 1、块 2 为数据块,可用于存贮数据。
数据块可作两种应用:
★用作一般的数据保存,可以进行读、写操作。
★用作数据值,可以进行初始化值、加值、减值、读值操作。
3.密钥
每个扇区的块 3 为控制块,包括了密码 A、存取控制、密码 B。具体结构如下:
A0A1 A2 A3 A4 A5 FF078069 B0B1B2B3B4B5
密码 A(6 字节) 存取控制( 4 字节) 密码 B (6 字节)
一般情况下第 0 个扇区的第 0 块,里面有一些厂商信息,最好不要去操作它,那么可以从第 1 个扇区开始,在读写数据之前必须要做的一件事情就是验证密钥也叫做验证密码,整个的密码的管理并不复杂,不像在网络通信里面用的复杂的 rsa、des 以及 talking、open ccl,包括说公钥私钥等等,这里都用不到。这里的密码就是在电脑里面,如果密码是 6 个 1,那这里写 6 个 1 即可,这 6 个 1 就是密码。
关于密码是否正确,再去输入 6 个 1 进去,会发现输入的是 6 个 1,就是上面的 6个 1,那么密码就对了。中间它没有对密文进行加密存储所以是明文存储的。但是这里的意思也不是铭文存储可以把密码读出来,A 和 B 的密码尤其是 A 密,是任何人都不能读的,即使知道它的密码多少都不可以读,叫做不可见。B 密在满足一定权限的情况下也是可以读出来的,密码一旦设了之后是看不见的就只能修改,不能去看,它由权限决定。
前面的三块属于用户要存取的普通数据,例如卡里面有多少钱、扣了多少钱等等。
4.总结
S50 卡共 64 块,16 个扇区。每个扇区的前三块是用户数据,第 4 块用于保存密码和权限。如果要去修改某个扇区的密码,修改的其实就第 4 个块。如果在没有修改它之前买了一张新卡回来,那应该如何知道里面的密码是多少?所有出厂密码都是6 个 0xff,就表示密码就验证通过。A 密和 B 密都一样,默认控制权限是 ff0780,69 基本上没有用到,权限解锁其实主要就是靠前三个来实现的,这是它的一个默认值。所以在对卡片拿到之后,第 1 步是先要通过密码的认证,密码认证不过,卡是不让读写的,会出现读写失败,这就是实现的权限管理。所以去刷卡的时候,如果读卡器不知道的卡片的密码,刷卡就会失败。
unsigned char type[2] ,ret,card_ id[4];int i,ops;
int snr = 3;unsigned char b_ data[16],block = 0;
unsigned char a_ key[6] = {0xff,0xff,0xff , 0xff,0xff ,0xff};
rfid_ reset();
rfid_ carda_ init( ) ;
while(1){
ret = rfid_ carda request(PICC_ REQALL, type) ;
if(ret ==OK){
printf("card type = ex%02x%02x\n",type[0], type[1]);
//WaitCard0ff( );
}else continue;
ret = rfid_ _anticoll(card_ id);
if(ret == OK){
printf("card ID:");
for(i=0;i<4;i++)
printf("0x%02x ",card_ _id[i]);
puts("");
/ /WaitCard0ff();
有关代码里面读写数据之前的操作,包括了复位、初始化、寻卡、获取卡号,选卡以及密码的验证。选卡的过程其实就是当有多张卡的时候,必须要指定某一张卡进行操作,那么选卡需要用到的就是之前读出来的卡的 ID,所以这也就是为什么卡里面一定要有一个唯一的 ID,而且一定是唯一,不唯一的话个一个 ID 堆两张卡,这两张卡就被同时修改了。选卡的过程基本上就是最后一步了,处于 ready 状态同时已经得到它的卡号,那就可以进行选卡。
当把卡选中的时候,这张卡在处于一个激活状态,也就可以对卡进行各项操作,包括读写,但是读写之前必须要进行密码认证。选卡很简单,就是把卡号给它就可以,卡号存在将要发送给卡片的缓存区里面,缓冲区一共有 7 个字节,卡号占了 4个字节。前两个字节是命令和参数。第一个是命令,第二个是参数,中间的 4 个字节就是卡号。
ucComMF522Buf[0] = PICC_ _ANTICOLL1;
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i=0; i<4; i++)
{
ucComMF522Buf[i+2] = *(pSnr+i)E
ucComMF522Buf[6]^= *(pSnr+i)i|
}
CalulateCRC( ucComMF 522Buf ,7, &ucComMF 522Buf[7]);
第 7 个字节把所有的卡号做了易货运算,并存在了最后一个字节里面。易货完成之后还要做 crc,crc 就是官方给出的一个建议的代码。自己也可以写一个产生 crc 的函数,但是尽量不要自己去产生,最好把的数据通过 pcd 阅读器来产生,这样就更可靠一些,产生一个 16 的 crc。
crcr 是单独放到了最后,跌了 8 个字节的缓冲,但是实际上最后在发送的时候,也是发送了 9 个字节。把整个的数据从命令、参数、卡号、易货,还有包括的 crc 全部放到 buffer 里面。然后通过 rfid_cmd 传输给卡片。
status = rfid_ cmd(PCD_ _TRANSCEIVE, ucComMF 522Buf ,9, ucComMF522Buf , &unLen) ;
if ( (status
== CMD_ SUCCESS) && (unLen == 0x18))
{ status = CMD_ SUCCESS; }
else
{ status = CMD_ _FAIL; }
传过去之后,如果返回的是一个成功,那表示卡就被选定。当卡被选定的时候,才可以对卡进行密码的认证和数据的读写以及充值等等操作,有关密码的认证。