【STM32】STM32+RC522-射频IC识别模块

看了很多文章都没有详细讲过RC522和IC卡,这里总结一下,做个笔记

一、RC522

RFID-RC522 是一种常见的射频识别(RFID)模块,用于近距离无线通信。以下是一些基本信息:

主要特点

  • 通信协议: 使用 SPI 通信,与单片机、树莓派等设备轻松集成。
  • 频率: 工作在 13.56 MHz 的高频(HF)范围。
  • 支持协议: 符合 ISO/IEC 14443 标准,支持 MIFARE 卡(如 MIFARE Classic 1K/4K 等)。
  • 供电电压: 通常为 3.3V,但部分模块支持 5V 电平输入。
  • 读写范围: 一般在 2-5 厘米,具体取决于天线设计和环境。

常用功能

  1. 读取卡片 UID: 可以获取 RFID 卡的唯一标识符。
  2. 读写数据块: 支持对 MIFARE 卡片的数据块进行读写操作(需要密钥认证)。
  3. 防碰撞机制: 可识别多个卡片并与目标卡通信。
  4. 功耗低: 支持节能模式。

硬件接口

RC522 模块有以下引脚:

  • VCC: 供电(3.3V 或 5V,取决于模块设计)。
  • GND: 地。
  • SCK: SPI 时钟。
  • MOSI: 主机输出从机输入。
  • MISO: 主机输入从机输出。
  • NSS/SDA: SPI 片选/模块选择。
  • RST: 模块复位。

常见应用

  • 门禁系统。
  • 电子支付。
  • 智能考勤。
  • 物流追踪。

二、IC卡

关于详细的IC卡的介绍可以看下面这个链接,讲的非常详细

【【教程】手把手教你玩转IC卡(门禁卡、电梯卡、饭卡、水卡、校园卡、一卡通)】https://www.bilibili.com/video/BV11h4y1T7Pm?vd_source=065123a0ee559bc650cb8a6e66c8de94

我们生活中常见的一般都是cuid卡,它有16个扇区,依次为0扇区-15扇区,每个扇区又分为4个区块,一个区块有16个字节,所以一个扇区有64个字节,卡总共有1024个字节,就是1KB。

卡的0扇区的第一个区块包含了卡号,校验值,卡类型,卡类型代号,生产厂商信息。第一个区块的前四个字节是卡号,所以我们的卡号是00 00 00 00 - FF FF FF FF的范围内,如果卡号是唯一的,那么就有16^8=4294967296个卡号,42亿多个,一时半会儿也用不完,如果用完了也可以像ipv4->ipv6那样扩展,将六个字节作为卡号,那不就取之不尽用之不竭了吗。我们的身份证的卡号就是6个字节的卡号。当 4 字节 UID 不足以满足需求时,可以使用 7 字节或 10 字节的 UID。这类似于互联网的 IPv4 向 IPv6 的扩展,虽然理论上有限,但可以通过增加长度来大幅度扩展编号空间。

做一个简易门禁系统可以通过验证uid(卡号)来验证身份,但是问题就是卡号很容易被复制,所以我们就可以用上其他扇区。每个扇区的第四个区块是控制块,在这个区块中,前六个字节是密钥A,后六个字节是密钥B,中间四个字节一般是厂商写好固定的FF 07 80 69。我们想要增加门禁系统的安全性,就可以将01扇区(第2扇区)的第1区块的第一个字节设置为FF,如果你这个字节是FF那你就是我们小区的,如果不是FF就不是我们小区的。在我们读取这个区块的内容的时候,需要验证密钥A或者秘钥B才能访问这个扇区里面的数据,所以我们还可以修改密钥实现简单的加密效果,这里配上后面的代码更好理解。

三、通信前的准备

我们使用stm32个四个GPIO模拟SPI与RC522进行通信

1、SPI协议层

/*引脚配置*/
#define RC522_CS(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)(x))
#define RC522_SCK(x)	GPIO_WriteBit(GPIOB, GPIO_Pin_13, (BitAction)(x))
#define RC522_DO(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_15, (BitAction)(x))
#define RC522_DI()		GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)


//-------------------------------------------------------------------------------------------------------------------
// 函数简介     通过 RC522 向设备发送一个字节的数据
// 参数说明     uint8_t data  - 要发送的数据字节
// 返回参数     void
// 使用示例     RC522_SendByte(0x3F); // 发送一个字节 0x3F 到 RC522
// 备注信息     该函数通过控制 SCK 引脚来逐位发送数据,每发送一个位,SCK 会先拉高再拉低。
//              发送完成后,SCK 会返回低电平,等待下一位数据发送。
//-------------------------------------------------------------------------------------------------------------------
void RC522_SendByte(uint8_t data) 
{
    for (uint8_t i = 0; i < 8; i++) 
	{
        // 发送高位
        RC522_DO(data & 0x80);
        data <<= 1;

        // 拉高 SCK
        RC522_SCK(1);
        RC522_Delay(1);

        // 拉低 SCK
        RC522_SCK(0);
        RC522_Delay(1);
    }
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     从 RC522 读取一个字节的数据
// 参数说明     void
// 返回参数     uint8_t - 读取到的字节数据
// 使用示例     uint8_t byte = RC522_ReadByte(); // 从 RC522 读取一个字节的数据
// 备注信息     该函数通过 SCK 引脚控制 SPI 时钟,读取 MISO 引脚的数据,逐位构建接收到的数据字节。
//-------------------------------------------------------------------------------------------------------------------
uint8_t RC522_ReadByte(void) 
{
    uint8_t data = 0;
    for (uint8_t i = 0; i < 8; i++) 
	{
        // 拉高 SCK
        RC522_SCK(1);
        RC522_Delay(1);

        // 读取 MISO 引脚
        data <<= 1;
        if (RC522_DI())
		{
            data |= 0x01;
        }

        // 拉低 SCK
        RC522_SCK(0);
        RC522_Delay(1);
    }
    return data;
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     向 RC522 寄存器写入一个字节的数据
// 参数说明     uint8_t addr - 寄存器地址
//              uint8_t value - 要写入的数据
// 返回参数     void
// 使用示例     RC522_WriteReg(0x01, 0x0F); // 向 RC522 的地址为 0x01 的寄存器写入值 0x0F
// 备注信息     该函数通过 SPI 总线向指定寄存器写入数据。发送时会先发送寄存器地址,地址最低位为 0 表示写操作,然后发送要写入的值。          
//-------------------------------------------------------------------------------------------------------------------
void RC522_WriteReg(uint8_t addr, uint8_t value) 
{
    RC522_CS(0); // 片选拉
06-02
RC522是一种RFID读写模块,它可以通过射频识别技术实现对RFID标签的读写操作。以下是使用RC522模块进行读取操作的示例代码: ```c #include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/gpio.h" #include "driver/spi_master.h" #include "mfrc522.h" static const char *TAG = "rc522"; void rc522_task(void *pvParameter) { ESP_LOGI(TAG, "RC522 task started"); spi_device_handle_t spi; spi_bus_config_t buscfg = { .miso_io_num = PIN_NUM_MISO, .mosi_io_num = PIN_NUM_MOSI, .sclk_io_num = PIN_NUM_CLK, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = MFRC522_MAX_LEN }; spi_device_interface_config_t devcfg = { .clock_speed_hz = 5000000, .mode = 0, .spics_io_num = PIN_NUM_CS, .queue_size = 7 }; esp_err_t ret; ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1); assert(ret == ESP_OK); ret = spi_bus_add_device(HSPI_HOST, &devcfg, &spi); assert(ret == ESP_OK); mfrc522_init(spi); while (1) { uint8_t uid[MFRC522_MAX_LEN]; uint8_t uid_len = sizeof(uid); if (mfrc522_request(spi, PICC_REQIDL, uid, &uid_len) == MFRC522_STATUS_OK) { ESP_LOGI(TAG, "Card detected"); if (mfrc522_get_card_type(uid[0]) == MFRC522_CARDTYPE_MIFARE1K) { ESP_LOGI(TAG, "Card type: MIFARE 1K"); uint8_t key[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t sector = 1; uint8_t block = 4; if (mfrc522_authenticate(spi, PICC_AUTHENT1A, sector, key, uid, uid_len) == MFRC522_STATUS_OK) { uint8_t data[MFRC522_BLOCK_SIZE]; if (mfrc522_read_block(spi, sector * 4 + block, data) == MFRC522_STATUS_OK) { ESP_LOGI(TAG, "Block %d data: %s", sector * 4 + block, data); } else { ESP_LOGE(TAG, "Read block failed"); } } else { ESP_LOGE(TAG, "Authenticate failed"); } } else { ESP_LOGE(TAG, "Unsupported card type"); } } vTaskDelay(1000 / portTICK_PERIOD_MS); } } void app_main() { xTaskCreate(rc522_task, "rc522_task", 2048, NULL, 10, NULL); } ``` 这个示例代码使用ESP32的HSPI接口与RC522模块进行通信,并且可以读取MIFARE 1K标签的数据。可以根据需要修改代码以实现其他操作。需要注意的是,RC522模块的接线需要参考其数据手册进行,以确保正确连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值