天天看点

【IoT】NFC MRC522 原理及示例解析

1、协议基础原理

ISO-14443A 协议:

国际标准化组织:International Organization for Standardization RFID 协议的一种;

PICC:

临近卡 - A 型和B 型

PCD:

临近耦合设备--指 MFRC522 模块

ATQ:

对请求的应答、ATQA 对 A 型卡请求的应答、ATQB 对 B 型卡请求的应答

REQA:

对 A 型卡的请求

REQB:

对 B 型卡的请求

WUPA:

A 型卡的唤醒命令

ASK:

选择确认

MIFARE: 

恩智浦半导体(NXP Semiconductors)拥有的商标之一

MIFARE卡(M1卡):

兼具读写功能,主要是非接触式,有快速防冲突机制 – 处理多卡同时进入感应区的机制,其特殊的存储结构适合一卡多用,目前主要芯片 philip mifare1 S50、S70 等;

2、MFRC522 基础特性

非接触式读写卡芯片,最大通信速率 13.56MHz;

支持接口:

UART,SPI(Speed_max=10Mbit/s),IIC(快速:400Kbit/s,高速:3400Kbit/s)

通信协议:

ISO-14443A、7816 等

收发缓冲:

64 字节

支持中断模式、可编程定时器、CRC 协处理器

1) MFRC522 与 M1 卡通信

M1-IC-S50 卡工作原理/操作流程:

M1卡结构:

共 16 个扇区,每个扇区 4 块(块0~3),共 64 块,按块号编址为 0~63;

第 0 扇区的块 0(即绝对地址 0 块)用于存放厂商代码,已经固化,不可更改。

其他各扇区:

块 0、块 1、块 2 为数据块,用于存储数据;

块 3 为控制块,存放密码 A,存取控制,存放密码 B

每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。

注:

加密是针对一个扇区来进行的。

MFRC522 模块与 MF-IC 卡通信流程:

3、MRC522 操作流程

RC522 支持 SPI、IIC 和 UART 三种通信方式,现以 SPI 为例:

#define RF_LPCTL               BIT3  // P2.3 射频卡休眠控制---RST   
#define RF_SS                  BIT7  // p2.7 射频卡从机选择(SS)---SDA
#define RF_SCLK                BIT6  // p2.6 射频卡数据时钟输出(SCLK)
#define RF_DATA_OUT            BIT5  // p2.5 射频卡数据输出(MOSI)
#define RF_DATA_IN             BIT1  // p2.1 射频模块输入(MISO)
           

要想对模块内部的数据块进行读写,需要完成4个步骤:寻卡→防冲突→选卡→读/写卡;

1)寻卡

status2=PcdRequest(0x52,Temp);  //寻卡 参数Temp为返回的卡类型
if(status2== MI_OK)
{
  tochar(Temp[0]);
  tochar(Temp[1]); //输出卡类型
}

其中0x52代表寻天线区内全部卡。
卡类型(TagType):

0x4400 =Mifare_UltraLight
0x0400 =Mifare_One(S50)
0x0200 =Mifare_One(S70)
0x0800 =Mifare_Pro(X)
0x4403 =Mifare_DESFire
           

比如,当 Temp[0]=04,Temp[1]=00 时,卡类型为 S50。

2)防冲突

status2= PcdAnticoll(UID);  // 防冲撞处理,输出卡片序列号,4 字节
if(status2==MI_OK)
{
  PutString0("Card Id is:");
  tochar(UID[0]);
  tochar(UID[1]);
  tochar(UID[2]);
  tochar(UID[3]); //输出卡片序列号
}
           

3)选卡

status2= PcdSelect(UID);    // 选择卡片,输入卡片序列号,4 字节

4)在读写卡之前需要先进行认证

status2= PcdAuthState(PICC_AUTHENT1A, 1, Password_Buffer, UID);

其中四个参数分别代表:

验证 A 密钥 + 块地址 + 扇区密码 + 卡序列号。

然后进行写操作:

status2=PcdWrite(1,writeData); // 写数据,将数组writeData中的数写入到卡中

其中第一个参数  1  代表写入的地址为块1.

或者进行读卡操作:

status2 = PcdRead(1, str); //读卡

其中第一个参数 1 代表读的地址为块 1。 

读卡后得到的数据存放于数组 str 中。

refer:

https://blog.csdn.net/li13158/article/details/81588148

https://blog.csdn.net/txf1984/article/details/46560513

继续阅读