#include <intrins.h>
#include "reg52.h"
#include "main.h"
#include "mfrc522.h"
#include <string.h>
#define MAXRLEN 18
/////////////////////////////////////////////////////////////////////
//功 能:寻卡
//参数说明: req_code[IN]:寻卡方式
// 0x52 = 寻感应区内所有符合14443A标准的卡
// 0x26 = 寻未进入休眠状态的卡
// pTagType[OUT]:卡片类型代码
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
/**RC522芯片操作命令
*PCD_IDLE 0x00 取消当前命令
*PCD_AUTHENT 0x0E 验证密钥
*PCD_RECEIVE 0x08 接收数据
*PCD_TRANSMIT 0x04 发送数据
*PCD_TRANSCEIVE 0x0C 发送并接收数据
*PCD_RESETPHASE 0x0F 复位
*PCD_CALCCRC 0x03 CRC循环冗余码计算
*/
/**Mifare_One卡片命令字
*PICC_REQIDL 0x26 寻天线区内未进入休眠状态
*PICC_REQALL 0x52 寻天线区全部卡
*PICC_ANTICOLL1 0x93 防碰撞
*PICC_ANTICOLL2 0x95 防碰撞
*PICC_AUTHENT1A 0x60 验证A密钥
*PICC_AUTHENT1B 0x61 验证B密钥
*PICC_READ 0x30 读块操作
*PICC_WRITE 0xA0 写块操作
*PICC_DECREMENT 0xC0 扣款操作
*PICC_INCREMENT 0xC1 充值操作
*PICC_RESTORE 0xC2 调取扇区块数据到缓冲区
*PICC_TRANSFER 0xB0 保存缓冲区中的数据
*PICC_HALT 0x50 休眠
*/
//返 回: 成功返回MI_OK
/**
*函数将我们的寻卡命令PICC_REQIDL装填到要发送的数组,通过
*PcdComMF522函数发送出去,如果此时在PCD有效范围内没有寻找到卡,则函数返回MI_ERR
*若函数返回MI_OK,并且ulen为0x10为两个字节则说明寻卡成功,返回的两个字节被装填入CardRevBuf数组。
*/
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);//寄存器包含接收器和发送器和数据模式检测器的状态标志
WriteRawRC(BitFramingReg,0x07);//不启动数据发送
SetBitMask(TxControlReg,0x03);//TX1,TX2输出信号将传递经发送数据调制的13.56MHz的能量载波信号。
ucComMF522Buf[0] = req_code;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);//通过522发送req_code命令,并接收返回数据,存到ucComMF522Buf中。
if ((status == MI_OK) && (unLen == 0x10))//因为2个字节是16bit
{
*pTagType = ucComMF522Buf[0];
*(pTagType+1) = ucComMF522Buf[1];
}
else
{ status = MI_ERR; }
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/**
*防冲突操作就是将防冲突命令通过PcdComMF522函数与PICC卡进行交互。防冲突命令是两个字节,
*其中第一个字节为Mifare_One卡的防冲突命令字PICC_ANTICOLL1(0X93),
*第二个字节为0x20
*选择代码SEL(1个字节),SEL规定了串联级别CLn。
*有效位的数目NVB(1个字节),NVB规定了PCD所发送的CLn的有效位的数目。
*/
/////////////////////////////////////////////////////////////////////
char PcdAnticoll(unsigned char *pSnr)
{
char status;
unsigned char i,snr_check=0;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);//寄存器包含接收器和发送器和数据模式检测器的状态标志
WriteRawRC(BitFramingReg,0x00);//不启动数据发送,接收的LSB为存放在位0.接受到的第二位防在位1,定义发送的最后一个字节的位数为8
ClearBitMask(CollReg,0x80);//所有接收的位在冲突后将被清除。
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);
if (status == MI_OK)
{
for (i=0; i<4; i++)
{
*(pSnr+i) = ucComMF522Buf[i];
snr_check ^= ucComMF522Buf[i];
}
if (snr_check != ucComMF522Buf[i])//返回四个字节,最后一个字节为校验位
{ status = MI_ERR; }
}
SetBitMask(CollReg,0x80);
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdSelect(unsigned char *pSnr)
{
char status;
unsigned char i;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i=0; i<4; i++)
{
ucComMF522Buf[i+2] = *(pSnr+i);
ucComMF522Buf[6] ^= *(pSnr+i);
}
CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);//计算CRC装填至ucComMF522Buf[7]
ClearBitMask(Status2Reg,0x08);//寄存器包含接收器和发送器和数据模式检测器的状态标志。
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x18))//成功返回SAK,包括1字节的SAK和2字节的CRC_A。
{ status = MI_OK; }
else
{ status = MI_ERR; }
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
// 0x60 = 验证A密钥
// 0x61 = 验证B密钥
// addr[IN]:块地址
// pKey[IN]:密码
// pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
{
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = auth_mode;
ucComMF522Buf[1] = addr;
for (i=0; i<6; i++)
{ ucComMF522Buf[i+2] = *(pKey+i); }
for (i=0; i<6; i++)
{ ucComMF522Buf[i+8] = *(pSnr+i); }
status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
{ status = MI_ERR; }
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
// pData[OUT]:读出的数据,16字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRead(unsigned char addr,unsigned char *pData)
{
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_READ;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x90))
{
for (i=0; i<16; i++)
{ *(pData+i) = ucComMF522Buf[i]; }
}
else
{ status = MI_ERR; }
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:写数据到M1卡一块
//参数说明: addr[IN]:块地址
// pData[IN]:写入的数据,16字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdWrite(unsigned char addr,unsigned char *pData)
{
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_WRITE;
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)
{
for (i=0; i<16; i++)
{ ucComMF522Buf[i] = *(pData+i); }
CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&
评论0