【高频RFID】RC522芯片介绍与HC32/STM32应用
文章目录
-
- 一、芯片介绍
-
- 1.1 芯片的优缺点分析
- 1.2 芯片天线设计
- 1.3 芯片应用流程
- 二、RC522与MCU通讯(模拟SPI)
-
- 2.1 RC522功能引脚说明
- 2.2 RC522寄存器常见命令说明
- 2.3 MCU通过SPI操作RC522寄存器
-
- 2.3.1 模拟SPI发送、接收函数
- 2.3.2 读、写RC522内部寄存器
- 三、RC522底层驱动代码详解
-
- 3.1 RC522复位初始化
- 3.2 天线射频控制
- 3.3 MIFARE卡片数据通信
- 3.4 数据CRC校验值计算
- 四、RC522应用驱动代码详解
-
- 4.1 寻卡操作
- 4.2 防冲突操作
- 4.3 选卡操作
- 4.4 密码认证操作
- 4.5 读数据操作
- 4.6 写数据操作
- 4.7 休眠操作
- 五、RC522读卡应用示例
-
- 5.1 M0卡片(Mifare_UltraLight)读取
- 5.2 M1卡片(Mifare_One)读取
一、芯片介绍
RC522是NXP推出的高频RFID读卡芯片(PCD),工作于13.56MHz频段,支持ISO/IEC 14443 Type A标准,兼容MIFARE Classic、Ultralight、NTAG等标签类型。集成了射频发射、接收、编码、解码等多种功能,并支持多种高速非接触式通信协议。
1.1 芯片的优缺点分析
芯片优势 | |
---|---|
高集成度 | 芯片集成射频前端、调制解调器、加密引擎、SPI/I2C接口,无需复杂电路快速实现RFID读写功能 |
超低功耗 | 工作电压范围2.5V–3.3V,休眠模式下电流小于1μA |
芯片局限 | |
弱安全性 | 仅支持Crypto1加密算法(已被破解),易受重放攻击与密钥破解威胁,不适合高安全场景 |
短读写距离 | 读写距离仅4–5cm,受天线尺寸与环境干扰影响大;对比CLRC663的10cm以上距离场景受限 |
协议单一 | 仅支持ISO14443-A协议,不支持Felica或ISO14443-B等协议 |
1.2 芯片天线设计
- 匹配电路参数:天线谐振频率需严格匹配13.56MHz,典型匹配电路含 1–3μH电感与约50pF电容。失配会导致读写距离骤降。
- 布局与尺寸:天线面积越大,磁场覆盖范围越广。推荐采用矩形环状天线(尺寸≥5×5cm),并远离金属物体以减少涡流损耗。
- 电源与信号:使用LDO稳压器单独供电,避免数字电路噪声耦合至射频模块;VCC与GND间并联100nF+10μF电容,抑制高频噪声。
1.3 芯片应用流程
- 寻卡:探测是否有卡片进入感应区
- 防冲突:如果有多张卡,选择其中一张进行通信
- 选卡:选定要操作的卡片
- 认证:对于MIFARE Classic等有权限控制的卡片,需要进行密钥认证
- 读写块数据:对卡片的存储块进行读写操作
- 休眠/唤醒:控制卡片进入低功耗状态
二、RC522与MCU通讯(模拟SPI)
2.1 RC522功能引脚说明
RC522功能引脚 | ||
---|---|---|
引脚编号 | 引脚名称 | 功能描述 |
6 | NRSTPD | 芯片掉电、复位引脚 掉电模式:低电平有效 复位模式:上升沿触发 |
11、13 | TX1、TX2 | 13.56MHz天线驱动引脚 两个引脚输出经过调制的13.56MHz能量载波信号来驱动天线线圈 需调节外部匹配电路(线圈、电阻、电容)达到理想效果 |
23 | IRQ | 中断请求输出(如芯片检测到卡片,会产生下降沿中断信号) |
24 | SDA/RX/NSS | I2C模式:I2C数据线(SDA) UART模式:串行数据接收 SPI模式:SPI片选信号(NSS/CS),低电平有效 |
29 | SCK | SPI模式:主控制器提供的同步时钟 |
30 | MOSI | SPI模式:主出从入(MOSI),MCU向RC522发送数据 |
31 | TX/MISO | UART模式:串行数据发送 SPI模式:主入从出(MISO),RC522向MCU发送数据 |
2.2 RC522寄存器常见命令说明
RC522寄存器命令 | ||
---|---|---|
地址 | 名称 | 功能描述 |
0x01 | CommandReg | 启动和停止命令的执行 |
0x02 | ComIEnReg | 中断使能寄存器 |
0x04 | ComIrqReg | 中断请求标志寄存器 |
0x06 | ErrorReg | 错误寄存器 |
0x08 | Status2Reg | 发射、接收状态寄存器 |
0x09 | FIFODataReg | 64字节FIFO数据缓冲寄存器 |
0x0A | FIFOLevelReg | FIFO级别寄存器(缓冲区字节数) |
0x0C | ControlReg | 控制寄存器(控制FIFO缓冲区的行为) |
0x11 | ModeReg | 模式寄存器(芯片发送、接收工作模式设置) |
0x14 | TxControlReg | 发送器控制寄存器(控制天线驱动引脚TX1、TX2的输出模式和信号) |
0x26 | RFCfgReg | 接收器增益参数寄存器(显著影响读写距离) |
2.3 MCU通过SPI操作RC522寄存器
主从式连接中,SPI 使用 4 根信号线进行通信。对于模拟SPI,MCU需要控制SCK、MOSI、MISO、CS 这4个GPIO 引脚;针对HC32的MCU,模拟SPI引脚定义以及初始化如下:
#define RC522_PORT (PortA)
#define RC522_RST_PIN (Pin11) # 复位引脚
#define SPI_CS_PIN (Pin15) # 片选引脚
#define SPI_SCK_PIN (Pin08) # 时钟引脚
#define SPI_SO_PIN (Pin09) # MOSI引脚(MCU输出,芯片输入)
#define SPI_SI_PIN (Pin10) # MISO引脚(MCU输入,芯片输出)#define RC522_RST_L() PORT_ResetBits(RC522_PORT, RC522_RST_PIN)
#define RC522_RST_H() PORT_SetBits(RC522_PORT, RC522_RST_PIN)#define SPI_CS_L() PORT_ResetBits(PortB, SPI_CS_PIN)
#define SPI_CS_H() PORT_SetBits(PortB, SPI_CS_PIN)#define SPI_SCLK_L() PORT_ResetBits(RC522_PORT, SPI_SCK_PIN)
#define SPI_SCLK_H() PORT_SetBits(RC522_PORT, SPI_SCK_PIN)#define SPI_SO_L() PORT_ResetBits(RC522_PORT,SPI_SO_PIN)
#define SPI_SO_H() PORT_SetBits(RC522_PORT, SPI_SO_PIN)/*** @Description: RC522引脚配置* @return {*}*/
void RC522_GPIO_Config(void)
{stc_port_init_t stcPortInit;MEM_ZERO_STRUCT(stcPortInit);stcPortInit.enPinMode = Pin_Mode_Out;stcPortInit.enExInt = Disable;stcPortInit.enPullUp = Enable;// 输出引脚配置PORT_Init(PortB, SPI_CS_PIN, &stcPortInit);PORT_Init(RC522_PORT, SPI_SCK_PIN, &stcPortInit);PORT_Init(RC522_PORT, SPI_SO_PIN, &stcPortInit);PORT_Init(RC522_PORT, RC522_RST_PIN, &stcPortInit);// 输入引脚配置stcPortInit.enPinMode = Pin_Mode_In;stcPortInit.enExInt = Disable;stcPortInit.enPullUp = Enable;PORT_Init(RC522_PORT, SPI_SI_PIN, &stcPortInit); SPI_CS_H();SPI_SCLK_H();SPI_SO_H();
}
2.3.1 模拟SPI发送、接收函数
/*** @Description: 模拟SPI发送数据* @param data 发送数据*/
void SPI_RC522_SendByte(uint8_t data)
{for (uint8_t i = 0; i < 8; i++) {if (data & 0x80) {SPI_SO_H();} else {SPI_SO_L();}SPI_SCLK_H();data <<= 1;SPI_SCLK_L();Ddl_Delay1us(10);}
}/*** @Description: 模拟SPI读数据* @return {*} 读出的值*/
uint8_t SPI_RC522_ReadByte(void)
{uint8_t data;for (uint8_t i = 0; i < 8; i++) {SPI_SCLK_H();data <<= 1;if (PORT_GetBit(RC522_PORT, SPI_SI_PIN) == Set) {data |= 1;}Ddl_Delay1us(5);SPI_SCLK_L();}return data;
}
2.3.2 读、写RC522内部寄存器
通过SPI通讯读取、写入 RC522 芯片内部寄存器函数。RC522中规定SPI通讯发送的地址数据中:最高位(MSB)为命令字节(1:写操作,0:读操作)、最低位(LSB)为0、其余6位为地址数据;因此在地址发送前需先将地址左移1位确保最高、最低位为0,再对最高位命令字节进行设置。
/*** @Description: 读RC522寄存器* @param Address 寄存器地址* @return {*} 读出的值*/
uint8_t ReadRawRC(uint8_t Address)
{uint8_t ucAddr;uint8_t ucResult = 0;ucAddr = ((Address << 1) & 0x7E) | 0x80;SPI_SCLK_L();SPI_CS_L();SPI_RC522_SendByte(ucAddr);ucResult = SPI_RC522_ReadByte();SPI_CS_H();return ucResult;
}/*** @Description: 写RC522寄存器* @param Address 寄存器地址* @param value 写入的值* @return {*}*/
void WriteRawRC(uint8_t Address, uint8_t value)
{uint8_t ucAddr;ucAddr = ((Address << 1) & 0x7E);SPI_SCLK_L();SPI_CS_L()