符合EPC Class1 Gen2(简称G2)协议。
标签分区:A:Tag memory(标签内存)分为Reserved(保留),EPC(电子产品代码),TID(标签识别号)和User(用户)四个独立的存储区块(Bank)。
Reserved区:存储Kill Password(灭活口令)和Access Password(访问口令)。
EPC区:存储EPC号码等。
TID区:存储标签识别号码,每个TID号码应该是唯一的。
User区:存储用户定义的数据。
此外还有各区块的Lock(锁定)状态位等用到的也是存储性质的单元。
标签状态:A:收到连续波(CW)照射即上电(Power-up)以后,标签可处于Ready(准备),Arbitrate(裁断),Reply(回令),Acknowledged(应答),Open(公开),Secured(保护),Killed(灭活)七种状态之一。
1、Ready状态是未被灭活的标签上电以后,开始所处的状态,准备响应命令。
2、在Arbitrate状态,主要为等待响应Query等命令。
3、响应Query后,进入Reply状态,进一步将响应ACK命令就可以发回EPC号码。
4、发回EPC号码后,进入Acknowledged状态,进一步可以响应Req_RN命令。
5、Access Password不为0才可以进入Open状态,在此进行读、写操作。
6、已知Access Password才可能进入Secured状态,进行读、写、锁定等操作。
7、进入到Killed状态的标签将保持状态不变,永远不会产生调制信号以激活射频场,从而永久失效。被灭活的标签在所有环境中均应保持Killed状态,上电即进入灭活状态。灭活操作不可逆转。
要使标签进入某一状态一般需要适当次序的一组合法命令,反过来各命令也只能当标签在适当的状态下才能有效,标签响应命令后也会转到其他状态
RFID模块
实验效果
在串口监控器里面,我们把IC卡放在模块上,能读出储存在里面的数据,
程序就是这样来核对与我们数据库是否匹配,如果对得上,就开门,对不上肯定打死都不开
BOM表
Arduino Uno * 1
RFID-RC522 模块 * 1
IC卡 * 1-2
跳线若干
接线
Arduino Uno <------> RFID-RC522
10 <------> SDA
13 <------> SCK
11 <------> MOSI
12 <------> MISO
--null-- <------> IRQ
GND <------> GND
9 <------> RST
3.3V <------> 3.3V
程序
在工具里:可以设置端口。
我们需要用到RFID-RC522的库
下载:https://github.com/miguelbalboa/rfid
具体如何操作,再次说一下,下载解压到Arduino IDE的安装路径里的库文件夹libraries
当然我们还有第二种更新库的方法,不过这得用最新版的Arduino IDE ,
在菜单栏找到如下:
点开管理库,在搜索栏里输入RC522,找到图中的库,点击安装(我这图是已经安装过啦)
安装好库我们就可以直接使用例子里的程序
RFID 库文件及实例代码:
代码解读:
初始化:
/**
* ----------------------------------------------------------------------------
* This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
* for further details and other examples.
*
* NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
*
* Released into the public domain.
* ----------------------------------------------------------------------------
* This sample shows how to read and write data blocks on a MIFARE Classic PICC
* (= card/tag).
*
* BEWARE: Data will be written to the PICC, in sector #1 (blocks #4 to #7).
*
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
*/
#include <SPI.h>
#include <MFRC522.h>
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
/**
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// Prepare the key (used both as key A and as key B)
// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("Scan a MIFARE Classic PICC to demonstrate read and write."));
Serial.print(F("Using key (for A and B):"));
dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
Serial.println(F("BEWARE: Data will be written to the PICC, in sector #1"));
}
/**
* Main loop.
*/
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Check for compatibility
if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
&& piccType != MFRC522::PICC_TYPE_MIFARE_1K
&& piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("This sample only works with MIFARE Classic cards."));
return;
}
// In this sample we use the second sector,
// that is: sector #1, covering block #4 up to and including block #7
byte sector = 1;
byte blockAddr = 4;
byte dataBlock[] = {
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x08, 0x09, 0xff, 0x0b, // 9, 10, 255, 12,
0x0c, 0x0d, 0x0e, 0x0f // 13, 14, 15, 16
};
byte trailerBlock = 7;
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the whole sector as it currently is
Serial.println(F("Current data in sector:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// Read data from the block
Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
Serial.println();
// Authenticate using key B
Serial.println(F("Authenticating again using key B..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write data to the block
Serial.print(F("Writing data into block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
dump_byte_array(dataBlock, 16); Serial.println();
status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.println();
// Read data from the block (again, should now be what we have written)
Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
// Check that data in block is what we have written
// by counting the number of bytes that are equal
Serial.println(F("Checking result..."));
byte count = 0;
for (byte i = 0; i < 16; i++) {
// Compare buffer (= what we've read) with dataBlock (= what we've written)
if (buffer[i] == dataBlock[i])
count++;
}
Serial.print(F("Number of bytes that match = ")); Serial.println(count);
if (count == 16) {
Serial.println(F("Success :-)"));
} else {
Serial.println(F("Failure, no match :-("));
Serial.println(F(" perhaps the write didn't work properly..."));
}
Serial.println();
// Dump the sector data
Serial.println(F("Current data in sector:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
mfrc522.PCD_Init(); // Init MFRC522 card
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; //这里还不是很懂?是不是密钥验证!待学习
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) { //是否扫描到RFID卡
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) { //选择一个,信息是否读取成功
return;
}
RFID中记录 kill\access 密码信息 EPC编码 uid信息(卡片标识) user data 信息
这里 PICC 不是很明白???
Serial.print(F(" PICC type: ")); // Dump PICC type
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
验证:这里还需进一步理解???
block = 1;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
写入信息:
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
读取信息:
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer2, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
高频,超高频,低频RFID卡存储信息格式有没有区别?
RFID 内存储区有很多block块,每一块都有密钥key_A,key_B