目录
一、前言
RC522读卡器是一种常用的射频识别模块,通常用于与RFID标签进行通信。它可以读取和写入RFID标签上的信息,常见于门禁系统、智能卡、物联网设备等领域。RC522读卡器具有简单易用的特点,通过SPI接口与微控制器通信,适用于各种嵌入式系统和DIY项目。
二、资料获取
关注微信公众号--星之援工作室 发送关键字(RC522)
这里的话直接是采用的网上开源的资料进行书写,借花献佛咯
➡️🫡🫡🫡🫡🫡🫡🫡🫡➡️
三、代码编写
注意事项:这款设备是采用模拟 SPI 的方式进行控制和读取的,所以大家可以自由规划 io 口使用(实例程序的接口如下)
rc522_config.c
#include "rc522_config.h"
#include "stm32f10x.h"
static void RC522_SPI_Config ( void );
/**
* @brief RC522_Init
* @param 无
* @retval 无
*/
void RC522_Init ( void )
{
RC522_SPI_Config ();
RC522_Reset_Disable();
RC522_CS_Disable();
}
/**
* @brief R522 SPI配置
* @param 无
* @retval 无
*/
static void RC522_SPI_Config ( void )
{
/* SPI_InitTypeDef SPI_InitStructure */
GPIO_InitTypeDef GPIO_InitStructure;
/*!< Configure SPI_RC522_SPI pins: CS */
RC522_GPIO_CS_CLK_FUN ( RC522_GPIO_CS_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = RC522_GPIO_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = RC522_GPIO_CS_Mode;
GPIO_Init(RC522_GPIO_CS_PORT, &GPIO_InitStructure);
/*!< Configure SPI_RC522_SPI pins: SCK */
RC522_GPIO_SCK_CLK_FUN ( RC522_GPIO_SCK_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = RC522_GPIO_SCK_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = RC522_GPIO_SCK_Mode;
GPIO_Init(RC522_GPIO_SCK_PORT, &GPIO_InitStructure);
/*!< Configure SPI_RC522_SPI pins: MOSI */
RC522_GPIO_MOSI_CLK_FUN ( RC522_GPIO_MOSI_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = RC522_GPIO_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = RC522_GPIO_MOSI_Mode;
GPIO_Init(RC522_GPIO_MOSI_PORT, &GPIO_InitStructure);
/*!< Configure SPI_RC522_SPI pins: MISO */
RC522_GPIO_MISO_CLK_FUN ( RC522_GPIO_MISO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = RC522_GPIO_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = RC522_GPIO_MISO_Mode;
GPIO_Init(RC522_GPIO_MISO_PORT, &GPIO_InitStructure);
/*!< Configure SPI_RC522_SPI pins: RST */
RC522_GPIO_RST_CLK_FUN ( RC522_GPIO_RST_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = RC522_GPIO_RST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = RC522_GPIO_RST_Mode;
GPIO_Init(RC522_GPIO_RST_PORT, &GPIO_InitStructure);
}
rc522_config.h
#ifndef __RC522_CONFIG_H
#define __RC522_CONFIG_H
/
//MF522命令字
/
#define PCD_IDLE 0x00 //取消当前命令
#define PCD_AUTHENT 0x0E //验证密钥
#define PCD_RECEIVE 0x08 //接收数据
#define PCD_TRANSMIT 0x04 //发送数据
#define PCD_TRANSCEIVE 0x0C //发送并接收数据
#define PCD_RESETPHASE 0x0F //复位
#define PCD_CALCCRC 0x03 //CRC计算
/
//Mifare_One卡片命令字
/
#define PICC_REQIDL 0x26 //寻天线区内未进入休眠状态
#define PICC_REQALL 0x52 //寻天线区内全部卡
#define PICC_ANTICOLL1 0x93 //防冲撞
#define PICC_ANTICOLL2 0x95 //防冲撞
#define PICC_AUTHENT1A 0x60 //验证A密钥
#define PICC_AUTHENT1B 0x61 //验证B密钥
#define PICC_READ 0x30 //读块
#define PICC_WRITE 0xA0 //写块
#define PICC_DECREMENT 0xC0 //扣款
#define PICC_INCREMENT 0xC1 //充值
#define PICC_RESTORE 0xC2 //调块数据到缓冲区
#define PICC_TRANSFER 0xB0 //保存缓冲区中数据
#define PICC_HALT 0x50 //休眠
/
//MF522 FIFO长度定义
/
#define DEF_FIFO_LENGTH 64 //FIFO size=64byte
#define MAXRLEN 18
/
//MF522寄存器定义
/
// PAGE 0
#define RFU00 0x00
#define CommandReg 0x01
#define ComIEnReg 0x02
#define DivlEnReg 0x03
#define ComIrqReg 0x04
#define DivIrqReg 0x05
#define ErrorReg 0x06
#define Status1Reg 0x07
#define Status2Reg 0x08
#define FIFODataReg 0x09
#define FIFOLevelReg 0x0A
#define WaterLevelReg 0x0B
#define ControlReg 0x0C
#define BitFramingReg 0x0D
#define CollReg 0x0E
#define RFU0F 0x0F
// PAGE 1
#define RFU10 0x10
#define ModeReg 0x11
#define TxModeReg 0x12
#define RxModeReg 0x13
#define TxControlReg 0x14
#define TxAutoReg 0x15
#define TxSelReg 0x16
#define RxSelReg 0x17
#define RxThresholdReg 0x18
#define DemodReg 0x19
#define RFU1A 0x1A
#define RFU1B 0x1B
#define MifareReg 0x1C
#define RFU1D 0x1D
#define RFU1E 0x1E
#define SerialSpeedReg 0x1F
// PAGE 2
#define RFU20 0x20
#define CRCResultRegM 0x21
#define CRCResultRegL 0x22
#define RFU23 0x23
#define ModWidthReg 0x24
#define RFU25 0x25
#define RFCfgReg 0x26
#define GsNReg 0x27
#define CWGsCfgReg 0x28
#define ModGsCfgReg 0x29
#define TModeReg 0x2A
#define TPrescalerReg 0x2B
#define TReloadRegH 0x2C
#define TReloadRegL 0x2D
#define TCounterValueRegH 0x2E
#define TCounterValueRegL 0x2F
// PAGE 3
#define RFU30 0x30
#define TestSel1Reg 0x31
#define TestSel2Reg 0x32
#define TestPinEnReg 0x33
#define TestPinValueReg 0x34
#define TestBusReg 0x35
#define AutoTestReg 0x36
#define VersionReg 0x37
#define AnalogTestReg 0x38
#define TestDAC1Reg 0x39
#define TestDAC2Reg 0x3A
#define TestADCReg 0x3B
#define RFU3C 0x3C
#define RFU3D 0x3D
#define RFU3E 0x3E
#define RFU3F 0x3F
/
//和MF522通讯时返回的错误代码
/
#define MI_OK 0x26
#define MI_NOTAGERR 0xcc
#define MI_ERR 0xbb
/*********************************** RC522 引脚定义 *********************************************/
//RC522模块有除了电源还有6个数据引脚,其中IRQ不需要使用,悬空即可,剩下的5个数据引脚连接如下:
//如果RC522需要修改与STM32的连接,则修改这些IO即可,但必须连接到STM32的SPI引脚
//片选,即RC522模块的SDA引脚
#define RC522_GPIO_CS_CLK_FUN RCC_APB2PeriphClockCmd
#define RC522_GPIO_CS_CLK RCC_APB2Periph_GPIOA
#define RC522_GPIO_CS_PORT GPIOA
#define RC522_GPIO_CS_PIN GPIO_Pin_3
#define RC522_GPIO_CS_Mode GPIO_Mode_Out_PP
//时钟,即RC522模块的SCK引脚,接STM32的SPI的SCK引脚
#define RC522_GPIO_SCK_CLK_FUN RCC_APB2PeriphClockCmd
#define RC522_GPIO_SCK_CLK RCC_APB2Periph_GPIOA
#define RC522_GPIO_SCK_PORT GPIOA
#define RC522_GPIO_SCK_PIN GPIO_Pin_5
#define RC522_GPIO_SCK_Mode GPIO_Mode_Out_PP
// 数据输入,即即RC522模块的MOSI引脚,接STM32的SPI的MOSI引脚
#define RC522_GPIO_MOSI_CLK_FUN RCC_APB2PeriphClockCmd
#define RC522_GPIO_MOSI_CLK RCC_APB2Periph_GPIOA
#define RC522_GPIO_MOSI_PORT GPIOA
#define RC522_GPIO_MOSI_PIN GPIO_Pin_7
#define RC522_GPIO_MOSI_Mode GPIO_Mode_Out_PP
// 数据输出,即即RC522模块的MISO引脚,接STM32的SPI的MISO引脚
#define RC522_GPIO_MISO_CLK_FUN RCC_APB2PeriphClockCmd
#define RC522_GPIO_MISO_CLK RCC_APB2Periph_GPIOA
#define RC522_GPIO_MISO_PORT GPIOA
#define RC522_GPIO_MISO_PIN GPIO_Pin_6
#define RC522_GPIO_MISO_Mode GPIO_Mode_IN_FLOATING
//复位,即即RC522模块的RST引脚,接STM32的普通IO即可
#define RC522_GPIO_RST_CLK_FUN RCC_APB2PeriphClockCmd
#define RC522_GPIO_RST_CLK RCC_APB2Periph_GPIOA
#define RC522_GPIO_RST_PORT GPIOA
#define RC522_GPIO_RST_PIN GPIO_Pin_2
#define RC522_GPIO_RST_Mode GPIO_Mode_Out_PP
/*********************************** RC522 函数宏定义*********************************************/
#define RC522_CS_Enable() GPIO_ResetBits ( RC522_GPIO_CS_PORT, RC522_GPIO_CS_PIN )
#define RC522_CS_Disable() GPIO_SetBits ( RC522_GPIO_CS_PORT, RC522_GPIO_CS_PIN )
#define RC522_Reset_Enable() GPIO_ResetBits( RC522_GPIO_RST_PORT, RC522_GPIO_RST_PIN )
#define RC522_Reset_Disable() GPIO_SetBits ( RC522_GPIO_RST_PORT, RC522_GPIO_RST_PIN )
#define RC522_SCK_0() GPIO_ResetBits( RC522_GPIO_SCK_PORT, RC522_GPIO_SCK_PIN )
#define RC522_SCK_1() GPIO_SetBits ( RC522_GPIO_SCK_PORT, RC522_GPIO_SCK_PIN )
#define RC522_MOSI_0() GPIO_ResetBits( RC522_GPIO_MOSI_PORT, RC522_GPIO_MOSI_PIN )
#define RC522_MOSI_1() GPIO_SetBits ( RC522_GPIO_MOSI_PORT, RC522_GPIO_MOSI_PIN )
#define RC522_MISO_GET() GPIO_ReadInputDataBit ( RC522_GPIO_MISO_PORT, RC522_GPIO_MISO_PIN )
/*********************************** 函数 *********************************************/
void RC522_Init ( void );
#endif /* __RC522_CONFIG_H */
main
/**
******************************************************************************
* @file main.c
* @author fire
* @version V1.0
* @date 2013-xx-xx
* @brief RFID-RC522模块实验
******************************************************************************
*/
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include "bsp_usart1.h"
#include "rc522_config.h"
#include "rc522_function.h"
#include <stdbool.h>
#include "bsp_lcd.h"
#include "./font/fonts.h"
#include "./key/bsp_key.h"
extern uint16_t lcdid;
uint8_t KeyValue[]={0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 卡A密钥
//uint8_t KeyValue[]={'1' ,'2', '3', '4', '5', '6'}; // 卡A密钥
/**
* @brief IC测试函数
* @param 无
* @retval 无
*/
void IC_test ( void )
{
uint32_t writeValue = 100;
uint32_t readValue;
char cStr [ 30 ];
uint8_t ucArray_ID [ 4 ]; /*先后存放IC卡的类型和UID(IC卡序列号)*/
uint8_t ucStatusReturn; /*返回状态*/
while ( 1 )
{
/*寻卡*/
if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK )
{
/*若失败再次寻卡*/
printf ( "寻卡失败\n" );
ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); //PICC_REQALL PICC_REQIDL
}
if ( ucStatusReturn == MI_OK )
{
//printf ( "寻卡成功\n" );
/*防冲撞(当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作)*/
if ( PcdAnticoll ( ucArray_ID ) == MI_OK )
{
PcdSelect(ucArray_ID);
PcdAuthState( PICC_AUTHENT1A, 0x11, KeyValue, ucArray_ID );//校验密码
WriteAmount(0x11,writeValue); //写入金额
if(ReadAmount(0x11,&readValue) == MI_OK) //读取金额
{
//writeValue +=100;
sprintf ( cStr, "The Card ID is: %02X%02X%02X%02X",ucArray_ID [0], ucArray_ID [1], ucArray_ID [2],ucArray_ID [3] );
printf ( "%s\r\n",cStr ); //打印卡片ID
ILI9341_DispStringLine_EN(LINE(0), cStr);
printf ("余额为:%d\r\n",readValue);
sprintf ( cStr, "TThe residual amount: %d", readValue);
ILI9341_DispStringLine_EN(LINE(1), cStr );
PcdHalt();
}
/* 按键1检测 */
if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )
{
printf("金额 +100\r\n");
writeValue += 100;
}
/* 按键2检测 */
if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )
{
printf("金额 -100\r\n");
writeValue -= 100;
}
}
}
}
}
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main ( void )
{
/*滴答时钟初始化*/
SysTick_Init ();
/*USART1 配置模式为 115200 8-N-1,中断接收 */
USART1_Config ();
/* Key 初始化 */
Key_GPIO_Config();
/*RC522模块所需外设的初始化配置*/
RC522_Init ();
/*LCD 初始化*/
LCD_Init ();
//判断一下LCD内部IC
if(lcdid == LCDID_ILI9341)
{
ILI9341_GramScan ( 6 );
}
else if(lcdid == LCDID_ST7789V)
{
ILI9341_GramScan ( 0 );
}
printf ( "WF-RC522 Test\n" );
LCD_SetFont(&Font8x16);
LCD_SetColors(RED,BLACK);
/* 清屏,显示全黑 */
ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);
ILI9341_DispStringLine_EN(LINE(13),
"Please put the IC card on WF-RC522 antenna area ..." );
LCD_SetTextColor(BLUE);
PcdReset ();
/*设置工作方式*/
M500PcdConfigISOType ( 'A' );
while ( 1 )
{
/*IC卡检测 */
IC_test ();
}
}
/****************************END OF FILE**********************/
四、参考
野火资料库https://doc.embedfire.com/products/link/zh/latest/index.htmlRC522模块学习
https://blog.csdn.net/hbzdsXCV/article/details/128132423?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171625709616800182718369%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171625709616800182718369&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-128132423-null-null.142^v100^pc_search_result_base7&utm_term=RC522&spm=1018.2226.3001.4187