RC522 RFID模块代码例程
例程1:Arduino (MFRC522 库)
依赖:安装 MFRC522 库(作者 miguelbalboa)
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10 // 片选
#define RST_PIN 9 // 复位
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
Serial.println("RC522 Ready. 请刷卡...");
}
void loop() {
if (!mfrc522.PICC_IsNewCardPresent())
return;
if (!mfrc522.PICC_ReadCardSerial())
return;
Serial.print("UID: ");
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
byte sector = 0;
byte blockAddr = 0;
byte trailerBlock = 3;
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; // 默认密钥
MFRC522::StatusCode status;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
trailerBlock, &key, &(mfrc522.uid));
if (status == MFRC522::STATUS_OK) {
byte buffer[18];
byte size = sizeof(buffer);
status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status == MFRC522::STATUS_OK) {
Serial.print("Block 0 data: ");
for (byte i = 0; i < 16; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
Serial.println();
}
}
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
例程2:STM32 HAL (SPI 裸驱动)
#include "stm32f1xx_hal.h"
#define RC522_REG_COMMAND 0x01
#define RC522_REG_COM_IEN 0x02
#define RC522_REG_FIFO_DATA 0x09
#define RC522_REG_FIFO_LEVEL 0x0A
#define RC522_REG_TX_CONTROL 0x14
#define RC522_REG_BIT_FRAMING 0x0D
#define RC522_REG_MODE 0x11
#define RC522_REG_T_MODE 0x2A
#define RC522_REG_T_PRESCALER 0x2B
#define RC522_REG_T_RELOAD_H 0x2C
#define RC522_REG_T_RELOAD_L 0x2D
#define RC522_REG_ERROR 0x06
#define RC522_REG_COLL 0x0E
#define RC522_REG_VERSION 0x37
#define RC522_CS_PORT GPIOA
#define RC522_CS_PIN GPIO_PIN_4
#define RC522_RST_PORT GPIOA
#define RC522_RST_PIN GPIO_PIN_3
#define RC522_SPI hspi1
static void rc522_cs_low(void) { HAL_GPIO_WritePin(RC522_CS_PORT, RC522_CS_PIN, GPIO_PIN_RESET); }
static void rc522_cs_high(void) { HAL_GPIO_WritePin(RC522_CS_PORT, RC522_CS_PIN, GPIO_PIN_SET); }
static uint8_t rc522_spi_transfer(uint8_t data) {
uint8_t rx;
HAL_SPI_TransmitReceive(&RC522_SPI, &data, &rx, 1, 100);
return rx;
}
static uint8_t rc522_read_reg(uint8_t reg) {
uint8_t addr = ((reg << 1) & 0x7E) | 0x80;
rc522_cs_low();
rc522_spi_transfer(addr);
uint8_t val = rc522_spi_transfer(0x00);
rc522_cs_high();
return val;
}
static void rc522_write_reg(uint8_t reg, uint8_t val) {
uint8_t addr = ((reg << 1) & 0x7E);
rc522_cs_low();
rc522_spi_transfer(addr);
rc522_spi_transfer(val);
rc522_cs_high();
}
void rc522_init(void) {
HAL_GPIO_WritePin(RC522_RST_PORT, RC522_RST_PIN, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(RC522_RST_PORT, RC522_RST_PIN, GPIO_PIN_SET);
HAL_Delay(50);
rc522_write_reg(RC522_REG_COMMAND, 0x0F); // Soft reset
HAL_Delay(50);
rc522_write_reg(RC522_REG_T_MODE, 0x80);
rc522_write_reg(RC522_REG_T_PRESCALER, 0x18);
rc522_write_reg(RC522_REG_T_RELOAD_H, 0x00);
rc522_write_reg(RC522_REG_T_RELOAD_L, 0x3B);
rc522_write_reg(RC522_REG_TX_CONTROL, 0x03);
rc522_write_reg(RC522_REG_MODE, 0x3D);
uint8_t tx = rc522_read_reg(RC522_REG_TX_CONTROL);
rc522_write_reg(RC522_REG_TX_CONTROL, tx | 0x03);
}
uint8_t rc522_request(uint8_t req_mode, uint8_t *tag_type) {
rc522_write_reg(RC522_REG_BIT_FRAMING, 0x07); // LSB first, 7 bits
rc522_write_reg(RC522_REG_FIFO_DATA, req_mode);
rc522_write_reg(RC522_REG_COMMAND, 0x0C); // Transceive
rc522_write_reg(RC522_REG_COM_IEN, 0x20); // 使能完成中断
HAL_Delay(30);
uint8_t err = rc522_read_reg(RC522_REG_ERROR);
uint8_t fifo_len = rc522_read_reg(RC522_REG_FIFO_LEVEL);
if (err != 0 || fifo_len < 2) return 0xFF;
*tag_type = rc522_read_reg(RC522_REG_FIFO_DATA);
return 0;
}
void rc522_demo(void) {
rc522_init();
uint8_t ver = rc522_read_reg(RC522_REG_VERSION);
printf("RC522 Version: 0x%02X (expected 0x92 or 0x91)\r\n", ver);
while (1) {
uint8_t tag_type = 0;
if (rc522_request(0x26, &tag_type) == 0) {
printf("Card detected! Type: 0x%02X\r\n", tag_type);
}
HAL_Delay(500);
}
}
例程3:ESP32 (直接寄存器操作)
#include <SPI.h>
#define RC522_SS 5
#define RC522_RST 4
SPIClass rc522_spi(HSPI);
void setup() {
Serial.begin(115200);
pinMode(RC522_SS, OUTPUT);
pinMode(RC522_RST, OUTPUT);
digitalWrite(RC522_SS, HIGH);
rc522_spi.begin(14, 12, 13, RC522_SS); // SCK=14, MISO=12, MOSI=13
rc522_spi.setFrequency(8000000);
rc522_spi.setDataMode(SPI_MODE0);
rc522_init();
Serial.println("RC522 on ESP32 ready.");
}
void loop() {
uint8_t tag_type;
if (rc522_request(0x26, &tag_type) == 0) {
Serial.printf("Tag type: 0x%02X\n", tag_type);
}
delay(500);
}
常见问题排查
| 现象 |
可能原因 |
解决方法 |
| 无法检测到卡 |
供电不足/天线问题 |
确保 3.3V 供电稳定,远离金属 |
| 读卡距离短 |
天线匹配差 |
更换模块或优化天线布局 |
| 通信超时 |
SPI引脚错误 |
检查MISO/MOSI/SCK/NSS连接 |
| 认证失败 |
密钥错误 |
确认卡片密钥,尝试默认密钥 |
| Version寄存器读0x00 |
SPI不通 |
检查接线和片选时序 |