RC522 - NFC刷卡模块
芯片介绍/引脚介绍
MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是 NXP 公司针对“三表”应用推出的一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。
非接触式 IC 卡又称射频卡,由 IC 芯片、感应天线组成,封装在一个标准的 PVC 卡片内,芯片及天线无任何外露部分。是世界上最近几年发展起来的一项新技术,它成功的将射频识别技术和 IC 卡技术结合起来,结束了无源(卡中无电源)和免接触这一难题,是电子器件领域的一大突破。卡片在一定距离范围(通常为 5—10cm)靠近读写器表面,通过无线电波的传递来完成数据的读写操作。
其可以由SPI,I2C,UART驱动,本笔记采用较为常用的SPI通信。
关于SPI通信相关内容,详见协议使用笔记SPI章节。
M1卡介绍
M1 卡分为 16 个扇区,每个扇区由 4 块(块 0、块 1、块 2、块 3)组成,(我们也将 16 个扇区的 64 个块按绝对地址编号为 0~63,存贮结构(其它扇区依此类推)如下图所示:
- 注意:由于扇区0用于存放厂商代码,已经固化,不可更改,因此我们不使用该扇区。
M1卡工作原理
读 (Read):读一个块;
写 **(**Write):写一个块;
加(Increment):对数值块进行加值;
减(Decrement):对数值块进行减值;
存储(Restore):将块中的内容存到数据寄存器中;
传输(Transfer):将数据寄存器中的内容写入块中;
中止(Halt):将卡置于暂停工作状态。
- 每个扇区的块 3 为控制块,包括了密码 A、存取控制、密码 B。具体结构如下:
- 每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为 4 个字节,共 32 位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:
块0 | 块1 | 块2 | 块3 |
---|
C1_0 | C1_1 | C1_2 | C1_3 | C2_0 | C2_1 | C2_2 | C2_3 | C3_0 | C3_1 | C3_2 | C3_3 |
三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权限(如进行减值操作必须验证 KEY A,进行加值操作必须验证 KEY B,等等)。三个控制位在存取控制字节中的位置,以块 0 为例:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|
字节6 | | | | C2_0_b | | | | C1_0_b | 字节7 | | | | C1_0 | | | | C3_0_b | 字节8 | | | | C3_0 | | | | C2_0 | 字节9 | | | | | | | | |
其中C2_0_b表示C2_0取反
该四字节整体结构如下:
字节6-9位为上图控制块的存取控制,其中0和4代表块0的存取控制,1和5代表块1的存取控制,依此类推。
| 控制块 | 访问条件 |
C1_X | C2_X | C3_X | Read | Write | Increment | Decrement/Transfer/Restore |
---|
0 | 0 | 0 | A/B | A/B | A/B | A/B | 0 | 1 | 0 | A/B | N | N | N | 1 | 0 | 0 | A/B | B | N | N | 1 | 1 | 0 | A/B | B | B | A/B | 0 | 0 | 1 | A/B | N | N | A/B | 0 | 1 | 1 | B | B | N | N | 1 | 0 | 1 | B | N | N | N | 1 | 1 | 1 | N | N | N | N |
(注意:访问条件中填入的内容表示可访问项,其中 A/B 表示 密码A和密码B,A表示密码A,B表示密码B,N表示都不可访问)
例如:当块 x 的存取控制位 C1_x C2_x C3_x = 0 0 1 时,表示:
? 1、通过密码A或密码B可读取块x中数据,但两个密码都不可写数据
? 2、通过密码A或密码B都不能使块x中数据增加,但两个密码都可以使块x中数据减少、传送和恢复
| 控制块 | 密码A | 存取控制 | 密码B |
C1_3 | C2_3 | C3_3 | Read | Write | Read | Write | Read | Write |
---|
0 | 0 | 0 | N | A/B | A/B | N | A/B | A/B | 0 | 1 | 0 | N | N | A/B | N | A/B | N | 1 | 0 | 0 | N | B | A/B | N | N | B | 1 | 1 | 0 | N | N | A/B | N | N | N | 0 | 0 | 1 | N | A/B | A/B | A/B | A/B | A/B | 0 | 1 | 1 | N | B | A/B | B | N | B | 1 | 0 | 1 | N | N | A/B | B | N | N | 1 | 1 | 1 | N | N | A/B | N | N | N |
(注意:密码A、存取控制、密码B填入读写性质,其中 A/B 表示 密码A和密码B,A表示密码A,B表示密码B,N表示都不可访问)
例如:当块 3 的存取控制位 C1_3 C2_3 C3_3 = 0 0 1 时,表示:
? 1、密码 A:不可读,验证 KEYA 或 KEYB 正确后,可写(更改)
? 2、存取控制:验证 KEYA 或 KEYB 正确后,可读、可写
? 3、密码 B:验证 KEYA 或 KEYB 正确后,可读、可写
数据读写流程
M1 射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为 M1 射频卡,即验证卡片的卡型。
当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。
选择被选中的卡的序列号,并同时返回卡的容量代码。
选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验)
示例代码移植
如无示例代码,可以点此下载。
- 该代码为80C52的示例代码,使用着仅需将引脚设置为自己使用的引脚,调用自己的初始化函数,再解决几个类型不匹配的错误即可使用,移植过程过于简单,此处不再赘述。
示例函数调用说明
部分函数说明
void InitializeSystem(void);
void PcdReset(void);
void PcdAntennaOff(void);
void PcdAntennaOn(void);
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
char PcdAnticoll(unsigned char *pSnr)
char PcdSelect(unsigned char *pSnr)
char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
char PcdWrite(unsigned char addr,unsigned char *pData)
char PcdRead(unsigned char addr,unsigned char *pData)
char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
|