STM32+RC522(实现对ic卡的增删改查)
前言1.硬件部分1.1STM32F103C8T61.2RFID-RC522识别模块1.3按键模块接线部分
2.代码部分rc522.crc522.hmain.c
3.总结3.1效果展示3.2使用以及注意事项3.2.1使用方式3.2.2注意事项
前言
这是基于STM32F103C8T6和RFID识别模块,实现的对ic卡的增删改查,能够读取卡号,对卡内指定的区域进行数据修改。 感谢 物联网小菜鸟一枚 大佬代码思路 https://blog.csdn.net/m0_69428059/article/details/124259091
1.硬件部分
1.1STM32F103C8T6
1.2RFID-RC522识别模块
1.3按键模块
接线部分
STM32F103C8T6RC522PB12SDAPB13SCKPB15MOSIPB14MISOGNDGNDRSTPA8VCCVCC
STM32F103C8T6按键PA0key0PA1key1
2.代码部分
rc522.c
#include "rc522.h"
#include "delay.h"
#include "usart.h"
#include
#include "led.h"
#include "key.h"
#include
// M1卡分为16个扇区,每个扇区由四个块(块0、块1、块2、块3)组成
// 将16个扇区的64个块按绝对地址编号为:0~63
// 第0个扇区的块0(即绝对地址0块),用于存放厂商代码,已经固化不可更改
// 每个扇区的块0、块1、块2为数据块,可用于存放数据
// 每个扇区的块3为控制块(绝对地址为:块3、块7、块11.....)包括密码A,存取控制、密码B等
/*******************************
*连线说明:
*1--SDA PB12
*2--SCK PB13
*3--MOSI PB15
*4--MISO PB14
*5--悬空
*6--GND GND
*7--RST PA8
*8--VCC VCC
************************************/
/*全局变量*/
unsigned char CT[2];//卡类型
unsigned char SN[4]; //卡号
unsigned char date[16]; //存放数据
unsigned char date1_0[16]; //扇区1块0存放数据
unsigned char date1_3[16]; //扇区1块3存放数据
unsigned char date2_3[16]; //扇区2块3存放数据
unsigned char date2_0[16]; //扇区2块0存放数据
unsigned char date3_0[16]; //扇区3块0存放数据
unsigned char date3_3[16]; //扇区3块3存放数据
unsigned char date4_3[16]; //扇区4块3存放数据
unsigned char card0_bit=0;
unsigned char card1_bit=0;
unsigned char card2_bit=0;
unsigned char card3_bit=0;
unsigned char card4_bit=0;
unsigned char total=0;
// 替换成自己卡的UID
//A32E3E4E {163,46,62,78}
//卡号的uid(读取出来的卡号进行16进制转十进制,每两位进行转换)
unsigned char card_0[4]= {163,46,62,78};//自己的卡uid
//密码a和b
u8 KEY_A[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
u8 KEY_B[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
// 置零用
unsigned char DATA0[16]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char DATA1[16]= {0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x07,0x81,0x69,0xff,0xff,0xff,0xff,0xff,0xff};//改尾块设置扇区0为数据块
unsigned char DATA2[16]= {0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x0c,0xf3,0x0c,0xf3};//设置3扇区0块区为数值块结构,钱包余额初始为0
unsigned char status;
unsigned char adr2_0=0x08;// 第2扇区0区块(第9块)
unsigned char adr1_0=0x04;// 第1扇区0区块(第5块)
unsigned char adr1_3=0x07;// 第1扇区3区块(第8块)
unsigned char adr2_3=0x0B;// 第2扇区3区块(第12块)
unsigned char adr3_0=0x0C;// 第3扇区0区块(第13块)
unsigned char adr3_3=0x0F;// 第3扇区3区块(第16块)
unsigned char adr4_3=0x13;// 第4扇区3区块(第20块)
unsigned char adr5_3=0x17;// 第5扇区3区块(第24块)
#define RC522_DELAY() delay_us( 20 )
//money
char money[255];
//显示卡的卡号,以十六进制显示
void ShowID(u8 *p)
{
u8 num[9];
u8 i;
//取卡号
for(i=0;i9?(num[i*2]+='7'):(num[i*2]+='0');
num[i*2+1]=p[i]%16;
num[i*2+1]>9?(num[i*2+1]+='7'):(num[i*2+1]+='0');
}
num[8] = 0;
printf("your card id is %s\r\n", num);
printf("ID>>>%s\r\n", num);
}
void RC522_Handel(void)
{
u8 i = 0;
status = PcdRequest(PICC_REQALL,CT);//寻卡
// printf("\r\nstatus>>>>>>%d\r\n", status);
if(status==MI_OK)// 寻卡成功
{
status=MI_ERR;
status = PcdAnticoll(SN);// 防冲撞 获得UID 存入SN
ShowID(SN);
printf("寻卡成功\r\n");
}
else
printf("Please swipe the card\r\n");
if (status==MI_OK)// 防冲撞成功
{
status = MI_ERR;
ShowID(SN); // 串口打印寻卡成功的ID号
// 判断是否为自己的卡,是自己的卡才执行后面的操作。
if((SN[0]==card_0[0])&&(SN[1]==card_0[1])&&(SN[2]==card_0[2])&&(SN[3]==card_0[3]))
{
card0_bit=1;
printf("\r\nwelcome \r\n");
status = PcdSelect(SN);
if(status == MI_OK)//选卡成功
{
status = MI_ERR;
// 验证A密钥 块地址 密码
// 注意:此块地址只需要指向某一扇区就可以了,且只能对验证过的扇区进行读写操作
status = PcdAuthState(KEYA, adr3_3, KEY_A, SN);
if(status == MI_OK)//验证成功
{
printf("PcdAuthState(A) success\r\n");
}
else
{
printf("PcdAuthState(A) failed\r\n");
}
// 验证B密钥 块地址 密码
status = PcdAuthState(KEYB, adr3_3, KEY_B, SN);
if(status == MI_OK)//验证成功
{
printf("PcdAuthState(B) success\r\n");
}
else
{
printf("PcdAuthState(B) failed\r\n");
}
}
/****************新卡执行数值操作需要先写一次卡(格式系统选中作为金额存储数据块)****************/
// if(status == MI_OK)//读卡成功
// {
// status = MI_ERR;
// printf("Write the card after 1 second. Do not move the card!!!\r\n");
// delay_ms(1000);
// // 写数据到M1卡一块
// printf("开始写入数据\r\n");
// status = PcdWrite(adr3_0, DATA2);
// if(status == MI_OK)//写卡成功
// {
// printf("PcdWrite() success\r\n");
// }
// else
// {
// printf("PcdWrite() failed\r\n");
// delay_ms(3000);
// }
// }
// if(status == MI_OK)//写卡成功
// {
// status = MI_ERR;
// // 读取M1卡一块数据 块地址 读取的数据
// status = PcdRead(adr3_0, date3_0);
// if(status == MI_OK)//读卡成功
// {
// printf("date3_0:");
// for(i = 0; i < 16; i++)
// {
// printf("%02x", date3_0[i]);
// }
// printf("\r\n");
// }
// else
// {
// printf("PcdRead() failed\r\n");
// }
// }
///
if(status == MI_OK)//验证成功
{
status = MI_ERR;
// 读取M1卡一块数据 块地址 读取的数据 注意:因为上面验证的扇区是3扇区,所以只能对3扇区的数据进行读写,超出范围读取失败。
status = PcdRead(adr3_0, date3_0);
if(status == MI_OK)//读卡成功
{
printf("date3_0:");
for(i = 0; i |