天天看點

【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

繼續閱讀