3.3V供电、GND接地不用多说,IRQ是中断才用到的此处没有用到可以不接,其余5个引脚接法如下表所示:
/* 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>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial) //端口打开失败什么都不做
;
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
// 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):"));
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
}
int state = 0; //1=49 2=50 3=51
bool selectedcard = false;
// Init array that will store new NUID
byte nuidPICC[4]; //当前卡片的id
String cm1;
void loop() {
if (state == 0 || state == 48) {
//读取串口的数据
if (Serial.available() > 0) {
// read the incoming byte:
state = Serial.read();
//Serial.println(state);
}
} else {
if (state != 49 && state != 50) {
while (Serial.available() > 0) {
cm1 += char(Serial.read());
delay(2);
}
if (cm1.length() > 0) {
Serial.print("输入");
Serial.println(cm1);
if (cm1.length() == 6 && cm1.compareTo("000000") == 0) {
state = 0;
return;
}
byte byteArray[cm1.length() / 2] = { 0 };
hexCharacterStringToBytes(byteArray, cm1.c_str());
printHex(byteArray, sizeof(byteArray));
//Serial.println(tep_1);
cm1 = "";
}
}
}
if (state == 49) { //字符1
Serial.println("开始读卡");
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!mfrc522.PICC_IsNewCardPresent()) {
Serial.println("没有检测到新卡片");
state = 0;
return;
}
// Select one of the cards
if (!mfrc522.PICC_ReadCardSerial()) {
Serial.println(("选卡失败"));
state = 0;
return;
}
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("卡片类型未知"));
}
//打印当前卡片id
Serial.print(F("The NUID tag is:"));
printHex(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println("");
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
state = 0; //状态重置
} else if (state == 50) {
//接收数据,并写入卡片id
Serial.println("等待输入新卡号");
String temp2;
while (Serial.available() > 0) {
temp2 += char(Serial.read());
delay(2);
}
byte inputID[4] = { 0 };
byte paritybit;
if (temp2.length() > 0) {
if (temp2.length() != 8) {
Serial.println("卡号id应是个8位数");
state = 0;
return;
}
hexCharacterStringToBytes(inputID, temp2.c_str());
Serial.println("输入的卡号是:");
printHex(inputID, sizeof(inputID));
Serial.println("");
paritybit = idChecksum(inputID); //计算校验位
Serial.print("id校验码:");
Serial.println(paritybit, HEX);
} else {
return;
}
//读取缓冲区的内容,如果内容不存在,则 retrun;
//准备读取新卡,并打印新卡的id
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
Serial.println(F("卡片读取失败,请确认"));
delay(50);
state = 0;
return;
}
Serial.print(F("当前卡片的 UID:"));
printHex(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println("");
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println("不支持的卡片类型.");
state = 0;
return;
}
byte sector = 0; //0扇区
byte blockAddr = 0; //第0块
Serial.print(F("Reading data from block "));
Serial.print(blockAddr);
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
byte trailerBlock = 3; //授权验证的块号
// Authenticate using key A 使用密钥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));
state = 0;
return;
}
status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("读取数据块失败: "));
Serial.println(mfrc522.GetStatusCodeName(status));
state = 0;
return; //读取卡片失败,退出
}
Serial.print(F("Data in block "));
Serial.print(blockAddr);
Serial.print(F(":"));
printHex(buffer, 16);
Serial.println();
//写入前需要校验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));
state = 0;
return;
}
//设置0块的数据,以备写入
buffer[0] = inputID[0];
buffer[1] = inputID[1];
buffer[2] = inputID[2];
buffer[3] = inputID[3];
buffer[4] = paritybit;
//写入到当前卡的id中
status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(blockAddr, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed, 失败: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.println("写入完毕,当前卡片数据:");
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
state = 0; //状态重置
}
}
//bcc校验,求uid的 校验位
byte idChecksum(byte *buffer) {
return buffer[0] ^ buffer[1] ^ buffer[2] ^ buffer[3];
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void printHex(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? "0" : "");
Serial.print(buffer[i], HEX);
Serial.print(" ");
}
}
void hexCharacterStringToBytes(byte *byteArray, const char *hexString) {
bool oddLength = strlen(hexString) & 1;
byte currentByte = 0;
byte byteIndex = 0;
for (byte charIndex = 0; charIndex < strlen(hexString); charIndex++) {
bool oddCharIndex = charIndex & 1;
if (oddLength) {
// If the length is odd
if (oddCharIndex) {
// odd characters go in high nibble
currentByte = nibble(hexString[charIndex]) << 4;
} else {
// Even characters go into low nibble
currentByte |= nibble(hexString[charIndex]);
byteArray[byteIndex++] = currentByte;
currentByte = 0;
}
} else {
// If the length is even
if (!oddCharIndex) {
// Odd characters go into the high nibble
currentByte = nibble(hexString[charIndex]) << 4;
} else {
// Odd characters go into low nibble
currentByte |= nibble(hexString[charIndex]);
byteArray[byteIndex++] = currentByte;
currentByte = 0;
}
}
}
}
byte nibble(char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0; // Not a valid hexadecimal character
}
使用说明
1、代码中注释 1=49 2=50 3=51 这里指的是 1、2、3对应的Ascii码,串口读取的是字符串对应的ASCII码
2、输入<1>读取卡片,输入<2>将读取的卡片值写入到新的卡片中,<000000>重置状态初始化程序 ,<3>未使用
输出:
实验中主要输出卡片数据的是语句:
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
使用默认的 FF FF FF FF FF FF作为密码读取卡片数据。
执行:在串口中输入 01(byte类型) 或者 1(string) 响应。
Scan a MIFARE Classic PICC to demonstrate read and write.
Using key (for A and B):FF FF FF FF FF FF
开始读卡
PICC type: MIFARE 1KB
The NUID tag is:2E 1C F5 FF
Card UID: 2E 1C F5 FF
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits
15 63 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
14 59 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
56 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
13 55 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
12 51 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
11 47 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
10 43 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
9 39 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
8 35 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
7 31 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
29 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
6 27 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
5 23 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
4 19 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
3 15 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
2 11 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
1 7 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
0 3 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
0 2E 1B F2 7D BA 08 04 00 62 63 64 65 66 67 68 69 [ 0 0 0 ]
自定义密码卡片的输出如下
开始读卡
PICC type: MIFARE 1KB
The NUID tag is:3E F5 E9 7D
Card UID: 3E F5 E9 7D
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits
15 63 PCD_Authenticate() failed: Error in communication.
14 59 PCD_Authenticate() failed: Timeout in communication.
13 55 PCD_Authenticate() failed: Timeout in communication.
12 51 PCD_Authenticate() failed: Timeout in communication.
11 47 PCD_Authenticate() failed: Timeout in communication.
10 43 PCD_Authenticate() failed: Timeout in communication.
9 39 PCD_Authenticate() failed: Timeout in communication.
8 35 PCD_Authenticate() failed: Timeout in communication.
7 31 PCD_Authenticate() failed: Timeout in communication.
6 27 PCD_Authenticate() failed: Timeout in communication.
5 23 PCD_Authenticate() failed: Timeout in communication.
4 19 PCD_Authenticate() failed: Timeout in communication.
3 15 PCD_Authenticate() failed: Timeout in communication.
2 11 PCD_Authenticate() failed: Timeout in communication.
1 7 PCD_Authenticate() failed: Timeout in communication.
0 3 PCD_Authenticate() failed: Timeout in communication.
本文链接:https://blog.nnwk.net/article/143
有问题请留言。版权所有,转载请在显眼位置处保留文章出处,并留下原文连接
Leave your question and I'll get back to you as soon as I see it. All rights reserved. Please keep the source and links
友情链接:
子卿全栈
全部评论