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

c 复制代码
#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 读写
c 复制代码
#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 初始化
c 复制代码
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)
c 复制代码
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
c 复制代码
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;
}

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

c 复制代码
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/contentcst/182345.html

五、常见卡类型对照

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

六、调试指南

问题 原因
读不到卡 天线未打开 / 电压不稳
SPI 无响应 CS 没拉低 / SPI 模式错
UID 变化 电磁干扰 / 供电不足
只能读一次 未复位 CommandReg
相关推荐
Groundwork Explorer11 小时前
W5500 网卡编程初始化与使用指南
python·单片机
智闲电子设计13 小时前
STM32 SD 卡 + FatFS 实战:掉电丢数据?f_sync 和簇对齐写救你
stm32·单片机·嵌入式硬件
ヾChen15 小时前
ESP32 OTA 踩坑实录
stm32·单片机·嵌入式硬件·物联网·学习
DevHub15 小时前
probe-rs 教程:一行命令替代 OpenOCD 烧写调试 Cortex-M
arm开发·嵌入式硬件·mcu·rust
小僧景贤15 小时前
嵌入式ADC高阶深度解析:基于STM32底层原理、误差溯源、硬件调校与工业级落地
单片机·嵌入式硬件·stm32 adc·工业级高精度采集·adc 误差校准·量产固件开发
黑猫学长呀15 小时前
【驱动开发常见问题】编译出现rm: cannot remove `asm/arch‘: Is a directory
驱动开发·单片机·嵌入式硬件·bug·编译报错·kernrl
雨田言炎16 小时前
STM32专题之内部FLASH详解
笔记·stm32·单片机
Be for thing18 小时前
【嵌入式成长10】STC89C51蜂鸣器|有源/无源蜂鸣器区分、三极管驱动、定时器播放音乐实战
单片机·嵌入式硬件·学习
郎哥编程课堂19 小时前
单片机零基础训练营第2天:嵌入式开发常用的三种进制
单片机·嵌入式硬件
LCG元19 小时前
STM32 DAC+DMA+定时器触发生成任意波形:数据对齐陷阱、输出缓冲器选型与频率精度实测
stm32·单片机·嵌入式硬件