RFID_RC522例程分析+学习笔记 在学习
RFID_RC522时花了很长时间,期间搜集了很多的例程、资料和帖子,总感觉有点散,现今将其按照我的方式整理如下
如有错误,还望指正。1.首先先来说MF_RC522非接触式(最大通信速率13.56MHz)读写卡芯片。 MF_RC522能干什么? MF_RC522的内部发送器部分可驱动读写器天线与ISO 14443A/MIFARE卡和应答机的通信。ISO 14443A/MIFARE卡是什么? 即支持ISO 14443A通信协议的MIFARE卡(如RFID_RC522模块附带的M1卡)。 注释如下: ISO
是国际化标准组织。IEC是国际电工委员会。ISO/IEC 14443
协议是非接触式IC标准协议。这种协议又可分为TYPE A和TYPE B两个标准,具体可以参考ISO/IEC 14443协议浅谈:TYPE A和TYPE B。https://blog.csdn.net/luoqindong/article/details/54705862。在这里ISO/IEC14443A==ISO14443A
。换个方式说MF_RC522
读写卡芯片符合ISO/IEC14443A 通信协议,ISO/IEC14443A协议支持MIFARE S50、S70、UltraLight、MIFARE Pro、FM11RF08等兼容卡片。说道这里再说一下非接触式IC卡的国际标准:
显然我们所用的M1
卡就属于PICC,属于近耦合型的,作用距离在0~100mm(与读卡器有关),RC522读写器就是PCD。 单片机怎样驱动MF_RC522?MF_RC522
支持的主机接口类型有串行UART、I2C、SPI,常见的RFID_RC522
模块都是SPI(
串行外设接口)的,在使用时需要注意SPI接口的速率不能超过10bit/s。2.非接触式IC卡在刚开始学习时看别人的例程或帖子时会看见Mifare_One
卡、S50卡、M1_S50卡在这里我们统称为M1卡。M1卡的核心是飞利浦的下属子公司恩智浦出品的Mifare 1 IC S50系列微模块,毫无疑问它确定了卡片的特性以及卡片读写器的诸多性能。M1 IC S50内建有高速的CMOSEEPROM、MCU等。卡片上除了IC微晶片及一副高效率的天线外,无任何其他元器件,卡片上无源(无任何电池),可以打开手电筒紧贴在卡的背面,观看卡的前面。读写器怎么和无源的非接触式IC卡通信?读写器(例如MF_RC522
)向 M1 卡发一组固定频率的电磁波,卡片内有一个 LC 串联谐振电路,其频率与读写器发射的频率相同,在电磁波的激励下,LC 谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到 2V 时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。 例程分析:底层驱动代码是店家给的例程,经过了解后发现所有的RC522
代码几乎一样。给的例程是用IO口模拟的,因为STM32自带有SPI外设,所以程序稍微改动就好。这里只对函数的调用进行分析,具体寄存器的操作,个人没有完全搞懂。将STM32F103ZET6
的SPI2工作在主模式下,波特率不大于10Mbps。因为SPI2挂载在APB1下所以输入时钟为36MHz,所以波特率预分频值不小于4。MISO和MOIS上传输字节时都是高位在前,空闲态时钟为低电平,在时钟上升沿同步接收和发送数据,在下降沿数据转换。RST复位端低电平复位。
了解M1卡与读写器的通讯流程:MF_RC522
初始化—寻卡—防冲突—选卡—对要操作的块所在的扇区进行密码验证—操作卡(读、写、加值、减值、转移、恢复)。
如果想做一个简单的门禁控制读卡器,前三步就够了,能够实现对M1卡的UID读取和防冲突功能。再深入一点就是用于一卡通系统的读卡设备和发卡设备。实现对卡内EEPROM中的数据进行读、写、加值、减值、转移、恢复高层操作。
1.RC522初始化
对卡进行操作时,主要用到两类命令:
PICC是接近式卡。PCD是接近式耦合设备。
在通信过程中实际上是使用PCD命令控制RC522发出PICC命令与卡进行交互。
2.寻卡函数
需要输入寻卡方式和一个用于存放卡片类型代码的数组,寻卡成功后,函数返回MI_OK
(0)并将返回两字节的卡片类型数据放入数组。即卡的类型=(pTagType[0]<<8)|pTagType[1];
寻卡的命令有两个分别是上图Mifare_One
卡片命令字 (M1卡)的前两个。3.防冲突函数 如果有多张Mifare 1
卡片处在读写器的天线的工作范围之内时,防冲功能启用时,读写器会根据卡片的序列号来选定一张卡片。被选中的卡片将直接与读写器进行数据交换,未被选择的卡片处于等待状态,准备与读写器进行通信。
调用此函数需要输入一个4字节的用来存放卡片序列号数组。成功后函数返回MI_OK
,并将得到的序列号放进数组。4.选卡函数
调用此函数需要卡片的序列号,选卡成功后返回MI_OK。
到此为止我们就将M1
的卡片序列号(ID)读出来了。下面就是对卡片内部的EEPROM操作的函数了,在此之前先来了解卡片的存储器组织结构和读写控制。M1卡的主要指标: 1
容量为 8K 位 EEPROM 2
分为 16 个扇区,每个扇区为4块,每块16个字节,以块为存取单位 3
每个扇区有独立的一组密码及访问控制 4
每张卡有唯一序列号,为32 位,没有重复的两张Mifare卡 5
具有防冲突机制,支持多卡操作 6
工作频率:13.56MHZ 7
通信速率:106KBPS 8
读写距离:10cm以内(与读写器有关) M1卡中的EEPROM的存储结构与访问权限: M1卡中集成了1024个字节的EEPROM,这1024个字节分成了16个扇区,每个扇区有4个块,每个块都有16个字节。 M1
卡中的这64个块在访问的时候是按绝对地址(块0)来操作的,即块地址=
扇区编号×4+扇区内的块编号,其中扇区编号是0~15,扇区内的块编号是0~3。所有扇区的第3
块都是控制块,第0个扇区中的第0块是存放产品代码的,这个块是64个块中唯一一个只能读不能写的块,存放的是固化在其中的32bit的世界唯一的卡片序列号。其余15个扇区的第0块到第2块都是数据块。
控制块包含了存取数据所需要的KeyA
(密码A)可选的KeyB(密码B)以及本扇区内四个块的存储条件,当不需要KeyB时,这个块的最后6个字节可以被当做数据字节来使用。M1卡出厂控制块默认值(初始值)为下图所示:
每个扇区的密码和存取控制都是独立的,可以根据实际需求设定各自的密码以及存取控制。存取控制为四个字节,共32
位,扇区中的每个块(包括数据块和控制块)的存取条件是有密码和存取控制共同决定的,中在存取控制的每个块都有相应的三个控制位,定义如下: 块0
:C10 C20 C30 块1
:C11 C21 C31 块2
:C12 C22 C32 块3
:C13 C23 C33 例如:C1
(该块的第几个控制位)0(块),块0的三位控制位中的第1位。 三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权。
存取控制(4
字节,其中字节9为备用字节)结构如下所示:
从图上可以看出:
块0
三位存取控制位分别为 C10 C20 C30=0 0 0。反码位C10_b C20_b C30_b=1 1 1将反码取反得到0、0、0,继续向下看。
由刚才得到的块0
的3位存取控制位的值可以看出,知道KeyA或KeyB验证成功后就可以对块0进行读、写、加值、减值、转移、恢复操作。在这里要说的是,对于一个新卡来说KeyA和KeyB都是默认的(FF FF FF FF FF FF),并且所有的数据块的三位存取控制位都是000。 需要注意的是,这里的存取条件查询表只适合数据块,而控制块的存取条件如下图:
如果keyB
可以读取,那么KeyB的空间就会用于存储数据,不能用来进行验证(这个地方自己去体会,想用KEYB就要修改KEYB的存储控制位),因为此时所有的进一步的存储区存取操作都将失败。一张新卡也不能用KeyB来验证(厂家设置的存取条件为001)。此外还有一个需要注意的地方就是,所有的控制块都禁止加值、减值、转移、恢复操作。
控制块的三位存取控制位的初始值为C13 C23 C33=0 0 1
。结合上表可知 密码A
:不可读,验证KeyA或KeyB正确后,可写(更改)。 存取控制:验证KeyA
或KeyB正确后,可写可读。 密码B
:验证KeyA或KeyB正确后,可写可读。
    图片14        
   密码验证模式有两种:
    图片15       
   新卡的话每个扇区的控制块都是初始值,密码A和密码B都是6个0xFF 。如果是被人用过的卡那可能个别扇区被修改了密码,不过16个扇区一般也不会都用。至于那几个扇区没有用,就需要自己用初始密码去试。
   调用该函数需要选择密码验证是KEYA还是KEYB,然后输入你要操作的块地址,存放密码数组和存放卡片序列号的数组。验证成功后就可以对该块所在的扇区内所有的块进行操作了(读、写、加值、减值、转移、恢复)。
6.读/写函数
   图片16 、17         
   这两个函数非常简单,输入要读/写的块地址和用来存放或写入数据的16个字节的数组。读/写成功后返回MI_OK。
   在这里要注意:
  控制块的存取控制的那4个字节中规定了KEYA不能被读取,所以当你用KEYA6个0xFF读控制块的时候,读出KEYA是6个0x00。
  读/取都是按块(16个Byte)操作的。
  先读后写,防止把其他不需要改动的位给修改了。当用写函数修改密码A的时候注意记住修改后的密码。
  块0是不可写的。
数据块的两种应用:
  A用作读/写快:只能用来读取和写入普通的16个Byte的数据。
  B用作数值块:用于电子钱包功能(读、写、加值、减值、转移和恢复)。
  当用M1卡作为电子钱包时,要将某个块按规定初始化为数值块。
  如下图所示,0~3字节为数值(可以理解为多少钱),0字节是数值的最低字节。4~7字节是数值的取反值,8~9字节还是数值,12字节为地址,13字节地址反值,14、15就不说了。
      图片18
初始数值块是用写命令把数据写到块的,例如我把第1块初始化为值块,数值为0,用写块命令写入
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0xfe,0x01,0xfe。
然后可以用DECREMENT(减值)、 INCREMENT(加值)、TRANSFER(转移)、 RESTORE(恢复)命令对数值块进行操作了。
需要注意的是在执行加值/减值前面要将数值读出,计算加减后是否超处理数据有效范围,如小于0等。超出直接return;
6.扣款(减值)/充值(加值)函数
     图片19 、20
 该函数可以对已将初始化好的数值块进行减值和加值操作,例如我们要对刚才初始成数值块的块1进行加值(加1)操作。我们第一个参数选择PICC_INCREMENT,地址输入0x01,加1的话即为0x00000001,我们新建一个4Byte的数组,使其最低字节为0x01。然后传入该数组,成功后返回MI_OK,然后我们再读块1后数据就会变成
 0x01,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x01,0xfe,0x01,0xfe。
 有了此功能我们在用M1卡作为电子钱包时会方便很多。不用再自己去读、改、写等麻烦的操作了。
7.M1卡备份钱包函数
   图片20、21
  该函数里面使用了TRANSFER(转移)、RESTORE(恢复)命令字。
调用该函数可以将数值块备份到同一扇区内的另一个块,被备份的必须是数值块,普通数据块不可以备份。例如将数值块1备份数据块2,数据块就可以。
到此结束。 烟台汽车工程职业学院 王承飞 QQ858777845
最后在这里我列出我学习和整理资料时参考的链接:
https://blog.csdn.net/a827415225/article/details/51898897
//CSDN MFRC522应用详解
http://www.docin.com/p-906980594.html
//豆丁网基于非接触式IC卡的读卡器的设计与开发
https://wenku.baidu.com/view/4d5b2ceb680203d8cf2f241b.html
//MFRC522中文资料 周立功
https://blog.csdn.net/u012246376/article/details/53843946
//RFID MFRC522综述
https://blog.csdn.net/smilestone_322/article/details/49721903
//Mifare 卡之电子钱包
一周热门 更多>