STM32 驱动 RC522(MFRC522)实现方案

STM32 驱动 RC522(MFRC522)实现方案 适用于 STM32F1/F4/G0/L4 等全系列(HAL 库),实现 RFID 卡号读取(Mifare Classic)。


一、硬件连接(SPI 方式,最常用 )

RC522 支持 SPI / I2C / UART,STM32 一般用 SPI(最快最稳)

1、推荐接线(STM32 ↔ RC522)

RC522 STM32 说明
VCC 3.3V ❗❗ 严禁 5V
GND GND
RST PB0 复位
NSS / SDA PB12 SPI 片选
SCK PB13 SPI 时钟
MOSI PB15 SPI 输出
MISO PB14 SPI 输入
IRQ NC 中断(可选)

推荐 SPI 速率:≤ 10MHz
SPI 模式:Mode 0 (CPOL=0, CPHA=0)


二、SPI & GPIO 初始化(CubeMX)

SPI 配置

参数
Mode Full-Duplex Master
Frame Format Motorola
Data Size 8 bits
CPOL Low
CPHA 1 Edge
Prescaler 8 ~ 16
NSS Soft

GPIO

引脚 模式
PB12 GPIO_Output(CS)
PB0 GPIO_Output(RST)

三、RC522 驱动核心代码

1、 rc522.h

#ifndef __RC522_H
#define __RC522_H

#include "stm32f4xx_hal.h"

#define RC522_CS_LOW()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define RC522_CS_HIGH()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define RC522_RST_LOW()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET)
#define RC522_RST_HIGH() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET)

void RC522_Init(void);
uint8_t RC522_Request(uint8_t req_code, uint8_t *card_type);
uint8_t RC522_Anticoll(uint8_t *uid);
uint8_t RC522_SelectTag(uint8_t *uid);
uint8_t RC522_Auth(uint8_t auth_mode, uint8_t block, uint8_t *key, uint8_t *uid);
uint8_t RC522_Read(uint8_t block, uint8_t *data);
uint8_t RC522_Write(uint8_t block, uint8_t *data);

#endif

2、rc522.c(核心)

SPI 读写

#include "rc522.h"
#include "spi.h"

static uint8_t RC522_ReadByte(uint8_t addr)
{
    uint8_t tx = 0x80 | (addr << 1);
    uint8_t rx = 0;
    RC522_CS_LOW();
    HAL_SPI_TransmitReceive(&hspi2, &tx, &rx, 1, 10);
    HAL_SPI_Receive(&hspi2, &rx, 1, 10);
    RC522_CS_HIGH();
    return rx;
}

static void RC522_WriteByte(uint8_t addr, uint8_t val)
{
    uint8_t tx[2] = {(addr << 1), val};
    RC522_CS_LOW();
    HAL_SPI_Transmit(&hspi2, tx, 2, 10);
    RC522_CS_HIGH();
}

RC522 初始化

void RC522_Init(void)
{
    RC522_RST_HIGH();
    HAL_Delay(50);
    RC522_WriteByte(0x01, 0x0F); // Command = SoftReset
    RC522_WriteByte(0x2A, 0x8D); // TAuto=1
    RC522_WriteByte(0x2B, 0x3E); // TPreScaler
    RC522_WriteByte(0x2D, 30);   // TReloadVal
    RC522_WriteByte(0x2C, 0);
    RC522_WriteByte(0x15, 0x40); // Force100ASK
    RC522_WriteByte(0x11, 0x3D); // Mode
    RC522_WriteByte(0x26, 0x60); // TxControl (ANT=ON)
}

寻卡(REQA)

uint8_t RC522_Request(uint8_t req, uint8_t *card_type)
{
    uint8_t status;
    RC522_WriteByte(0x01, 0x0C); // Idle
    RC522_WriteByte(0x0D, 0x07); // BitFraming
    RC522_WriteByte(0x1C, req);

    card_type[0] = RC522_ReadByte(0x22);
    card_type[1] = RC522_ReadByte(0x21);
    return 0;
}

防冲突 & 读 UID

uint8_t RC522_Anticoll(uint8_t *uid)
{
    RC522_WriteByte(0x01, 0x0C);
    RC522_WriteByte(0x0D, 0x00);
    RC522_WriteByte(0x1C, 0x93);

    for (int i = 0; i < 5; i++)
        uid[i] = RC522_ReadByte(0x22 + i);

    return 0;
}

四、主函数示例(读取卡号)

uint8_t uid[5];

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_SPI2_Init();
    MX_GPIO_Init();

    RC522_Init();

    while (1)
    {
        if (RC522_Request(0x26, uid) == 0)
        {
            if (RC522_Anticoll(uid) == 0)
            {
                printf("Card UID: %02X %02X %02X %02X\r\n",
                       uid[0], uid[1], uid[2], uid[3]);
            }
        }
        HAL_Delay(500);
    }
}

参考代码 基于STM32 驱动RC522 读RFID程序 www.youwenfan.com/contentcnt/182345.html

五、常见卡类型对照

返回值 卡类型
0x0400 Mifare UltraLight
0x0200 Mifare Classic 1K
0x0800 Mifare Classic 4K

六、调试指南

问题 原因
读不到卡 天线未打开 / 电压不稳
SPI 无响应 CS 没拉低 / SPI 模式错
UID 变化 电磁干扰 / 供电不足
只能读一次 未复位 CommandReg
posted @ 2026-04-20 09:58  yu8yu7  阅读(92)  评论(0)    收藏  举报