基于STM32与RC522读写IC卡

本文主控采用STM32F103ZET6,利用RC522完成对IC的读写操作,并将IC卡内容通过STM32串口1发送到串口助手进行显示。附完整代码。

一、RC522简介

1、概述

在这里插入图片描述

2、寄存器概述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
获取资料关注公众号,回复 RC522

3、硬件连接

RC522模块如图所示:
在这里插入图片描述
RC522模块引脚说明

标号IO类型功能描述
3.3V电源电源正
GND电源电源地
RST输入复位
MISO输出SPI口从机输出
MOSI输入SPI口从机输入
SCK输入SPI口时钟
SDA输入SPI口片选
IRQ输出中断请求

RC522模块与STM32连接

RC522STM32
3.3V3.3V
GNDGND
RSTPC4
MISOPA7
MOSIPA6
SCKPA5
SDAPA4
IRQ未接

二、S50非接触式IC卡性能简介(M1)

1、 主要指标

 容量为8K位EEPROM
 分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位
 每个扇区有独立的一组密码及访问控制
 每张卡有唯一序列号,为32位
 具有防冲突机制,支持多卡操作
 无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
 数据保存期为10年,可改写10万次,读无限次
 工作温度:-20℃~50℃(湿度为90%)
 工作频率:13.56MHZ
 通信速率:106 KBPS
 读写距离:10 cm以内(与读写器有关)

2、 存储结构

1、 M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63,存贮结构如下图所示:
在这里插入图片描述

2、 第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。
3、 每个扇区的块0、块1、块2为数据块,可用于存贮数据。
数据块可作两种应用:
★ 用作一般的数据保存,可以进行读、写操作。
★ 用作数据值,可以进行初始化值、加值、减值、读值操作。
4、 每个扇区的块3为控制块,包括了密码A、存取控制、密码B。具体结构如下:
在这里插入图片描述

5、 每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:

      块0:   C10   C20   C30
      块1:   C11   C21   C31
      块2:   C12   C22   C32
      块3:   C13   C23   C33

三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权限(如
进行减值操作必须验证KEY A,进行加值操作必须验证KEY B,等等)。三个控制
位在存取控制字节中的位置,以块0为例:
在这里插入图片描述

6、数据块(块0、块1、块2)的存取控制如下:
在这里插入图片描述
例如:当块0的存取控制位C10 C20 C30=1 0 0时,验证密码A或密码B正确后可读;
验证密码B正确后可写;不能进行加值、减值操作。

7、控制块块3的存取控制与数据块(块0、1、2)不同,它的存取控制如下:

在这里插入图片描述

例如:当块3的存取控制位C13 C23 C33=1 0 0时,表示:
密码A:不可读,验证KEYA或KEYB正确后,可写(更改)。
存取控制:验证KEYA或KEYB正确后,可读、可写。
密码B:验证KEYA或KEYB正确后,可读、可写。

3、 工作原理

卡片的电气部分只由一个天线和ASIC组成。
天线:卡片的天线是只有几组绕线的线圈,很适于封装到IS0卡片中。
ASIC:卡片的ASIC由一个高速(106KB波特率)的RF接口,一个控制单元和一个
8K位EEPROM组成。
工作原理:读写器向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与读写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。

4、 M1射频卡与读写器的通讯

在这里插入图片描述
复位应答(Answer to request)
M1射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为M1射频卡,即验证卡片的卡型。

防冲突机制 (Anticollision Loop)
当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。

选择卡片(Select Tag)
选择被选中的卡的序列号,并同时返回卡的容量代码。

三次互相确认(3 Pass Authentication)
选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验。)

对数据块的操作
读 (Read):读一个块;
写 (Write):写一个块;
加(Increment):对数值块进行加值;
减(Decrement):对数值块进行减值;
存储(Restore):将块中的内容存到数据寄存器中;
传输(Transfer):将数据寄存器中的内容写入块中;
中止(Halt):将卡置于暂停工作状态;

三、STM32程序

主程序

int main(void)
{   
  char status;
	uint8_t snr,TagType[4], SelectedSnr[4], DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
  uint8_t i,temp,num_kuai;
	uint8_t g_ucTempbuf[20];
  uint8_t	buf[16]={'9','1','3','7','1','0','8','2','0','0','0','0','1','0','2','3'};
	GPIO_ini(); 
	USART1_Config();
		
  InitializeSystem( );

	//HMISendb(DEBUG_USART2,0xff);
  while (1)
  {
		//printf("卡的类型2:");
		status= PcdRequest(REQ_ALL,TagType);
		if(!status)
		{
			printf("卡的类型:");
			for(i=0;i<4;i++)
			{
					temp=TagType[i];
					printf("%X",temp);
					//Uart_WByte(temp);
					
			}
			 printf("\n");
			status = PcdAnticoll(SelectedSnr);
			if(!status)
			{
				printf("卡序列号:");	//超级终端显示,
				for(i=0;i<4;i++)
				{
					temp=SelectedSnr[i];
					printf("%X",temp);
					
				}
				 printf("\n");
				status=PcdSelect(SelectedSnr);
				if(!status)
				{
					
						snr = 1;  //扇区号1
						status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块
					
						if(!status)
						{
								for(num_kuai=0;num_kuai<4;num_kuai++)
						    {
									 status = PcdRead((snr*4+num_kuai), g_ucTempbuf);//读块
									 if (!status )
									 {   
											  printf("卡读块%X:",num_kuai);	//超级终端显示,
											  for(i=0;i<16;i++)
												{
														temp=g_ucTempbuf[i];
														printf("%X",temp);
													
												}

						            printf("\n");
						        }
					       }
							
							status = PcdWrite((snr*4+1), buf);  // 写卡,将buf[0]-buf[16]写入0扇区1块
							if(!status)
							{
								//读写成功,点亮LED
								LED_ON;	
								
							}
						WaitCardOff();
						
					}
				}
			}
		}	

	}

}

RC522引脚配置程序

//////////////////////////////////
//端口定义
/////////////////////////////////////////////////////////////////////
//MFRC522
#define MF522_RST_PIN                    GPIO_Pin_4
#define MF522_RST_PORT                   GPIOC
#define MF522_RST_CLK                    RCC_APB2Periph_GPIOC  
  
#define MF522_MISO_PIN                   GPIO_Pin_7
#define MF522_MISO_PORT                  GPIOA
#define MF522_MISO_CLK                   RCC_APB2Periph_GPIOA  

#define MF522_MOSI_PIN                   GPIO_Pin_6  
#define MF522_MOSI_PORT                  GPIOA
#define MF522_MOSI_CLK                   RCC_APB2Periph_GPIOA  

#define MF522_SCK_PIN                    GPIO_Pin_5  
#define MF522_SCK_PORT                   GPIOA
#define MF522_SCK_CLK                    RCC_APB2Periph_GPIOA 

#define MF522_NSS_PIN                    GPIO_Pin_4  
#define MF522_NSS_PORT                   GPIOA
#define MF522_NSS_CLK                    RCC_APB2Periph_GPIOA
void GPIO_ini()
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(MF522_RST_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = MF522_RST_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(MF522_RST_PORT, &GPIO_InitStructure);
	
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(MF522_MISO_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = MF522_MISO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(MF522_MISO_PORT, &GPIO_InitStructure);
	
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(MF522_MOSI_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = MF522_MOSI_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(MF522_MOSI_PORT, &GPIO_InitStructure);
	
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(MF522_SCK_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = MF522_SCK_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(MF522_SCK_PORT, &GPIO_InitStructure);
	
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(MF522_NSS_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = MF522_NSS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(MF522_NSS_PORT, &GPIO_InitStructure);
	
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(LED_CLK, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = LED_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(LED_PORT, &GPIO_InitStructure);
}

四、实验结果

IC卡内容通过STM32串口1发送到串口助手进行显示,将{‘9’,‘1’,‘3’,‘7’,‘1’,‘0’,‘8’,‘2’,‘0’,‘0’,‘0’,‘0’,‘1’,‘0’,‘2’,‘3’}数据写入0扇区1块请添加图片描述
获取资料关注公众号,回复 RC522

RC522是一种基于ISO14443标准的非接触式智能读写设备,广泛应用于各种电子支付、门禁系统以及身份识别等领域。它能够读取和写入ISO14443 A/B标准的IC信息,并通过RS232、SPI或I²C接口微控制器通信。 在STM32微控制器上开发RC522读写程序,主要是为了集成智能处理功能到基于STM32的嵌入式应用中去。以下是基本步骤: ### 硬件准备 1. **RC522模块**:选择一款支持ISO14443协议的RC522模块,如基于ATMEL ATMN78XX系列芯片的模块。 2. **STM32 MCU**:选择适合的STM32型号,比如STM32F0、STM32F1、STM32F4等,取决于您的项目需求和预算。 3. **连接线材**:需要RS232、SPI或I²C电缆将RC522模块连接至STM32。 ### 软件开发 1. **选择开发环境**:使用Keil uVision、STM32CubeIDE等开发环境搭建项目。 2. **配置库文件**:通常需要STM32 HAL库或专用于RC522的库(如SWIPE),以便更好地控制STM32RC522之间的通信。 3. **编写程序**: - 初始化RC522:设置正确的时钟频率、电源管理策略,以及初始化RC522的硬件资源。 - 发送命令:执行读、写操作前,需要向RC522发送特定的命令序列。 - 数据交互:根据ISO14443规范,读取或写入片数据。 - 错误检查处理:对收到的数据进行校验,确保数据的完整性和有效性。 ### 示例程序结构 ```c #include "stm32f1xx_hal.h" // 假设已经包含了必要的头文件和库函数引用 void main(void) { // 初始化RC522模块 RC522_Init(); // 循环等待用户执行读写操作 while (1) { switch (RC522_Antenna_WakeUp()) { case OK: // 成功唤醒天线,尝试连接片 if(RC522_ConnectCard()) { // 已经成功连接片,可以开始读写操作 if(RC522_ReadCardData()) // 读取片数据 { // 处理读取到的数据... } else { // 处理读取失败的情况... } } break; case CARD_NOT_FOUND: // 片未找到 printf("Card not found\n"); break; default: // 其他错误情况 printf("Error in antenna\n"); break; } } } ``` ### 注意事项 - 确保STM32RC522之间的通信速度匹配ISO14443规范的要求。 - 对于复杂的操作,可能需要更详细的错误处理机制和日志记录,便于调试和维护。 - 根据实际应用需求调整程序流程和功能实现细节。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芦苇电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值