⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf.c

📁 使用RC531读卡芯片读取二代身份证的模块软件设计部分
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------*
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 + -