本文主控采用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连接
RC522 | STM32 |
---|---|
3.3V | 3.3V |
GND | GND |
RST | PC4 |
MISO | PA7 |
MOSI | PA6 |
SCK | PA5 |
SDA | PA4 |
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