📄 rf.c
字号:
//------------------------------------------------------------------------*
INT8U ReadTag(INT8U Tagtype, INT8U *UIDLen, INT8U UID_Buf[])
{
INT8U flag;
if(Tagtype)
{
//读取ISO14443A
flag = Request_TypeA(); //询卡
if(flag) return 1;
flag = Get_UID_TypeA(UIDLen, UID_Buf); //读TypeA电子标签UID
if(flag) return 3;
}
else
{
//读取ISO14443B
flag = Request_TypeB(); //询卡
if(flag) return 1;
flag = ATTRIB_TypeB(); //选卡
if(flag) return 2;
flag = Get_UID_TypeB(UIDLen, UID_Buf); //读TypeB卡号
if(flag) return 3;
}
return 0; //操作成功
}
//------------------------------------------------------------------------*
//3.1 对ISO14443A电子标签的相关操作 *
//------------------------------------------------------------------------*
//Request_TypeA-----------------------------------------------------------*
//功 能: 向TypeA卡发送request信号 *
//参 数: 无 *
//返 回: 1,2 - request命令执行失败;0 - request命令执行成功 *
//------------------------------------------------------------------------*
INT8U Request_TypeA(void)
{
INT8U Data;
INT8U Flag;
INT8U Len;
INT8U SndData[1];
INT8U ReData[40];
//写bitframing寄存器,7bit数据的发送,短帧格式
RFRegWrite(RegBitFraming, 0x07);
// Bit3=0 加密单元关闭
Data = RFRegRead(RegControl);
Data &= 0xf7;
RFRegWrite(RegControl, Data);
//TypeA接收冗余校验
RFRegWrite(RegChannelRedundancy, 0x03);
//ISO14443-A 询卡指令
SndData[0] = 0x26;
Flag = Command_Send(SndData, 0x01, PCD_TRANSCEIVE);
if(Flag)
{
//命令发送失败
RFRegWrite(RegCommand, 0x00); //空闲指令(Idle)取消当前操作
return 1; //失败返回
}
//命令发送成功
Len = Read_FIFO(ReData); //接收2个字节的ATQA应答
if(Len >= 2) //判断回读的应答数据长度为2否
{
//判断回应的数据是否为"04,00" or "84,00"
return 0; //成功
}
return 2; //失败
}
//Get_UID_TypeA-----------------------------------------------------------*
//功 能: 发送ANTICOLLISION指令,获得ISO14443A电子标签UID *
//出 口: UIDLen - UID有效数据长度,UID_Buf - UID数据数组 *
//返 回: 1,2,3 - 命令执行失败;0 - 命令执行成功 *
//------------------------------------------------------------------------*
INT8U Get_UID_TypeA(INT8U *UIDLen, INT8U UID_Buf[])
{
INT8U i;
INT8U Flag;
INT8U Len;
INT8U SndData[2];
INT8U ReData[40];
//TypeA接收冗余校验
RFRegWrite(RegChannelRedundancy, 0x03);
//ISO14443A ANTICOLLISION指令
SndData[0] = 0x93; //SEL
SndData[1] = 0x20; //NVB
Flag = Command_Send(SndData, 0x02, PCD_TRANSCEIVE);
if(Flag)
{
//命令发送失败
RFRegWrite(RegCommand, 0x00); //空闲指令(Idle)取消当前操作
return 1; //失败
}
//接收ANTICOLLISION指令应答,UID
Len = Read_FIFO(ReData); //读出FIFO寄存器的内容
if(Len == 5)
{
if(Check_UID(Len, ReData) == 0) //校验得到的5位UID是否正确
{
//设置出口参数
*UIDLen = 4;
for(i = 0; i < Len; i++)
{
UID_Buf[i] = ReData[i];
}
return 0; //成功
}
return 3; //失败
}
return 2; //失败
}
//Check_UID---------------------------------------------------------------*
//功 能: 对收到的UID号进行校验 *
//参 数: Len - 数据长度, CheckData - 待校验数据 *
//返 回: 1 - 校验错误;0 - 校验成功 *
//------------------------------------------------------------------------*
INT8U Check_UID(INT8U Len, INT8U CheckData[])
{
INT8U i,Data = 0;
for(i = 0; i < Len; i++)
{
//对5位UID号进行异或操作
Data ^= CheckData[i];
}
if(Data) return 1; //校验错误
return 0; //校验成功
}
//------------------------------------------------------------------------*
//3.2 对ISO14443B电子标签的相关操作 *
//------------------------------------------------------------------------*
//Request_TypeB-----------------------------------------------------------*
//功 能: 向ISO14443B电子标签发送询卡命令 *
//参 数: 无 *
//返 回: 1,2 - 询卡命令执行失败; 0 - 询卡命令执行成功 *
//------------------------------------------------------------------------*
INT8U Request_TypeB(void)
{
INT8U Data;
INT8U Flag;
INT8U Len;
INT8U SndData[3];
INT8U ReData[40];
//TypeB接收冗余校验
RFRegWrite(RegChannelRedundancy, 0x2c);
// Bit3=0 加密单元关闭
Data = RFRegRead(RegControl);
Data &= 0xf7;
RFRegWrite(RegControl, Data);
//ISO14443-B 询卡指令
SndData[0] = 0x05;
SndData[1] = 0x00;
SndData[2] = 0x00;
Flag = Command_Send(SndData, 0x03, PCD_TRANSCEIVE);
if(Flag)
{
//取消当前操作
RFRegWrite(RegCommand, 0x00);
return 1; //失败
}
//接收询卡应答
Len = Read_FIFO(ReData);
if(Len >= 12)
{
//判断回应的数据是否为"50,00,...."
return 0; //成功
}
return 2; //失败
}
//ATTRIB_TypeB------------------------------------------------------------*
//功 能: 向TypeB卡发送ATTRIB指令 *
//参 数: 无 *
//返 回: 1,2 - ATTRIB命令执行失败; 0 - ATTRIB命令执行成功 *
//------------------------------------------------------------------------*
INT8U ATTRIB_TypeB(void)
{
INT8U Flag;
INT8U Len;
INT8U SndData[9];
INT8U ReData[40];
//发送激活指令ATTRIB
SndData[0] = 0x1d;
SndData[1] = 0x00;
SndData[2] = 0x00;
SndData[3] = 0x00;
SndData[4] = 0x00;
SndData[5] = 0x00;
SndData[6] = 0x08;
SndData[7] = 0x01;
SndData[8] = 0x08;
Flag = Command_Send(SndData, 0x09, PCD_TRANSCEIVE);
if(Flag)
{
//取消当前操作
RFRegWrite(RegCommand, 0x00);
return 1; //失败
}
//接收激活指令ATTRIB应答
Len = Read_FIFO(ReData);
if(Len >= 1)
{
//判断回应的数据是否为"08"
return 0; //成功
}
return 2; //失败
}
//Get_UID_TypeB-----------------------------------------------------------*
//功 能: 向TypeB卡发送Get_UID信号 *
//出 口: UIDLen - UID有效数据长度,UID_Buf - UID数据数组 *
//返 回: 1,2 - Get_UID命令执行失败; 0 - Get_UID命令执行成功 *
//------------------------------------------------------------------------*
INT8U Get_UID_TypeB(INT8U *UIDLen, INT8U UID_Buf[])
{
INT8U i;
INT8U Flag;
INT8U Len;
INT8U SndData[5];
INT8U ReData[40];
//发送命令,获取二代证UID
SndData[0] = 0x00;
SndData[1] = 0x36;
SndData[2] = 0x00;
SndData[3] = 0x00;
SndData[4] = 0x08;
//执行发送接收命令
Flag = Command_Send(SndData, 0x05, PCD_TRANSCEIVE);
if(Flag)
{
//取消当前操作
RFRegWrite(RegCommand, 0x00);
return 1; //失败
}
//接收应答
Len = Read_FIFO(ReData);
if(Len == 10)
{
//判断回应的数据是否为UID "....9000"
//设置出口参数
for (i = 0; i < 10; i++)
{
UID_Buf[i] = ReData[i];
}
*UIDLen = Len;
return 0; //成功
}
return 2; //失败
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -