寻卡防冲突
/*******************************************************************************
//功 能:寻卡
//参数说明: 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
//返 回: 成功返回MI_OK
*******************************************************************************/
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08); //清零Status2Reg的MFAuthent Command执行成功标志位
WriteRawRC(BitFramingReg,0x07); //清零Transceive命令开始位
SetBitMask(TxControlReg,0x03); //开启天线
ucComMF522Buf[0] = req_code; //取522要执行的命令
//printf("%x\n",ucComMF522Buf[0]);
//printf("%x\n",ucComMF522Buf[1]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);//向PICC发送寻天线区内全部卡命令,并接收PICC返回的数据
if ((status == MI_OK))
if ((status == MI_OK) && (unLen == 0x10))//没有错误并接接收为2个字节
{
*pTagType = ucComMF522Buf[0];//取接收缓冲区的第一个字节
*(pTagType+1) = ucComMF522Buf[1];//取接收缓冲区的第二个字节
}
else
{
status = MI_ERR; //错误
}
#if PRINT
printf("card type is:\n");
printf("%x\n",ucComMF522Buf[0]);
printf("%x\n",ucComMF522Buf[1]);
#endif
return status;
}
/*******************************************************************************/
/*******************************************************************************
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返 回: 成功返回MI_OK
//协 议:SEL NVB(0X20)
*******************************************************************************/
char PcdAnticoll(unsigned char *id)
{
char status;
unsigned char i,snr_check=0;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);//清除标志位
WriteRawRC(BitFramingReg,0x00);//000 指示最后一个字节的所有位将被发送。
ClearBitMask(CollReg,0x80);//发生碰撞所有接收位将被清除
ucComMF522Buf[0] = PICC_ANTICOLL1;//0x93 防冲撞 发到卡里的命令
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);//获得卡的序列号,ucComMF522Buf[]
if (status == MI_OK)
{
for (i=0; i<4; i++)
{
id[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
//协 议:SEL NVB(0X70) ID(4个byte) IDCHECK CRC16
*******************************************************************************/
char PcdSelect(unsigned char *id)
{
char status = 0XFF;
unsigned char i;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN]; //MAXRLEN = 18
ucComMF522Buf[0] = PICC_ANTICOLL1;//防冲撞命令
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i=0; i<4; i++)
{
ucComMF522Buf[i+2] = *(id+i);//填充卡的序列号
ucComMF522Buf[6] ^= *(id+i);//计算校验码
}
CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);//获得CRC校验结果的16位值
//放入ucComMF522Buf【0,1】
ClearBitMask(Status2Reg,0x08);//清零MFAuthent Command执行成功标志位
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);//把CRC值和卡号发的卡里
if ((status == MI_OK) && (unLen == 0x18))//返回24个字节&状态为无错误
{
status = MI_OK;
}
else
{
status = MI_ERR;
}
return status;
}
因为S50卡所以select结果是8