在学习读写M1卡的相关知识,并准备在51下完成读写数据块数据时,出了问题。作为参照物,转到Arduino下进行测试。本帖是测试读取处理部分的代码。
读取操作一样一套严格按照以下顺序进行操作:
1、寻卡 (Request):让RC522模块寻找附近的M1卡,获取卡片类型代码。
2、防冲突 (Anticollision):当有多张卡时,选出一张进行通信,并获得该卡的UID(唯一标识符,4字节)。
3、选卡 (Select Tag):正式选定刚才通过防冲突检测的卡片。
4、认证扇区 (Authentication):这是最关键的一步。在操作某个扇区前,必须用该扇区的密码(KeyA或KeyB)进行身份验证。比如要读取1号扇区,就需要用1号扇区的密码去认证。
5、读/写操作 (Read/Write):认证成功后,才能对同一个扇区内的数据块(块0、1、2)进行读写。
操作中,使用默认的出厂KeyA:0xFF,0xFF,0xFF,0xFF,0xFF,0xFF。操作的对象块为第一扇区的第0、1、2块数据。电路连接参照之前的帖子:
Arduino下使用ESP32C3开发板测试RFID-RC522
代码如下:
#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)
const byte blockAddresses[] = {4, 5, 6};
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() {
// 检测新卡并读取序列号
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
return;
}
// 显示卡片UID
Serial.print(F("卡片 UID: "));
MFRC522Debug::PrintUID(Serial, mfrc522.uid);
Serial.println();
// 循环读取块4, 5, 6(对应第1扇区的0、1、2块:所在扇区的第一个块的地址 = 扇区编号 * 4)
for (byte block : blockAddresses) {
// 3. 使用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(" 失败。"));
continue; // 认证失败则跳过当前块
}
// 4. 读取块数据
status = mfrc522.MIFARE_Read(block, buffer, &bufferSize);
if (status != 0) {
Serial.print(F("读取块 "));
Serial.print(block);
Serial.println(F(" 失败。"));
continue;
}
// 5. 在串口监视器中打印数据(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();
}测试结果:

我要赚赏金
