STM32F103+RFID-RC522模块 实现简单读卡写卡demo

Posted Love丶伊卡洛斯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103+RFID-RC522模块 实现简单读卡写卡demo相关的知识,希望对你有一定的参考价值。

目录

前言

特别声明:

  • 本仓库发布的程序,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。

  • 本人对任何脚本问题概不负责,包括但不限于由任何脚本错误导致的任何损失或损害。

  • 间接使用脚本的任何用户,包括但不限于建立VPS或在某些行为违反国家/地区法律或相关法规的情况下进行传播, 本人对于由此引起的任何隐私泄漏或其他后果概不负责。

  • 任何以任何方式查看此项目的人或直接或间接使用该项目的任何程序的使用者都应仔细阅读此声明。本人保留随时更改或补充此免责声明的权利。一旦使用并复制了任何相关脚本或Script项目的规则,则视为您已接受此免责声明。

本文不含任何广告性质,仅供学习参考。写卡需谨慎!!!,不然可能会玩崩了。血的教训!!!

参考资料:
浅谈IC卡数据分析
智能卡 ISO14443 协议 解读
STM32F103ZET–RFID-RC522使用例程(战舰版)
M1卡使用说明书
M1卡介绍
STM32-RC522
Mifare1技术说明(M1卡说明文档)
源码参考:RFID-RC522,不能使用,我进行了一定的修改。下载参考下方传送门。
开发板:正点原子 STM32F103 精英版

语言:C语言
开发环境:Keil5
开发板使用了 LED SPI USART RFID-RC522模块 钥匙扣卡 M1卡


Win10软件 SSCOM串口调试 FlyMcu烧录(ps:电脑安装驱动CH340)

安卓软件 NFC Writer (手机需有NFC功能)

代码下载:

码云 GitHub

功能介绍:

寻卡-》防冲撞-》选卡-》验证2扇区密钥-》读取2扇区0区块数据-》写入数据到2扇区0区块-》再读取2扇区0区块数据。
串口打印卡UID,验证结果,读取到的2扇区0区块数据等信息。
注意:只有验证成功的扇区,才能对此扇区进行读写操作!

// 验证A密钥 块地址 密码 SN 
// 注意:此处的块地址0x0B即2扇区3区块,此块地址只需要指向某一扇区就可以了,
// 即2扇区为0x08-0x0B这个范围都有效,且只能对验证过的扇区进行读写操作
status = PcdAuthState(0x60, 0x0B, KEY_A, SN);
// 读取M1卡一块数据 块地址 读取的数据
// 注意:因为上面验证的扇区是2扇区,所以只能对2扇区的数据进行读写,即0x08-0x0B这个范围,
// 超出范围读取失败。
status = PcdRead(0x08, DATA);

另外:3区块的密钥A单片机读取出来是全00,手机是全ff
控制字的默认值是“FF078069”,此时
A密钥:不可被读出,有全部权限
B密钥:可被读出,没有任何权限
下图参考:https://blog.csdn.net/hiwoshixiaoyu/article/details/104048663

接线

1--SDA  <----->PA4
2--SCK  <----->PA5
3--MOSI <----->PA7
4--MISO <----->PA6
5--悬空
6--GND <----->GND
7--RST <----->PB0
8--VCC <----->VCC

STM32

STM32F1开发指南(精英版)-库函数版本_V1.2

STM32中文参考手册


RFID-RC522

参考:https://www.cirmall.com/circuit/2149/

RFID射频模块电路原理图

使用图+效果图

测试程序0 RC522_Handle()

最终效果

一、先用手机软件NFC Writer读取空卡看看内容

1、打开软件和NFC(ps:我的手机是小米10)

2、将空卡贴于手机背部,弹出提示发现新卡,点击“好的”

3、上面的新卡片左滑到新卡片1,单击这个卡片

4、进入卡片信息详细页面

钥匙扣卡

M1空白卡


可以发现2张卡除了卡号和卡号异或值不同外,其他数据都一样,之后的例子都以钥匙扣卡举例。
下图参考:https://blog.csdn.net/hiwoshixiaoyu/article/details/104048663

二、编译、烧写程序

三、将钥匙扣卡发在模块上,打开串口,开始测试


串口打印

注意 原卡 2扇区0区块数据为

我们放上卡后,进行了数据写入,之后读取到的数据都为DATA1的数据0.0

unsigned char DATA1[16]= 0x12,0x34,0x56,0x78,0x9A,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff;
// 0x08 就是2扇区0区块(即第9块)
unsigned char addr=0x08;
status = PcdWrite(addr, DATA1);


此时数据写入完毕后,我们再将钥匙扣卡贴于手机,看看现在手机读取出来的结果

OK,看样子写入成功了,那么到此例程就结束了。

测试程序1 RC522_Handle1()

测试程序1,完成0x0F块 验证KEY_A、KEY_B 读 写RFID1 验证KEY_A1、KEY_B1 读 写RFID2

// 测试用 3区块数据
unsigned char RFID1[16]= 0x10,0x20,0x30,0x40,0x50,0x60,0xff,0x07,0x80,0x29,0x01,0x02,0x03,0x04,0x05,0x06;
unsigned char RFID2[16]= 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff;
// 测试用 3区块密钥
u8 KEY_A1[6]= 0x10,0x20,0x30,0x40,0x50,0x60;
u8 KEY_B1[6]= 0x01,0x02,0x03,0x04,0x05,0x06;

核心代码

main.c

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "rc522.h"
#include "led.h"

/**
*   连线说明:
*   1--SDA  <----->PA4
*   2--SCK  <----->PA5
*   3--MOSI <----->PA7
*   4--MISO <----->PA6
*   5--悬空
*   6--GND <----->GND
*   7--RST <----->PB0
*   8--VCC <----->VCC
**/

int main(void)

    u8 num = 0;
    delay_init();	    	 //延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 	//串口初始化为115200
    LED_Init();
    RC522_Init();       //初始化射频卡模块
    while(1)
    
		// 重要提醒,写卡操作有风险,请勿随意尝试,不能保证程序安全性,本人对任何程序问题概不负责,不限于由任何程序错误导致的任何损失或损害
		// 测试程序0,完成addr读写读
        RC522_Handle();
		// 谨慎使用 测试程序1,完成0x0F块 验证KEY_A、KEY_B 读 写RFID1 验证KEY_A1、KEY_B1 读 写RFID2
		// RC522_Handle1();

        if(num % 20 == 0)
            LED0 = !LED0;
        num++;
    


rc522.h

#ifndef __RC522_H
#define __RC522_H
#include "sys.h"
#include "stm32f10x.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                 0
#define 	MI_NOTAGERR           (1)
#define 	MI_ERR                (2)

#define	SHAQU1	0X01
#define	KUAI4	0X04
#define	KUAI7	0X07
#define	REGCARD	0xa1
#define	CONSUME	0xa2
#define READCARD	0xa3
#define ADDMONEY	0xa4

//
//#define  spi_cs 1;
//sbit  spi_ck=P0^6;
//sbit  spi_mosi=P0^7;
//sbit  spi_miso=P4^1;
//sbit  spi_rst=P2^7;
#define SPIReadByte()	SPIWriteByte(0)
u8 SPIWriteByte(u8 byte);
void SPI1_Init(void);
//void SPI2_Init(void);

#define SET_SPI_CS  (GPIOF->BSRR=0X01)
#define CLR_SPI_CS  (GPIOF->BRR=0X01)



#define SET_RC522RST  GPIOF->BSRR=0X02
#define CLR_RC522RST  GPIOF->BRR=0X02


/***********************RC522 函数宏定义**********************/
#define          RC522_CS_Enable()         GPIO_ResetBits ( GPIOA, GPIO_Pin_4 )
#define          RC522_CS_Disable()        GPIO_SetBits ( GPIOA, GPIO_Pin_4 )

#define          RC522_Reset_Enable()      GPIO_ResetBits( GPIOB, GPIO_Pin_0 )
#define          RC522_Reset_Disable()     GPIO_SetBits ( GPIOB, GPIO_Pin_0 )

#define          RC522_SCK_0()             GPIO_ResetBits( GPIOA, GPIO_Pin_5 )
#define          RC522_SCK_1()             GPIO_SetBits ( GPIOA, GPIO_Pin_5 )

#define          RC522_MOSI_0()            GPIO_ResetBits( GPIOA, GPIO_Pin_7 以上是关于STM32F103+RFID-RC522模块 实现简单读卡写卡demo的主要内容,如果未能解决你的问题,请参考以下文章

基于Stm32的RFID-RC522模块的对RFID读写使用

rfid-rc522用串口怎么接线

基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

STM32+MFRC522完成IC卡号读取密码修改数据读写

STM32+MFRC522完成IC卡号读取密码修改数据读写