在前一个读取操作的帖子基础上,继续测试写入操作。操作过程为取得数据、修改数据、回写数据。
部分内容可参考一下两个贴子:
【合宙ESP32C3开发板】Arduino下测试RFID-RC522
【合宙ESP32C3开发板】Arduino下测试读取M1卡块数据
读取、修改、回写的对象为第1扇区的第0块第一个单元。
代码如下:
#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>
// 定义引脚 (与硬件连接一致)
#define SCK_PIN 4
#define MISO_PIN 5
#define MOSI_PIN 6
#define SS_PIN 7 // SDA
#define RST_PIN 8
// 初始化 SPI 驱动
MFRC522DriverPinSimple rst_pin(RST_PIN);
MFRC522DriverPinSimple ss_pin(SS_PIN);
MFRC522DriverSPI driver{ss_pin};
MFRC522 mfrc522{driver};
// 准备密钥(出厂默认为 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF)
MFRC522::MIFARE_Key key;
// 要读取的块地址(第1扇区的块0, 1, 2)
byte block = 4;
byte buffer[18]; // 读取缓冲区,至少18字节以容纳CRC
byte bufferSize = sizeof(buffer);
void setup() {
Serial.begin(115200);
SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN); // 明确指定 SPI 引脚
mfrc522.PCD_Init();
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);
Serial.println(F("将卡片靠近读卡器..."));
// 将密钥设置为出厂默认值
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
delay(1000);
//Serial.println("Ready to read card...");
}
void loop() {
byte newData[16] = {0}; // 示例数据,假设要写入的数据
// 检测新卡并读取序列号
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
return;
}
// 显示卡片UID
Serial.print(F("卡片 UID: "));
MFRC522Debug::PrintUID(Serial, mfrc522.uid);
Serial.println();
// 读取块4(对应第1扇区的0块:所在扇区的第一个块的地址 = 扇区编号 * 4)
// 使用Key A (0x60) 对当前块所在的扇区进行认证
// 注意:认证是针对整个扇区的,认证一个块后,同一扇区的其他块无需再次认证。
// 但为了代码清晰,这里每次读取前都进行认证。
byte status = mfrc522.PCD_Authenticate(0x60, block, &key, &mfrc522.uid);
if (status != 0) {
Serial.print(F("认证块 "));
Serial.print(block);
Serial.println(F(" 失败。"));
} else {
// 读取块数据
status = mfrc522.MIFARE_Read(block, buffer, &bufferSize);
if (status != 0) {
Serial.print(F("读取块 "));
Serial.print(block);
Serial.println(F(" 失败。"));
} else {
// 在串口监视器中打印数据(16字节)
Serial.print(F("块 "));
Serial.print(block);
Serial.print(F(" 数据: "));
for (byte i = 0; i < 16; i++) {
// 以十六进制格式打印,不足两位补0
if (buffer[i] < 0x10) Serial.print("0");
Serial.print(buffer[i], HEX);
Serial.print(" ");
}
// 也可尝试以ASCII字符打印(如果数据是文本)
// for (byte i = 0; i < 16; i++) Serial.print((char)buffer[i]);
Serial.println();
// 修改数据
buffer[0]+=0x10;
// 写回去, 写入整个块(MIFARE_Write 一次写入16字节)
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != 0) {
Serial.println(F("写入数据失败。"));
} else {
Serial.println(F("数据写入成功。"));
// 再读取
Serial.println(F("再读取。"));
status = mfrc522.MIFARE_Read(block, buffer, &bufferSize);
if (status != 0) {
Serial.print(F("读取块 "));
Serial.print(block);
Serial.println(F(" 失败。"));
} else {
// 在串口监视器中打印数据(16字节)
Serial.print(F("块 "));
Serial.print(block);
Serial.print(F(" 数据: "));
for (byte i = 0; i < 16; i++) {
// 以十六进制格式打印,不足两位补0
if (buffer[i] < 0x10) Serial.print("0");
Serial.print(buffer[i], HEX);
Serial.print(" ");
}
// 也可尝试以ASCII字符打印(如果数据是文本)
// for (byte i = 0; i < 16; i++) Serial.print((char)buffer[i]);
Serial.println();
}
}
}
}
// 停止与当前卡的通信
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}运行结果如下:

我要赚赏金
