首页 » 互联通信 » RC522射频卡模块与IC卡完成充值消费查询的技能实现思路,34码的裤子腰围是多少。

RC522射频卡模块与IC卡完成充值消费查询的技能实现思路,34码的裤子腰围是多少。

上海市建筑装饰工程集团通讯 2024-08-15 0

扫一扫用手机浏览

文章目录 [+]

第0个扇区第0块用于存放厂商代码,见地固话,不可变动。

每个扇区的块0、块1、块2为数据块,可以用于存储数据。
数据块可以进行读写操作。

RC522射频卡模块与IC卡完成充值消费查询的技能实现思路 RC522射频卡模块与IC卡完成充值消费查询的技能实现思路 互联通信

每个扇区的块3为掌握块,包括了密码A、存储掌握、密码B。
详细构造如下:

RC522射频卡模块与IC卡完成充值消费查询的技能实现思路 RC522射频卡模块与IC卡完成充值消费查询的技能实现思路 互联通信
(图片来自网络侵删)

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

重点总结:

(1)M1卡分为16个扇区,每个扇区由4块(0、1、2、3)组成。
在实际操作时,将16个扇区分为64个块,按绝对地址编号为0-63进行访问,也便是程序里须要填块的位置时,范围是0~63。

(2)每个块的大小是16字节,每个扇区里有3个数据块,数据块可以存放自己的自定义数据。

二、一卡通消费机实现事理2.1 封装核心函数

(1)紧张的硬件:单片机选择STM32,刷卡模块采取RC522。

(2)实现核心思路:为了方便存储数据,对数据进行管理,担保程序的通用性,将IC卡的所有信息都存放在IC卡上。
包括:激活状态、卡所属人信息,金额等。

以是在程序里定义了一个构造体:

#pragma pack(1) //这个构造体大小为16个字节,刚好存放到 IC卡的一个块里面 typedef struct CARD_INFO { u8 stat; //卡状态. 66表示此卡已经激活 其他值表示此卡未激活 // 88表示此卡挂失落,无法再进行消费 u32 money; //金额. 第一次激活卡,就将金额清0 u8 phone[11];//可以存放电话号码,ID,标识符之类的数据 }CARD; extern u8 IC_Card_uid[4];

并封装了两个底层函数: 接下来的所有对卡的操作只须要调用下面函数即可。

//读取卡号 u8 IC_Card_uid[4]; / card_uid :卡的id号外部5字节数组 data : 读出来的一个块,16字节数据 addr : 块号,从4开始 数据存放的地址。
每个扇区的0、1、2块是存放数据。
3是存放密码。
一样平常填:0、1、2 、4、5、6、8、9、10 数据一样平常格式:u8 SJ[16]={255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}; //写入的金额; / u8 IC_Card_Read(CARD rdata) { u8 KEY[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; //白卡的出厂密码 u8 status; /1. 寻卡/ status = search_card(IC_Card_uid); /2. 验证卡密码/ if(MI_OK==status) { print_CardNnmber(IC_Card_uid); status = RC522_PcdAuthState(PICC_AUTHENT1A, 3, KEY, IC_Card_uid); //验证卡片密码 形参参数:验证办法,块地址,密码,卡序列号 } /3. 读出数据/ if(MI_OK==status) { status = RC522_PcdRead(1,(u8)rdata); //从第addr块读出数据值。
} return status; } / 功能:写数据到指定块 参数: u8 addr :数据存放的地址。
每个扇区的0、1、2块是存放数据。
3是存放密码。
一样平常填:0、1、2 、4、5、6、8、9、10 数据一样平常格式:u8 SJ[16]={255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}; //写入的金额; / u8 IC_Card_Write(CARD wdata) { u8 KEY[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; //白卡的出厂密码 u8 status; /1. 寻卡/ status = search_card(IC_Card_uid); /2. 验证卡密码/ if(MI_OK==status) { status = RC522_PcdAuthState(PICC_AUTHENT1A, 3, KEY, IC_Card_uid); //验证卡片密码 形参参数:验证办法,块地址,密码,卡序列号 } /3. 写数据到卡/ if(MI_OK==status) { status = RC522_PcdWrite(1, (u8)wdata); //写数据到第addr块,data入的数据值。
} return status; }
2.2 编写案例接口

为了方便理解整体的设计思路,下面针对几个常见的操作编写了函数接口测试Demo。

void Activation_CardInformation(void); //对卡激活-将卡状态设置为66 void Unlock_CardInformation(void); //对卡解锁--去除挂失落状态。
将卡状态设置为66 void locking_CardInformation(void); //对卡挂失落。
将卡状态设置为88 void Consumption_CardInformation(void); //消费. 消费便是减少金额. void Recharge_CardInformation(void); //对卡进行充值. 充值便是累加金额 void Query_CardInformation(void); //查询卡的详细信息,通过串口打印

源代码如下:

#include "app.h" / 函数功能: 查询卡的详细信息,通过串口打印 / void Query_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("用户信息:%s\r\n",data.phone); printf("余额:%d\r\n",data.money); } else if(data.stat==88) { printf("此卡已挂失落.请先解锁.\r\n"); } //卡没有激活 else { printf("此卡没有激活.\r\n"); } //复位--开释选中的卡片 RC522_PcdReset(); } } / 函数功能: 对卡进行充值. 充值便是累加金额 / void Recharge_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("用户信息:%s\r\n",data.phone); printf("充值前的余额:%d\r\n",data.money); //累加金额 data.money+=100; //充值100块 //重新写入到卡里 RC522_PcdWrite(1, (u8)&data); //写数据到第addr块,data入的数据值。
; printf("充值后的余额:%d\r\n",data.money); } //卡已经挂失落 else if(data.stat==88) { printf("此卡已挂失落.请先解锁后再充值.\r\n"); } //卡没有激活 else { printf("此卡没有激活.请先激活后再充值.\r\n"); } //复位--开释选中的卡片 RC522_PcdReset(); } } / 函数功能: 消费. 消费便是减少金额. / void Consumption_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("用户信息:%s\r\n",data.phone); printf("消费前的余额:%d\r\n",data.money); //消费金额,如果:我要消费10元,先判断卡里有没有10元,没有就不能消费. printf("即将消费10元...\r\n"); //余额足够才能消费 if(data.money>=10) { data.money-=10; //减去10块 //重新写入到卡里 RC522_PcdWrite(1, (u8)&data); //写数据到第addr块,data入的数据值。
; printf("消费后的余额:%d\r\n",data.money); } else { printf("余额不敷,消费失落败...\r\n"); } } //卡已经挂失落 else if(data.stat==88) { printf("此卡已挂失落.请先解锁后再进行消费流程.\r\n"); } //卡没有激活 else { printf("此卡没有激活.请先激活后再进行消费流程.\r\n"); } //复位--开释选中的卡片 RC522_PcdReset(); } } / 函数功能: 对卡挂失落。
将卡状态设置为88 / void locking_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("用户信息:%s\r\n",data.phone); //设置挂失落状态 data.stat=88; //重新写入到卡里 RC522_PcdWrite(1, (u8)&data); //写数据到第addr块,data入的数据值。
; printf("此卡已成功挂失落.\r\n"); } //卡已经挂失落 else if(data.stat==88) { printf("此卡已挂失落.\r\n"); } //卡没有激活 else { printf("此卡没有激活.请先激活.\r\n"); } //复位--开释选中的卡片 RC522_PcdReset(); } } / 函数功能: 对卡解锁--去除挂失落状态。
将卡状态设置为66 / void Unlock_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("此卡已解锁.\r\n"); } //卡已经挂失落 else if(data.stat==88) { //设置解锁状态 data.stat=66; //重新写入到卡里 RC522_PcdWrite(1, (u8)&data); //写数据到第addr块,data入的数据值。
; printf("此卡已成功解锁.\r\n"); } //卡没有激活 else { printf("此卡没有激活.请先激活.\r\n"); } //复位--开释选中的卡片 RC522_PcdReset(); } } / 函数功能: 对卡激活-将卡状态设置为66 激活卡也叫注册卡。
可以写入一些用户信息到卡里. / void Activation_CardInformation() { CARD data; if(IC_Card_Read(&data)==MI_OK) { //判断卡是否已经激活 if(data.stat==66) { printf("此卡已激活,不须要重复激活.\r\n"); } //卡已经挂失落 else if(data.stat==88) { printf("此卡已激活,并挂失落,锁定,请先解锁...\r\n"); } //卡没有激活 else { //设置解锁状态 data.stat=66; strncpy((char)data.phone,"473608901",sizeof(data.phone)-1); //重新写入到卡里 // IC_Card_Write(&data); /3. 写数据到卡/ RC522_PcdWrite(1, (u8)&data); //写数据到第addr块,data入的数据值。
printf("此卡已成功激活.用户信息:%s\r\n",data.phone); } //复位--开释选中的卡片 RC522_PcdReset(); } }
2.3 编写操作界面

为了方便测试功能,在LCD屏上绘制了几个矩形,触摸屏点击分别实行对应的功能。

#include "app.h" / RC522射频模块外部的接口: 1--SDA <----->PB5--片选脚 2--SCK <----->PB4--时钟线 3--MOSI<----->PA12--输出 4--MISO<----->PA11--输入 5--悬空 6--GND <----->GND 7--RST <----->PA8--复位脚 8--VCC <----->VCC / int main() { USARTx_Init(USART1,72,115200); LCD_Init(); LCD_Clear(BLACK); XPT2046_TouchInit(); RC522_Init(); // DisplayString(0,0,16,"12345jkdbdfvdfvdfv7364837340hdxsmsks3743934ndvdfv",BLACK,WHITE); // // POINT_COLOR=0x00FF; //设置画笔颜色 // LCD_DrawLine(0,0,200,50); //画线 // //颜色添补 LCD_Fill(0,0,120,105,RED); //颜色添补 LCD_Fill(120,0,239,105,RED); //颜色添补 LCD_Fill(0,105,120,210,RED); //颜色添补 LCD_Fill(120,105,239,210,RED); //颜色添补 LCD_Fill(0,210,120,320,RED); //颜色添补 LCD_Fill(120,210,239,320,RED); DisplayString(0,0,16,"Activation",BLACK,WHITE); DisplayString(120,0,16,"Query",BLACK,WHITE); DisplayString(0,105,16,"Recharge",BLACK,WHITE); DisplayString(120,105,16,"Consumption",BLACK,WHITE); DisplayString(0,210,16,"locking",BLACK,WHITE); DisplayString(120,210,16,"Unlock",BLACK,WHITE); while(1) { //扫描触摸屏坐标 if(XPT2046_ReadXY()) { printf("x=%d,y=%d\r\n",xpt2046_touch.x,xpt2046_touch.y); printf("x0=%d,y0=%d\r\n",xpt2046_touch.x0,xpt2046_touch.y0); // 对卡激活- if(xpt2046_touch.x>0&&xpt2046_touch.x<120&& xpt2046_touch.y>0&&xpt2046_touch.y<105) { printf("---- 对卡激活-Demo----\r\n"); //充值Demo Activation_CardInformation(); //颜色添补 LCD_Fill(0,0,120,105,WHITE); DisplayString(0,0,16,"Activation",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(0,0,120,105,RED); DisplayString(0,0,16,"Activation",BLACK,WHITE); } //查询Demo else if(xpt2046_touch.x>120&&xpt2046_touch.x<240&& xpt2046_touch.y>0&&xpt2046_touch.y<105) { printf("----运行查询Demo----\r\n"); //查询Demo Query_CardInformation(); //颜色添补 LCD_Fill(120,0,239,105,WHITE); DisplayString(120,0,16,"Query",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(120,0,239,105,RED); DisplayString(120,0,16,"Query",BLACK,WHITE); } //充值Demo else if(xpt2046_touch.x>0&&xpt2046_touch.x<120&& xpt2046_touch.y>105&&xpt2046_touch.y<210) { printf("----运行充值Demo----\r\n"); //充值Demo Recharge_CardInformation(); //颜色添补 LCD_Fill(0,105,120,210,WHITE); DisplayString(0,105,16,"Recharge",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(0,105,120,210,RED); DisplayString(0,105,16,"Recharge",BLACK,WHITE); } //消费Demo else if(xpt2046_touch.x>120&&xpt2046_touch.x<240&& xpt2046_touch.y>105&&xpt2046_touch.y<210) { printf("----运行消费Demo----\r\n"); //消费Demo Consumption_CardInformation(); //颜色添补 LCD_Fill(120,105,239,210,WHITE); DisplayString(120,105,16,"Consumption",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(120,105,239,210,RED); DisplayString(120,105,16,"Consumption",BLACK,WHITE); //等待触摸屏松开 } //挂失落Demo else if(xpt2046_touch.x>0&&xpt2046_touch.x<120&& xpt2046_touch.y>210&&xpt2046_touch.y<320) { printf("----运行挂失落Demo----\r\n"); //挂失落Demo locking_CardInformation(); //颜色添补 LCD_Fill(0,210,120,320,WHITE); DisplayString(0,210,16,"locking",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(0,210,120,320,RED); DisplayString(0,210,16,"locking",BLACK,WHITE); } //解锁Demo else if(xpt2046_touch.x>120&&xpt2046_touch.x<240&& xpt2046_touch.y>210&&xpt2046_touch.y<320) { printf("----运行解锁Demo----\r\n"); //解锁Demo Unlock_CardInformation(); //颜色添补 LCD_Fill(120,210,239,320,WHITE); DisplayString(120,210,16,"Unlock",BLACK,WHITE); //等待触摸屏松开 while(XPT2046_PEN==0){} //颜色添补 LCD_Fill(120,210,239,320,RED); DisplayString(120,210,16,"Unlock",BLACK,WHITE); } } delay_ms(10); } }2.4 运行效果

点击下方,第一韶光理解华为云新鲜技能~

华为云博客_大数据博客_AI博客_云打算博客_开拓者中央-华为云

标签:

相关文章

监控回放怎样找,回放英文。

怎样打开监控视频回看当前视频画面要打开监控视频回看当前画面,首先需要进入监控系统的控制台,选择对应的摄像机通道,然后在录像回放界面...

互联通信 2024-08-15 阅读1 评论0