前言
RFID是Radio-Fequency Identification射頻識別的縮寫。RFID使用電磁場在短距離內(nèi)傳輸數(shù)據(jù),它可用于人員識別、刷卡交易,商品的電子標(biāo)簽等。工作原理為,ID磁卡進(jìn)入到磁場后,接受讀寫器發(fā)出的射頻信號,憑借感應(yīng)電流所獲得的能量發(fā)送出存儲在芯片中的產(chǎn)品信息,讀寫器讀取到信息并解碼后,送至處理單元進(jìn)行數(shù)據(jù)處理。
MFRC522是高度集成的非接觸式( 13.56MHz)讀寫卡芯片。此發(fā)送模塊利用調(diào)制和解調(diào)的原理,并將它們完全集成到各種非接觸式通信方法和協(xié)議中(13.56MHz)。
MFRC522的內(nèi)部發(fā)送器部分可驅(qū)動(dòng)讀寫器天線與ISO 14443A/MIFARE卡和應(yīng)答機(jī)的通信,無需其它的電路。接收器部分提供一個(gè)功能強(qiáng)大和高效的解調(diào)和譯碼電路,用來處理兼容ISO 14443A/MIFARE的卡和應(yīng)答機(jī)的信號。通信距離可達(dá)50mm,取決于天線的長度和調(diào)諧。數(shù)字電路部分處理完整的ISO 14443A幀和錯(cuò)誤檢測(奇偶&CRC)。
- 支持MIFARE標(biāo)準(zhǔn)器件,如S50、S70,UID卡,
- 支持MIFARE Classic加密。
- 支持MIFARE更高速的非接觸式通信,雙向數(shù)據(jù)傳輸速率高達(dá)424kbit/s。
- 內(nèi)部64字節(jié)的發(fā)送和接收FIFO緩沖區(qū)。
- 10Mbit/s的SPI接口
- I2C接口,快速模式的速率為400kbit/s,高速模式的速率為3400kbit/s
- 串行UART,傳輸速率高達(dá)1228.8kbit/s, 幀取決于RS232接口,電壓電平取決于提供的管腳電壓
本文將介紹ESP32開發(fā)板驅(qū)動(dòng)MFRC522 RFID模塊,讀取RFID卡原始數(shù)據(jù)、獲取RFID卡的UID,并將個(gè)人數(shù)據(jù)添加到RFID卡中。
ESP32開發(fā)板與MFRC522模塊接線
下圖為SPI通信接線圖
ESP32 | MFRC522 |
---|---|
GPIO5 | SDA引腳作為SPI通信時(shí)的CS片選 |
GPIO18 | SCK |
GPIO23 | MOSI |
GPIO19 | MISO |
不接 | IRQ |
GND | GND |
GPIO21 | RST |
3V3 | 3.3V |
讀取S50 IC白卡與S50 IC鑰匙卡扣原始數(shù)據(jù)
Arduino IDE中安裝RFID_MFRCC522驅(qū)動(dòng)庫
#include < MFRC522v2.h >
#include < MFRC522DriverSPI.h >
//#include < MFRC522DriverI2C.h >
#include < MFRC522DriverPinSimple.h >
#include < MFRC522Debug.h >
// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(5);
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{}; // Create I2C driver
MFRC522 mfrc522{driver}; // Create MFRC522 instance
void setup() {
Serial.begin(115200); // Initialize serial communication
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
mfrc522.PCD_Init(); // Init MFRC522 board.
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show details of PCD - MFRC522 Card Reader details.
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards.
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called.
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
delay(2000);
}
程序中PICC表示IC卡(proximity integrated circuit cards)
PCD表示讀寫模塊MFRC522(proximity coupling device)
編譯上傳程序到ESP32開發(fā)板 ,打開串口打印,把IC卡靠近MFRC522讀寫模塊,可在串口上打印出IC內(nèi)存儲的數(shù)據(jù)
從串口打印出的信息可知道
IC卡的存儲分布結(jié)構(gòu)劃分為16個(gè)(0-15)扇區(qū),每個(gè)扇區(qū)包含4個(gè)(0-3)存儲塊,每個(gè)存儲塊包含16個(gè)字節(jié)的存儲(0-15)
扇區(qū)0上的存儲塊0存儲著IC卡的出廠信息,第0-4字節(jié)為UUID(如43 17 EE 05),一個(gè)校驗(yàn)字節(jié),剩余的為出廠寫入的數(shù)據(jù)。存儲塊0為只讀模式,一般不可更改(部分克隆卡可修改)。
每個(gè)扇區(qū)的前3個(gè)存儲塊可用于存儲數(shù)據(jù),每個(gè)扇區(qū)的最后一個(gè)存儲塊為扇區(qū)尾塊Sector Trailer。
每個(gè)扇區(qū)尾塊固定為 16字節(jié),其數(shù)據(jù)結(jié)構(gòu)如下:
0~5 Key A(6字節(jié)),扇區(qū)的第一個(gè)訪問密鑰(默認(rèn)通常為 FF FF FF FF FF FF 或廠商預(yù)設(shè)值)。
6~8 Access Bits(4字節(jié)),存儲該扇區(qū)的訪問權(quán)限控制位(實(shí)際只用了3字節(jié),第9字節(jié)為備用)。
10~15 Key B(6字節(jié)),扇區(qū)的第二個(gè)訪問密鑰(可選,部分應(yīng)用可能不用或與Key A相同)。
每個(gè)扇區(qū)的最后一個(gè)塊是安全核心,決定了該扇區(qū)的訪問規(guī)則。操作時(shí)務(wù)必謹(jǐn)慎,建議先讀取并備份原始數(shù)據(jù)(需密鑰驗(yàn)證),再嘗試修改。
IC卡的類型為MIFARE 1KB 用戶可用的凈存儲容量為:
16扇區(qū) X 3存儲塊 X 16字節(jié) - 16字節(jié)=752字節(jié)
UID為 43 17 EE 05 不同的卡的UID會(huì)不一樣
讀寫用戶數(shù)據(jù)到指定的存儲塊
#include < MFRC522v2.h >
#include < MFRC522DriverSPI.h >
//#include < MFRC522DriverI2C.h >
#include < MFRC522DriverPinSimple.h >
#include < MFRC522Debug.h >
// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(5);
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{}; // Create I2C driver
MFRC522 mfrc522{driver}; // Create MFRC522 instance
MFRC522::MIFARE_Key key;
byte blockAddress = 2;
byte newBlockData[17] = {"www.yourcee.com"};
//byte newBlockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // CLEAR DATA
byte bufferblocksize = 18;
byte blockDataRead[18];
void setup() {
Serial.begin(115200); // Initialize serial communication
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
mfrc522.PCD_Init(); // Init MFRC522 board.
Serial.println(F("Warning: this example overwrites a block in your card, use with care!"));
// Prepare key - all keys are set to FFFFFFFFFFFF at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
// Check if a new card is present
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
delay(500);
return;
}
// Display card UID
Serial.print("----------------nCard UID: ");
MFRC522Debug::PrintUID(Serial, (mfrc522.uid));
Serial.println();
// Authenticate the specified block using KEY_A = 0x60
if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
Serial.println("Authentication failed.");
return;
}
// Write data to the specified block
if (mfrc522.MIFARE_Write(blockAddress, newBlockData, 16) != 0) {
Serial.println("Write failed.");
} else {
Serial.print("Data written successfully in block: ");
Serial.println(blockAddress);
}
// Authenticate the specified block using KEY_A = 0x60
if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
Serial.println("Authentication failed.");
return;
}
// Read data from the specified block
if (mfrc522.MIFARE_Read(blockAddress, blockDataRead, &bufferblocksize) != 0) {
Serial.println("Read failed.");
} else {
Serial.println("Read successfully!");
Serial.print("Data in block ");
Serial.print(blockAddress);
Serial.print(": ");
for (byte i = 0; i < 16; i++) {
Serial.print((char)blockDataRead[i]); // Print as character
}
Serial.println();
}
// Halt communication with the card
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
delay(2000); // Delay for readability
}
byte blockAddress = 2;
定義了一個(gè)名為blockAddress的變量。這個(gè)變量指定了IC卡內(nèi)將要寫入或讀取數(shù)據(jù)的塊。blockAddress被設(shè)置為2,將與卡片內(nèi)存的第2個(gè)塊進(jìn)行交互。如果你想寫入不同的塊,你可以更改這個(gè)值。
byte newBlockData[17] = {"www.yourcee.com"};
保存您想要寫入卡中的數(shù)據(jù),不超過16個(gè)字節(jié)
byte newBlockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
如果您想清除塊數(shù)據(jù),取消注釋這行代碼
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
IC卡的默認(rèn)密鑰也在以上行中設(shè)置。默認(rèn)情況下,工廠密鑰的所有字節(jié)都是0xFF。這個(gè)密鑰允許訪問卡的數(shù)據(jù)塊。
if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
Serial.println("Authentication failed.");
return;
}
代碼嘗試使用默認(rèn)密鑰(在本例中為塊2)對卡片上的特定塊進(jìn)行認(rèn)證。0x60是一個(gè)指定使用KEY_A進(jìn)行認(rèn)證的命令。KEY_A是RFID卡上可用的兩個(gè)密鑰(KEY_A和KEY_B)之一,每個(gè)密鑰提供不同的權(quán)限。使用0x60意味著代碼正在嘗試用KEY_A進(jìn)行認(rèn)證,而默認(rèn)情況下,在MIFARE RFID卡上KEY_A是0xFF 0xFF 0xFF 0xFF 0xFF。
編譯上傳程序到ESP32開發(fā)板 ,打開串口監(jiān)視器,并把IC卡 靠近MFRC522讀寫模塊,串口顯示出寫入并讀取到指定存儲塊的數(shù)據(jù)
總結(jié)
本實(shí)驗(yàn)只是對空白的MIFARE Classic IC卡進(jìn)行簡單的讀寫驗(yàn)證,由于IC卡大都有秘鑰,至于破解IC卡,復(fù)制C卡需要大家進(jìn)一步探索研究了。
審核編輯 黃宇
-
RFID
+關(guān)注
關(guān)注
391文章
6426瀏覽量
242089 -
MFRC522
+關(guān)注
關(guān)注
2文章
30瀏覽量
17771 -
ESP32
+關(guān)注
關(guān)注
21文章
1014瀏覽量
19158
發(fā)布評論請先 登錄
MFRC522非接觸式讀卡器IC中文手冊
別再用鑰匙啦!樹莓派Pico教你用RFID“刷”門禁~

RFID紙質(zhì)芯片卡的應(yīng)用

用于LEGIC Advant UID/序列號的NFC讀卡器,為什么無法讀取這些卡的UID/序列號?
SI522A 低功耗尋卡與多款13.56MHZ 兼容開發(fā)資料
SI522這款13.56MHz芯片能兼容這么多款同行芯片
原來ESP32竟可《一“芯”兩用》既做人體檢測傳感器也做Wi-Fi數(shù)據(jù)傳輸

Si522A:高度集成的13.56MHz非接觸式讀寫器芯片數(shù)據(jù)手冊

基于ESP32-C3FN4為核心自主研發(fā)的Wi-Fi+BT模塊-RF-WM-ESP32B1

SI522A 與 恩智浦 RC522 刷卡對比
esp8266和esp32區(qū)別是什么
esp32用什么軟件編程
如何讀取多張卡的UID,有償
ESP32-WROOM-32E、ESP32-WROOM-32D、ESP32-WROOM-32U 有什么區(qū)別?ESP32-WROOM-32 后綴字母代表的意思是?

評論