文章目录
- 一、ID卡、IC卡(M1卡、CPU卡)的区别
- 二、RC522读写操作
- 1. 数据读写流程
- 三、RC522驱动代码
- 1. RC522 与 STM32 的接线图
- 2. RC522.c
- 3. RC522.h
- 4. main.c
一、ID卡、IC卡(M1卡、CPU卡)的区别
- ID卡 :只存储了ID号,设备识别ID号,没有算法可言,容易复制,安全性低
IC卡包含了M1卡和CPU卡
- M1卡:存储了ID号,可读写数据,M1卡发一个数据到设备,设备再传一个数据给M1卡确认,再进行交易或身份认证,只有一个算法,可在空中盗-取信息,反复计算,算出其中算法,在复制卡,安全性比ID卡高很多,但还是能被破解
- CPU卡:有操作系统,可存储数据,也有自己的ID号,CPU卡发一串数据给设备,设备与SAM卡进行运算,设备再发一串数据回CPU卡确认,然后进行交易或身份认证;跟M1卡的区别在于一个算法在空中,一个算法在设备里面;无论是卡商,设备商,运营商,都不知道其中的算法,所以这个系统的安全性会高很多
M1卡介绍 :
M1 卡分为 16 个扇区,每个扇区由 4 块(块 0、块 1、块 2、块 3)组成,(我们也将 16 个扇区的 64 个块按绝对地址编号为 0~63,存贮结构(其它扇区依此类推)如下图所示:
每个扇区的块 0、块 1、块 2 为数据块,可用于存贮数据。数据块可作两种应用:
1、用作一般的数据保存,可以进行读、写操作。
2、用作数据值,可以进行初始化值、加值、减值、读值操作
每个扇区的块 3 为控制块,包括了密码 A、存取控制、密码 B。具体结构如下:
二、RC522读写操作
1. 数据读写流程
三、RC522驱动代码
1. RC522 与 STM32 的接线图
硬件平台:正点原子精英开发板 – STM32F103ZET6
*1--SDA <----->PA4--片选脚
*2--SCK <----->PA5--时钟线
*3--MOSI<----->PA7--输出
*4--MISO<----->PA6--输入
*5--悬空
*6--GND <----->GND
*7--RST <----->PA11--复位脚
*8--VCC <----->VCC
2. RC522.c
#include "rc522.h"
#include "string.h"
#include "./SYSTEM/usart/usart.h"#include "RC522.h"
#include "string.h"/*
函数功能:移植接口--SPI时序读写一个字节
函数参数:data:要写入的数据
返 回 值:读到的数据
*/
uint8_t RC522_SPI_ReadWriteOneByte(uint8_t tx_data)
{ uint8_t rx_data=0; uint8_t i;for(i=0;i<8;i++){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);; if(tx_data&0x80){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 1);}else {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);}tx_data<<=1; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);;rx_data<<=1;if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6))rx_data|=0x01;}//检测spi是否接通
// if(rx_data != 0) {
// printf("rx_data != 0\r\n");
// } else {
// printf("rx_data = 0\r\n");
// }return rx_data;
}/*
函数功能:初始化RC522的IO口
*1--SDA <----->PA4--片选脚
*2--SCK <----->PA5--时钟线
*3--MOSI<----->PA7--输出
*4--MISO<----->PA6--输入
*5--悬空
*6--GND <----->GND
*7--RST <----->PA11--复位脚
*8--VCC <----->VCC
*/
void RC522_IO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_11, GPIO_PIN_SET);/*Configure GPIO pins : PA4 PA5 PA7 PA11 */GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/*Configure GPIO pin : PA6 */GPIO_InitStruct.Pin = GPIO_PIN_6;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);} /*
功能描述:选卡读取卡存储器容量
输入参数:serNum 传入卡序列号
返 回 值:成功返回卡容量
*/
uint8_t RC522_MFRC522_SelectTag(uint8_t *serNum) //读取卡存储器容量
{ uint8_t i; uint8_t status; uint8_t size; uint8_t recvBits; uint8_t buffer[9];buffer[0]=PICC_ANTICOLL1; //防撞码1 buffer[1]=0x70;buffer[6]=0x00; for(i=0;i<4;i++) {buffer[i+2]=*(serNum+i); //buffer[2]-buffer[5]为卡序列号buffer[6]^=*(serNum+i); //卡校验码}RC522_CalulateCRC(buffer,7,&buffer[7]); //buffer[7]-buffer[8]为RCR校验码RC522_ClearBitMask(Status2Reg,0x08);status=RC522_PcdComMF522(PCD_TRANSCEIVE,buffer,9,buffer,&recvBits);if((status==MI_OK)&&(recvBits==0x18)) size=buffer[0]; else size=0;return size;
}/*
延时函数,纳秒级
*/
void RC522_Delay(uint32_t ns)
{uint32_t i;for(i=0;i<ns;i++){__nop();__nop();__nop();}
}/*
函数功能:RC522芯片初始化
*/
void RC522_Init(void)
{RC522_IO_Init(); //RC522初始化RC522_PcdReset(); //复位RC522 RC522_PcdAntennaOff(); //关闭天线DelayMs(2); //延时2毫秒RC522_PcdAntennaOn(); //开启天线M500PcdConfigISOType('A'); //设置RC632的工作方式
}/*
函数功能:复位RC522
*/
void RC522_Reset(void)
{RC522_PcdReset(); //复位RC522RC522_PcdAntennaOff(); //关闭天线DelayMs(2); //延时2毫秒RC522_PcdAntennaOn(); //开启天线
} /*
功 能: 寻卡
参数说明: req_code[IN]:寻卡方式0x52 = 寻感应区内所有符合14443A标准的卡0x26 = 寻未进入休眠状态的卡pTagType[OUT]:卡片类型代码0x4400 = Mifare_UltraLight0x0400 = Mifare_One(S50)0x0200 = Mifare_One(S70)0x0800 = Mifare_Pro(X)0x4403 = Mifare_DESFire
返 回 值: 成功返回MI_OK
*/
char RC522_PcdRequest(uint8_t req_code,uint8_t *pTagType)
{char status; uint8_t unLen;uint8_t ucComMF522Buf[MAXRLEN]; // MAXRLEN 18RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位,/接收数据命令RC522_WriteRawRC(BitFramingReg,0x07); //写RC632寄存器RC522_SetBitMask(TxControlReg,0x03); //置RC522寄存器位ucComMF522Buf[0]=req_code; //寻卡方式status=RC522_PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen); //通过RC522和ISO14443卡通讯if((status==MI_OK)&&(unLen==0x10)){ *pTagType=ucComMF522Buf[0];*(pTagType+1)=ucComMF522Buf[1];}else{status = MI_ERR;} return status;
}/*
功 能: 防冲撞
参数说明: pSnr[OUT]:卡片序列号,4字节
返 回: 成功返回MI_OK
*/
char RC522_PcdAnticoll(uint8_t *pSnr)
{char status;uint8_t i,snr_check=0;uint8_t unLen;uint8_t ucComMF522Buf[MAXRLEN]; RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位 RC522_WriteRawRC(BitFramingReg,0x00); //写RC522_ClearBitMask(CollReg,0x80); //清ucComMF522Buf[0]