MFRC522是应用于13.56MHz非接触式通信中高集成度的读写卡芯片,通过结合学习STM32 MFRC522 IC读卡 程序及原理图该博客的代码,结合一些资料,大概了解了MFRC522的充值与扣款的使用方法,下面是结合如上博客代码后添加的
首先添加如下充值和扣款的函数
/////////////////////////////////////////////////////////////////////
//功 能:扣款和充值
//参数说明: dd_mode[IN]:命令字
// 0xC0 = 扣款
// 0xC1 = 充值
// addr[IN]:钱包地址
// pValue[IN]:4字节增(减)值,低位在前
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue)
{
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = dd_mode;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{ status = MI_ERR; }
if (status == MI_OK)
{
// memcpy(ucComMF522Buf, pValue, 4);
for (i=0; i<16; i++)
{ ucComMF522Buf[i] = *(pValue+i); }
CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
unLen = 0;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
if (status != MI_ERR)
{ status = MI_OK; }
}
if (status == MI_OK)
{
ucComMF522Buf[0] = PICC_TRANSFER;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{ status = MI_ERR; }
}
return status;
}
首先该函数对于卡片内的数据格式是有要求的,就相当于一个自定义的数据类型格式,当你定义好M1卡的某一块为钱包时,需要对其进行初始化,将下面的数据写入到钱包(指定块)内,写入成功后该卡片则获取到了充值与扣款的资格。
同时,这个数组也是对卡片进行金额清零的需要写入的数据,举例:PcdWrite(1, RFID1); //清空金额,如果把卡片的第一块当做钱包,那么举例中即把钱包清0
unsigned char RFID1[16]={0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0xFE,0x01,0xFE};
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
MFRC522的充值、扣款、清零函数的实现,过程:寻卡成功->防冲撞->选卡成功->验证成功->读卡成功->充值、扣款、清零
unsigned char Add_Money[4] = {0,0,0,0}; //充钱金额
充值需要建立一个数组用来存储充值金额,之后在经过上诉过程读卡成功后,判断是否是你定义过的卡片然后再进行充值处理,由于卡片读出来的数据是16进制数,所以对于金额转化的方式需要特殊注意一下
if ((card1_bit==1) || (card2_bit==1))
{
Add_Money[2] = Recharge_Amount; //Recharge_Amount为充值金额 //金额转化
status = PcdValue (PICC_INCREMENT, 1, Add_Money);
if (status == MI_OK)//充值成功
{
status=MI_ERR;
status=PcdRead(1,RFID);
delay_ms(1);
if(status==MI_OK)//读卡成功
{
status=MI_ERR;
delay_ms(5);
for(i=0;i<16;i++)
{
temp=RFID[i];
printf("%d ",temp);
}
}
else printf ("读卡失败");
}
else printf ("充值失败!");
card1_bit = 0;
card2_bit = 0;
}
扣款的方式和充值基本无异,区别在于PcdValue写入的命令不同
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓扣款函数↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
status = PcdValue (PICC_DECREMENT, 1, Money);
if (status == MI_OK)//扣款成功
{
status=MI_ERR;
delay_ms(1);
if(status==MI_OK)//读卡成功
{
status=MI_ERR;
delay_ms(5);
for(i=0;i<16;i++)
{
temp=RFID[i];
printf("%d ",temp);
}
}
else printf ("读卡失败");
}
else
{
printf ("扣款失败!");
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑扣款函数↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑