> 文章列表 > NFC 学习笔记 3 MFRC522读写器1

NFC 学习笔记 3 MFRC522读写器1

NFC 学习笔记 3 MFRC522读写器1

MFRC522 简介

	`MFRC522`(Contactless Reader IC for 13.56 MHz with SPI Interface)是一款高度集成的13.56MHz射频识别读卡器芯片,由NXP Semiconductors公司设计和生产。该芯片支持ISO/IEC 14443A和MIFARE通信协议,可以读写、加密和解密多种传统射频卡和接触式智能卡。MFRC522芯片集成了调制解调器、解密器、发射天线、接收天线等基础电路,同时还具有SPI接口、中断输出和定时器等功能,方便与微处理器或其他外围设备集成。由于其功能强大、易于使用和应用广泛,MFRC522芯片被广泛应用于物联网、门禁控制、智能家居、物流管理、人员考勤等地方。

数据手册

arduino平台源码

在学习该模块之前,需要准备arduino Uno开发板+MFRC522模块。
fork github源码:https://github.com/461911662/rfid

demo学习

1.ChangeUID

描述:如何在可更改 UID 的 MIFARE 卡上设置 UID。
主要流程:

1.初始化arduino uno串口、MFRC522实例、提供新的UID
2.找卡
3.读当前卡的UID
4.设置新的UID
5.挂起PICC设备为IDLE和HALT状态
6.再次重复2-3步骤(重新激活卡),读取卡UID检验是否写成功

关键函数:

MFRC522 mfrc522(SS_PIN, RST_PIN)
// SS_PIN: 用于arduino在使用spi发送数据时,通知MFRC522的片选信号
// RST_PIN:用于arduino检测MFRC522是否上电
mfrc522.PCD_Init();
// 硬复位MFRC522模块,并设置对应的通信参数
// 设置TxControlReg打开天线
mfrc522.PICC_IsNewCardPresent() 
// 初始化MFRC522 TXRX寄存器为默认值(与NFC论坛规定速率一直106KBps)
// 以及设置默认的调制宽度。
// 通过SPI发送寻卡命令,寻卡命令格式:
// req: PICC_CMD_REQA			= 0x26
// resp: byte1、byte2
//  byte1:bit7保留
//         bit6表示SAK[1],防冲撞0:不支持,1:支持
//         bit5表示SAK[0],应答0:已经应答,1:需要选卡
//         bit0-4表示UID size,卡片UID支持的长度
//  byte2:用于区分不同的卡片类型,M卡为0x0。
mfrc522.PICC_ReadCardSerial()
// 读卡过程分为寻卡和选卡两个步骤
// 通讯协议如下:
//	Byte 0: SEL 可选的命令:PICC_CMD_SEL_CL1, PICC_CMD_SEL_CL2 or PICC_CMD_SEL_CL3
//	Byte 1: NVB	表示当前有效的bits位
//	Byte 2: UID-data or CT	表示UID<=4:UID,否则是级联PICC_CMD_CT				= 0x88
//	Byte 3: UID-data  表示UID
//	Byte 4: UID-data  表示UID
//	Byte 5: UID-data  表示UID
//	Byte 6: BCC	表示2-5的异或值
//	Byte 7: CRC_A 表示CRC低地址
//	Byte 8: CRC_A 表示CRC高地址
// 通讯示例:
//  UID size	Cascade level	Byte2	Byte3	Byte4	Byte5
//  ========	=============	=====	=====	=====	=====
//   4 bytes		1			uid0	uid1	uid2	uid3
//   7 bytes		1			CT		uid0	uid1	uid2
//  				2			uid3	uid4	uid5	uid6
//  10 bytes		1			CT		uid0	uid1	uid2
//  				2			CT		uid3	uid4	uid5
//  				3			uid6	uid7	uid8	uid9
// 1.寻卡命令格式:
// req: 
//  byte1:PICC_CMD_SEL_CL1		= 0x93
//  byte2:0x20 表示有32位有效的bit
// resp:
//  byte1: UID1
//  byte2: UID2
//  byte3: UID3
//  byte4: UID4 可能返回更多字符这个与所读的卡片有关
// 2.选卡命令格式(假设UID长度为4):
// req:
//  byte1:PICC_CMD_SEL_CL1		= 0x93
//  byte2:0x70 表示有0x70位有效的bit
//  byte3:UID1
//  byte4:UID2
//  byte5:UID3
//  byte6: UID4
//  byte7:UID1^UID2^UID3^UID4
//  byte8:Low CRC
//  byte9: High CRC
// resp:
//  byte1:SAK(Select Acknowledge)
//  byte2: Low CRCA
//  byte3:High CRCA
// SAK格式如下:
//  Bit 0(LSB):表示标签是否支持 ISO/IEC 14443-4 协议,如果支持则为 1,否则为 0。 
//  Bit 1:保留,未使用。 
//  Bit 2:Cascade 标志位,表示 UID 是否完整。 
//  Bit 3-7:表示标签的类型和版本信息,具体取值由不同的标签类型定义。
//  例如 MIFARE Classic 标签的 Bit 3-4 表示标签容量,Bit 5 表示加密类型等等。 
mfrc522.MIFARE_SetUid(newUid, (byte)4, true) 
// 设置UID的步骤大致有:
//  1.对block0进行鉴权
//  2.读取block0的内容
//  3.将旧的UID替换成新的UID,并更新BCC(Block Character Check)
//  4.关闭鉴权。
//  5.激活卡的后门功能,将新的block内容写到block0中去。
// 鉴权PICC卡片的命令格式:
// req:
//  byte1:PICC_CMD_MF_AUTH_KEY_A	= 0x60
//  byte2:blockAddr,M1有64个block
//  byte3:keyA1/keyB1
//  byte4:keyA2/keyB2
//  byte5:keyA3/keyB3
//  byte6:keyA4/keyB4
//  byte7:keyA5/keyB5
//  byte8:keyA6/keyB6
//  byte9-byte12:UID1-UID4
// resp:NA
// 读取PICC卡片的命令格式:
// req:
//  byte1:PICC_CMD_MF_READ		= 0x30
//  byte2:blockAddr,M1有64个block
//  byte3:Low CRCA
//  byte4:High CRCA
// resp:
//  byte1-byte16:1block为16字节
//  byte17-byte18:CRCA
// 写PICC卡片的命令分两部分:写命令+写数据
// 格式如下:
// 1.写命令
// req:
//  byte1:PICC_CMD_MF_WRITE		= 0xA0
//  byte2:blockAddr,M1有64个block
//  byte3-byte4:CRCA
// resp:
//  byte1:MF_ACK					= 0xA bit0-3
// 2.写数据
// req:
//  byte1-byte16:需要写的数据
PCD_StopCrypto1() 
// 清除当前的鉴权状态
mfrc522.PICC_DumpToSerial(&(mfrc522.uid))
// 打印的内容如下:
// 1.卡片UID
// 2.卡片SAK码
// 3.卡片类型
// 4.卡片扇区内容
2.DumpInfo

描述:展示使用MFRC522读取PICC里面的数据内容。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.读取PCD模块的版本信息
4.寻卡+选卡
5.打印选择的卡片数据信息

关键函数:

mfrc522.PCD_DumpVersionToSerial()
//1.打印PCD的版本信息
mfrc522.PICC_DumpToSerial(&(mfrc522.uid))
//1.打印PICC的数据内容
3.firmware_check

描述:这个例子测试你的 MFRC522 读卡器模块的固件,只有已知版本才能被检查。如果测试通过,并不意味着你的模块是完美无缺的!某些模块可能存在损坏的天线或者损坏的 PICC(Proximity Integrated Circuit Card)。
主要流程:

1.查看PCD估计版本呢
2.对MFRC522的PCD进行自测试

4.FixBrickedUID

描述:这个示例展示了如何修改一个损坏了的可更改 UID 的 MIFARE 卡片,针对可修改的卡片来说可以修改0扇区。
主要流程:

1.激活卡的后门功能
2.通过写命令直接清除0扇区的block

5.MifareClassicValueBlock

描述:这个示例展示了如何在 MIFARE Classic PICC(=卡片/标签)上设置数据块在处于“值块”模式:在这种模式下可以使用增量/减量、存储和传输等操作。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.找卡、选卡
4.使用keyA(0xFF、0xFF、0xFF、0xFF、0xFF、0xFF),认证操作的block。
5.设置M卡的控制位,将对应的block设置为value block。
6.对指定的value block进行增量加、增量减、存储、传输等操作。
7.打印对应block,检查value block是否被修改。
8.挂起PICC、并清除PCD的鉴权信息。

关键函数:

mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3)
// 通过4个block的权限转换成字节流。
// 这些字节流主要是用来构成控制块(block3)的关键字节
status = mfrc522.MIFARE_Increment(valueBlockA, 1)
// 增量加:对指定的block加1
// 增量加操作分为2个命令
// 发送增量命令
// req:
//  byte1:PICC_CMD_MF_INCREMENT	= 0xC1
//  byte2:value blockAddr,M1有64个block
//  byte3-byte4:CRCA
// resp:NA
// 发送增量值命令
// req:
//  byte1:value&0xFF
//  byte2:(value>>8)&&0xFF
//  byte3:(value>>16)&&0xFF
//  byte4:(value>>24)&&0xFF
//  byte5-byte6:CRCA
// resp:NA
status = mfrc522.MIFARE_Transfer(valueBlockA)
// 传输:将PICC内部bufer中的数据保存到value block中
// 发送传输命令
// req:
// byte1:PICC_CMD_MF_TRANSFER	= 0xB0
// byte2:value blockAddr,M1有64个block
// byte3-byte4:CRCA
// resp:NA
status = mfrc522.MIFARE_GetValue(valueBlockA, &value)
// 获取value block的值
// 与读取PICC卡片的命令格式相同,前4个字节位value值
// *value = (int32_t(buffer[3])<<24)
//        | (int32_t(buffer[2])<<16) 
//        | (int32_t(buffer[1])<<8) 
//        | int32_t(buffer[0])
status = mfrc522.MIFARE_SetValue(valueBlockB, 255)
// 设置value block的值,方法同写PICC卡片的命令
// 如下是value block的协议规则:
// Translate the int32_t into 4 bytes; repeated 2x in value block
//  buffer[0] = buffer[ 8] = (value & 0xFF);
//  buffer[1] = buffer[ 9] = (value & 0xFF00) >> 8;
//  buffer[2] = buffer[10] = (value & 0xFF0000) >> 16;
//  buffer[3] = buffer[11] = (value & 0xFF000000) >> 24;
// Inverse 4 bytes also found in value block
//  buffer[4] = ~buffer[0];
//  buffer[5] = ~buffer[1];
//  buffer[6] = ~buffer[2];
//  buffer[7] = ~buffer[3];
// Address 2x with inverse address 2x
//  buffer[12] = buffer[14] = blockAddr;
//  buffer[13] = buffer[15] = ~blockAddr;
status = mfrc522.MIFARE_Decrement(valueBlockB, 10);
// 增量减:对指定的block加10
// 增量减操作分为2个命令
// 发送增量命令
// req:
//  byte1:PICC_CMD_MF_DECREMENT	= 0xC0
//  byte2:value blockAddr,M1有64个block
//  byte3-byte4:CRCA
// resp:NA
// 发送增量值命令
// req:
//  byte1:value&0xFF
//  byte2:(value>>8)&&0xFF
//  byte3:(value>>16)&&0xFF
//  byte4:(value>>24)&&0xFF
//  byte5-byte6:CRCA
// resp:NA
6.MinimalInterrupt

描述:使用中断读取 MIFARE Classic PICC 的 UID。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.获取PCD固件版本
4.设置MFRC522的IRQ pin脚为输入上拉模式
5.使能PCD的rx中断
6.注册终端处理函数
7.清除1次终端状态
8.循环中寻找卡,触发中断进入中断处理函数,去选择卡片,读卡信息

7.Ntag216_AUTH
8.ReadAndWrite

描述:展示如何读写PICC模块。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.寻卡
4.读卡
5.使用KeyA鉴权卡的指定block
6.读取该block
7.使用KeyB鉴权卡的指定block
8.读写取该block
9.挂起PICC、并清除PCD的鉴权信息。

9.ReadNUID

描述:循环读取PICC模块UID。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.寻卡
4.读卡,将卡保存在内存中
5.循环检测新卡

10.ReadUidMultiReader

描述:连续多次从PICC 中读取UID。
主要流程:

与ReadNUID类似

11.rfid_default_keys

描述:从默认的工厂key中找到对应的key。
主要流程:

循环使用默认key,进行鉴权,鉴权成功即找到了对应的key

12.rfid_read_personal_data

描述:对第1和第2个扇区进行鉴权,然后获取扇区block的内容。
主要流程:NA

13.rfid_write_personal_data

描述:对第1和第2个扇区进行鉴权,然后重写扇区block的内容。
主要流程:NA

14.RFID-Cloner

描述:复制RFID卡。
主要流程:

1.初始化arduino uno串口、MFRC522实例
2.初始化MFRC522的PCD模块
3.寻卡
4.读卡
5.循环鉴权block,并将block值保存在内存中
6.寻新卡、读卡,鉴权新卡,将内存内容保存在新卡block中,跳过控制块。