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

📄 fm1702.c

📁 很好用的FM1702的读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*名称: Write_FIFO */
/*功能: 该函数实现向FM1715的FIFO中写入x bytes数据 */
/*输入: 
			count, 待写入字节的长度 */
			/* buff, 指向待写入数据的指针 */
/*输出: N/A */ 
/****************************************************************/
void Write_FIFO(uchar count,uchar idata *buff)
{
uchar i;

for(i=0;i<count;i++)
	{
	FIFOData =*(buff+i);
	}
}

/****************************************************************/
/*名称: Read_FIFO */
/*功能: 该函数实现从FM1715的FIFO中读出x bytes数据 */
/*输入: buff, 指向读出数据的指针 */ 
/*输出: N/A */
/****************************************************************/
uchar Read_FIFO(uchar idata *dBuf)
{
uchar temp;
uint i;

	
temp =FIFOLength;
if(temp ==0)
	{
	return 0;
	}
if(temp >= 24)			//temp=255,会进入死循环,因此增加FIFO_length越界判断
	{
	temp=24;
	}

for(i=0;i<temp;i++)
	{
	*dBuf = FIFOData;
	dBuf ++;
	}
return temp;
}
//******************************************************


//******************************************************
/*
FM1702卡片操作基本函数
****************************************************************
名称: MIF_Halt 
功能: 该函数实现暂停MIFARE卡
输入: N/A 
输出: 
FM1702_OK: 应答正确 
FM1702_PARITYERR: 奇偶校验错 
FM1702_CRCERR: CRC校验错 
FM1702_NOTAGERR: 无卡 
****************************************************************
*/
uchar MIF_Halt(void)
{
uchar temp;

CRCPresetLSB =0x63;
CWConductance =0x3F;
ChannelRedundancy =0x03;
*buffer=RF_CMD_HALT;
*(buffer+1)=0x00;

//temp=Command_Send(2,buffer,Transmit);
temp=Command_Send(2,buffer,Transceive);
if(temp ==TRUE )
//if(temp == FALSE)
	{
	return FM1702_OK;
	}
else
	{
	temp = ErrorFlag;
	if((temp&0x02)==0x02)
		{
		return(FM1702_PARITYERR);
		}
	if((temp&0x04)==0x04)
		{
		return(FM1702_FRAMINGERR);
		}
	return(FM1702_NOTAGERR);
	}
}
/*
LOADKEY
***************************************************************
名称: Load_keyE2 
功能: 该函数实现把E2中密码存入FM1715的keybuffer中 
输入: 
		Secnr: EE起始地址 
输出: 
		True: 密钥装载成功 
		False: 密钥装载失败 
/***************************************************************
*/
uchar Load_keyE2_CPY(uchar Secnr,uchar Mode) 
{ 
uchar temp; 
uchar msb = 0; 
uchar lsb = 0; 

temp = Secnr * 12; 
if (Mode == 0)  
	{
	if(temp >=0x80)		//计算密码存放地址
		{
		lsb=temp =0x80;
		msb = 0x01;
		}
	else
		{
		msb =0x00;
		lsb =temp + 0x80;
		}
	}
else
	{
	msb = 0x01;
	lsb = temp + 0x40;
	} 
buffer[0] = lsb; 
buffer[1] = msb; 
temp = Command_Send(2, buffer, LoadKeyE2); 
temp = ErrorFlag & 0x40;
if (temp == 0x40) 
	{ 
	return FALSE; 
	} 
return TRUE; 
} 

/*
***************************************************************/ 
/*名称: Request */
/*功能: 该函数实现对放入FM1715操作范围之内的卡
			片的Request操作 */
/*输入: 
		mode: 
		ALL(监测所以FM1715操作范围之内的卡片) */
		/* STD(监测在FM1715操作范围之内处于HALT状态的卡片) */ 
/*输出: 
		/*FM1715_NOTAGERR: 无卡 */
		/* FM1715_OK: 应答正确 */ 
		/* FM1715_REQERR: 应答错误 */
/***************************************************************
*/
uchar Request(uchar mode) 
{ 
uchar temp; 

CRCPresetLSB = 0x63; 
CWConductance = 0x3f; 
BitFraming = 0x07; //发送7bit 
ChannelRedundancy = 0x07; //关闭接收电路CRC 
buffer[0] =mode ; //Request模式选择 
temp = Control; 
temp = temp & (0xF7); 
Control = temp; //屏蔽CRYPTO1位 
//Control = 0X01; //屏蔽CRYPTO1位 
temp = Command_Send(1, buffer, Transceive); 
if(temp == FALSE) 
	{ 
	return FM1702_NOTAGERR;
	} 
Read_FIFO(buffer); 		//从FIFO中读取应答信息 
temp = Judge_Req(buffer); //判断应答信号是否正确 
if (temp == TRUE) 
	{ 
	tagtype[0] = buffer[0]; 
	tagtype[1] = buffer[1];
	return FM1702_OK; 
	} 
return FM1702_REQERR; 

}
/*
anticollision
**************************************************************
名称: AntiColl 
功能: 该函数实现对放入FM1702操作范围之内的卡
		片的防冲突检测 
输入: N/A 
输出: 
FM1702_NOTAGERR: 无卡 
FM1702_BYTECOUNTERR: 接收字节错误 
FM1702_SERNRERR: 卡片序列号应答错误 
FM1702_OK: 卡片应答正确 
***************************************************************
*/
uchar AntiColl(void)
{
uchar temp;
uchar i;
uchar row,col;
uchar pre_row;

row=0;
col=0;
pre_row=0;

CRCPresetLSB =0x63;
CWConductance =0x3f;
//ModConductance =0x3f;
//	ChannelRedundancy =0x03;			//closed CRC,start parity
buffer[0] =RF_CMD_ANTICOL;
buffer[1] =0x20;
ChannelRedundancy=0x03;				//closed CRC,start parity
temp=Command_Send(2,buffer,Transceive);
while(1)
	{
	if(temp==FALSE)
		{
		return(FM1702_NOTAGERR);
		}
	temp = ErrorFlag;
	if((temp & 0x02)==0x02)
		return(FM1702_PARITYERR);
	if((temp & 0x04)==0x04)
		return(FM1702_FRAMINGERR);
	temp=FIFOLength;
	if (temp==0)
		{
		return FM1702_BYTECOUNTERR;
		}
	Read_FIFO(buffer);
	Save_UID(row, col, temp); //将收到的UID 放入UID 数组中
	//Show_UID(); //显示UID
	temp=ErrorFlag;			//判断接收数据是否出错
	temp=temp&0x01;
	if(temp==0x00)
		{
		temp=Check_UID();		//校验收到的UID
		if(temp==FALSE)
			{
			return(FM1702_SERNRERR);
			}
		return(FM1702_OK);
		}
		else
			{
			temp =CollPos;		//读取冲突检测寄存器read collision register
			row =temp/8;
			col =temp%8;
			buffer[0]=RF_CMD_ANTICOL;	//set the count that the data to be sent
			Set_BitFraming(row+pre_row,col); //设置待发送数据的字节数
			pre_row=pre_row+row;
			for(i=0;i<pre_row+1;i++)
				{
				buffer[i+2]=UID[i];
				}
			if(col!=0x00)
				{
				row=pre_row+1;
				}
			else
				{
				row=pre_row;
				}
			temp=Command_Send(row+2,buffer,Transceive);
		}
	}
}

/*
SELECT
***************************************************************
名称: Select_Card 
功能: 该函数实现对放入FM1702操作范围之内的某张
		卡片进行选择 
输入: N/A 
输出: 
FM1702_NOTAGERR: 无卡 
FM1702_PARITYERR: 奇偶校验错 
FM1702_CRCERR: CRC校验错 
FM1702_BYTECOUNTERR: 接收字节错误 
 FM1702_OK: 应答正确 
 FM1702_SELERR: 选卡出错 
 ****************************************************************
 */
uchar Select_Card(void)
{
uchar temp,i;


CRCPresetLSB = 0x63;
CWConductance = 0x3F;
buffer[0] =RF_CMD_SELECT;
buffer[1] =0x70;
for(i=0;i<5;i++)
	{
	buffer[i+2]=UID[i];
	}
ChannelRedundancy=0x0F;
temp=Command_Send(7, buffer, Transceive);
	
if(temp==FALSE)
	{
	return(FM1702_NOTAGERR);
	}
else
	{
	temp=ErrorFlag;
	if((temp&0x02)==0x02)
		return(FM1702_PARITYERR);
	if((temp&0x04)==0x04)
		return(FM1702_FRAMINGERR);
	if((temp&0x08)==0x08)
		return(FM1702_CRCERR);
	
	temp =FIFOLength;
	if(temp !=1)
		return(FM1702_BYTECOUNTERR);
	Read_FIFO(buffer);	//从FIFO中读取应答信息Read FIFO information
	temp=*buffer;	
	if ((temp == 0x08) ||(temp==0x88) ||(temp ==0x53)) //判断应答信号是否正确//check ack signal
		return(FM1702_OK);
	else
		return(FM1702_SELERR);
	}
}

/*
AUTHENTICATION
************************************************************** 
名称: Authentication 
功能: 该函数实现密码认证的过程 
输入: UID: 卡片序列号地址 
SecNR: 扇区号
mode: 模式
输出:
FM1702_NOTAGERR: 无卡 
FM1702_PARITYERR: 奇偶校验错
FM1702_CRCERR: CRC校验错 
FM1702_OK: 应答正确 
FM1702_AUTHERR: 权威认证有错 
/***************************************************************
*/
uchar Authentication(uchar idata *UID,uchar SecNR, uchar mode)
{
uchar idata i;
uchar idata temp,temp1;

	
CRCPresetLSB=0x63;
CWConductance=0x3f;
//ModConductance=0x3f;
temp1=Control;
temp1=temp1&0xf7;
Control=temp1;
	
if(mode ==1)				//AUTHENT1  authentication
	buffer[0]=RF_CMD_AUTH_LB;
else
	buffer[0]=RF_CMD_AUTH_LA;

buffer[1]=SecNR*4 +3;
for(i=0;i<4;i++)
	{
	buffer[2+i]=UID[i];
	}

ChannelRedundancy=0x0f;			//开启CRC,奇偶校验校验start crc,parity verify
temp =Command_Send(6,buffer,Authent1);
if(temp==FALSE)
	{
	return FM1702_NOTAGERR;
	}

temp =ErrorFlag;
if((temp&0x02) ==0x02)
	return FM1702_PARITYERR;

if((temp&0x04)==0x04)
	return FM1702_FRAMINGERR;

if((temp&0x08)==0x08)
	return FM1702_CRCERR;
	
temp=Command_Send(0,buffer,Authent2);		//Authent2
if(temp==FALSE)
	{
	return FM1702_NOTAGERR;
	}

temp=ErrorFlag;
if((temp&0x02)==0x02)
	return FM1702_PARITYERR;

if((temp&0x04)==0x04)
	return FM1702_FRAMINGERR;

if((temp&0x08)==0x08)
	return FM1702_CRCERR;

temp1=Control;
temp1=temp1&0x08;
if(temp1==0x08)
	{
	return FM1702_OK;
	}
return FM1702_AUTHERR;
}

/*
***************************************************************
名称: MIF_Read
功能: 该函数实现读MIFARE卡块的数值 
输入: buff: 缓冲区首地址
 Block_Adr: 块地址 
输出: 
FM1702_NOTAGERR: 无卡 
FM1702_PARITYERR: 奇偶校验错 
FM1702_CRCERR: CRC校验错 
FM1702_BYTECOUNTERR: 接收字节错误
 FM1702_OK: 应答正确 
/***************************************************************
*/
uchar MIF_Read(uchar idata *buff,uchar Block_Adr)
{
uchar idata temp;

	
CRCPresetLSB=0x63;
CWConductance=0x3f;
//ModConductance=0x3f;			//FM1702无此register
ChannelRedundancy=0x0f;
//InterruptRq=0x7f;
	
buff[0]=RF_CMD_READ;
buff[1]=Block_Adr;

temp=Command_Send(2,buff,Transceive);
if(temp==0)
	{
	return FM1702_NOTAGERR;
	}

temp=ErrorFlag;
if((temp&0x02)==0x02) 	
	return FM1702_PARITYERR;

if((temp&0x04)==0x04) 	
	return FM1702_FRAMINGERR;

if((temp&0x08)==0x08) 	
	return FM1702_CRCERR;

temp=FIFOLength;
if(temp==0x10)			//8K卡读数据长度为16 ,8k card read data length is 16
	{
	Read_FIFO(buff);	
	return FM1702_OK;
	}
else if(temp==0x04)		//Token 卡读数据长度为16 。Token card read data length is 16
	{
	Read_FIFO(buff);
	return FM1702_OK;
	}
else
	{
	return FM1702_BYTECOUNTERR;
	}

}

/*
**************************************************************
名称: MIF_Write 
功能: 该函数实现写MIFARE卡块的数值 
输入: buff: 缓冲区首地址
 Block_Adr: 块地址 
输出: FM1702_NOTAGERR: 无卡 
 FM1702_BYTECOUNTERR: 接收字节错误 
 FM1702_NOTAUTHERR: 未经权威认证
 FM1702_EMPTY: 数据溢出错误 
 FM1702_CRCERR: CRC校验错 
 FM1702_PARITYERR: 奇偶校验错 
 FM1702_WRITEERR: 写卡块数据出错 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -