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

📄 fm1715.c

📁 射频读卡芯片FM1715的C驱动程序。实现对FM1715初始化操作;实现对FM1715操作的总线方式(并行总线,SPI)选择;该函数实现从FM1715的EEPOM中读出数据等功能函数
💻 C
📖 第 1 页 / 共 3 页
字号:
#else
	for(i = 0; i < count; i++)
	{
		FIFOW(*(buff + i));
	}
#endif
}


//第 29 页 共 52 页
//5.3.6 从FM1715 的FIFO 中读出x 字节数据
//****************************************************************
//*名称: Read_FIFO 
//*功能: 该函数实现从FM1715 的FIFO 中读出x bytes 数据 
//*输入: buff, 指向读出数据的指针 
//*输出: N/A 
//****************************************************************
uchar Read_FIFO(uchar idata *buff,uchar rlen)
{
	uchar temp;
	uchar i;
	temp = FIFO_LengthR;
	if (temp)
	{
		if (temp >= rlen)//24) //temp=255 时,会进入死循环
		{ //因此增加FIFO_Length 越限判断
			temp =rlen;// 24; //yanshouli,2003-12-2
		}

		for(i = 0;i < temp; i++)
		{
			*(buff + i) = FIFOR;
//		buff[i] =FIFOR;
		}
	}
	return temp;
}

/*
//重新初始化FM1702的内部寄存器值
uchar MfInOutSlaveConfig(void)
{
	uchar temp;
	uchar idata MSndBuffer[34];

	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	ChannelRedundancyW(0x03);



	MSndBuffer[0] = 0x10; // addr low byte
	MSndBuffer[1] = 0x00; // addr high byte
	
	MSndBuffer[2] = 0x00; // Page
	MSndBuffer[3] = 0x58; // RegTxControl modsource 11,InvTx2,Tx2RFEn,TX1RFEn
	MSndBuffer[4] = 0x3F; // RegCwConductance
	MSndBuffer[5] = 0x3F; // RFU13
	MSndBuffer[6] = 0x19; // RFU14
	MSndBuffer[7] = 0x13; // RegModWidth     
	MSndBuffer[8] = 0x00; // RFU16
	MSndBuffer[9] = 0x00; // RFU17
	
	MSndBuffer[10] = 0x00; // Page
	MSndBuffer[11] = 0x73; // RegRxControl1 
	MSndBuffer[12] = 0x08; // RegDecoderControl
	MSndBuffer[13] = 0xAD;//0x6c; // RegBitPhase     
	MSndBuffer[14] = 0xFF; // RegRxThreshold  
	MSndBuffer[15] = 0x00; // RFU1D
	MSndBuffer[16] = 0X41;//0x00; // RegRxControl2   
	MSndBuffer[17] = 0x00; // RegClockQControl
	
	MSndBuffer[18] = 0x00; // Page
	MSndBuffer[19] = 0x06; // RegRxWait
	MSndBuffer[20] = 0x03; // RegChannelRedundancy
	MSndBuffer[21] = 0x63; // RegCRCPresetLSB    
	MSndBuffer[22] = 0x63; // RegCRCPresetMSB    
	MSndBuffer[23] = 0x00;  // RFU25
	MSndBuffer[24] = 0x00;//0x04; // RegMfOutSelect enable mfout = manchester HT
	MSndBuffer[25] = 0x00; // RFU27
	 
	// PAGE 5      FIFO, Timer and IRQ-Pin Configuration
	MSndBuffer[26] = 0x00; // Page
	MSndBuffer[27] = 0x08; // RegFIFOLevel       
	MSndBuffer[28] = 0x07; // RegTimerClock      
	MSndBuffer[29] = 0x06; // RegTimerControl    
	MSndBuffer[30] = 0x0A; // RegTimerReload     
	MSndBuffer[31] = 0x02; // RegIRqPinConfig    
	MSndBuffer[32] = 0x00; // RFU    
	MSndBuffer[33] = 0x00; // RFU
	temp = Command_Send(34, MSndBuffer, WriteE2);
	if (temp == TRUE)//FALSE)    LJL 050415
	{
		return FM1715_OK;
	}
	else
	{
		return FM1715_Err;
	}
}

*/



//第 30 页 共 52 页
//5.4 FM1715 卡片操作基本函数
//5.4.1 HALT
//****************************************************************
//*名称: MIF_Halt 
//*功能: 该函数实现暂停MIFARE 卡 
//*输入: N/A 
//*输出: FM1715_OK: 应答正确 
//* FM1715_PARITYERR: 奇偶校验错 
//* FM1715_CRCERR: CRC 校验错 
//* FM1715_NOTAGERR: 无卡 
//****************************************************************
uchar MIF_Halt(void)
{
	uchar temp;
	uchar idata buffer[2];

	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	ChannelRedundancyW(0x03);
	*buffer = RF_CMD_HALT;
	*(buffer + 1) = 0x00;
	temp = Command_Send(2, buffer, Transceive);
	if (temp == TRUE)//FALSE)    LJL 050415
	{
		return FM1715_OK;
	}
	else
	{
		return FM1715_Err;
/*
		temp = ErrorFlagR;
		if ((temp & 0x02)==0x02)
		{
			return(FM1715_PARITYERR);
		}
		if ((temp & 0x04)==0x04)
		{
			return(FM1715_FRAMINGERR);
		}
			return(FM1715_NOTAGERR);
*/
	}
}


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

//	TxControl = 0x58;
//	delay(1);					//??????????? 1000
//	TxControl = 0x5b;
	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	buffer[0] = mode; //Request 模式选择
	Bit_FrameW(0x07); //发送7bit
	ChannelRedundancyW(0x03); //关闭CRC
	TxControlW(0x5b);
	ControlW(0x01); //屏蔽CRYPTO1 位
	temp = Command_Send(1, buffer, Transceive);
	if(temp == FALSE)
	{
		return FM1715_NOTAGERR;
	}
	if(Read_FIFO(buffer,2)>0) //从FIFO 中读取应答信息
	{
//		tagtype[0] = buffer[0];
//		tagtype[1] = buffer[1];
		return FM1715_OK;
	}
	else
		return FM1715_Err;
}
//注temp1 = 03 ; 上海标准TOKEN卡
//temp1 = 04 ; MIFARE标准8K
//temp1 = 05 ; MIFARE标准TOKEN卡
//temp1 = 53 ; 上海标准8K卡
//此返回值为目前市场使用的各类卡片的返回结果将来可能有更多的返回类别


//第 33 页 共 52 页
//5.4.4 ANTICOLLISION
//****************************************************************
//*名称: AntiColl 
//*功能: 该函数实现对放入FM1715 操作范围之内的卡片的防冲突检测 
//*输入: N/A 
//*输出: FM1715_NOTAGERR: 无卡 
//* FM1715_BYTECOUNTERR: 接收字节错误 
//* FM1715_SERNRERR: 卡片序列号应答错误 
//* FM1715_OK: 卡片应答正确 
//****************************************************************
uchar AntiColl(uchar *CardID)
{
	uchar temp;
	uchar i;
//	uchar row,col;
//	uchar pre_row;

	uchar idata buffer[5];

//	row = 0;
//	col = 0;
//	pre_row = 0;
	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	ModConductanceW(0x3f);
	buffer[0] = RF_CMD_ANTICOL;
	buffer[1] = 0x20;
	ChannelRedundancyW(0x03); //关闭CRC,打开奇偶校验
	temp=Command_Send(2, buffer, Transceive);
	while(1)
	{
		if(temp==FALSE)
		{
			return(FM1715_NOTAGERR);
		}
		temp = ErrorFlagR;
		if((temp & 0x02)==0x02)
			return(FM1715_PARITYERR);
		if((temp & 0x04)==0x04)
			return(FM1715_FRAMINGERR);
//		temp = ErrorFlagR&0x01; //判断接収数据是否出错
		if((temp & 0x01) == 0x00)  //判断接収数据是否出错
		{
			if(Read_FIFO(buffer,5)>0)
			{
				temp = Check_UID(buffer); //校验收到的UID
				if(temp == FALSE)
				{
					return(FM1715_SERNRERR);
				}
				for(i = 0; i < 4; i++)
				{
					CardID[i] = buffer[i];
				}
				return(FM1715_OK);
			
			}
			else
				return FM1715_BYTECOUNTERR;

		}
		else
			return FM1715_ANTICOLLERR;

/*
		else
		{
			temp = CollPosR; //读取冲突检测寄存器
			row = temp / 8;
			col = temp % 8;
			buffer[0] = RF_CMD_ANTICOL;
			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);
		}
*/
	}
}



  
//****************************************************************
//*名称: GetCardID 
//*功能: 该函数实现获取Mifare卡的IC号
//*输入: Mode: 寻卡模式RF_CMD_REQUEST_STD、RF_CMD_REQUEST_ALL
//* 
//*输出: 操作状态码 
//* 读出数据存于buffer 中 
//****************************************************************
uchar GetCardID(uchar Mode,uchar *CardID)
{
	uchar temp;
	uchar ret_code=0;


	delay_1ms(50); //为了降低功耗,在这里延时50毫秒再读卡,降低读卡频率
	TxControlW(0x5B);	//启动射频发射端口
	temp=ControlR;
	ControlW(temp&0xDF);//使读卡芯片退出待机状态

	MIF_Halt(); //Halt
	temp = Request(Mode);//RF_CMD_REQUEST_STD); //Request
	if(temp != FM1715_OK)
	{
		ret_code=FM1715_REQERR;
	}
	else
	{
		temp = AntiColl(CardID); //AntiCol
		if(temp != FM1715_OK)
			ret_code=FM1715_ANTICOLLERR;
	}
	temp=ControlR;
	ControlW(temp|0x20);//使读卡芯片处于待机状态
	TxControlW(0x58);	//关闭射频发射端口
	return ret_code;
}


/*

//第 35 页 共 52 页
//5.4.5 SELECT
//****************************************************************
//*名称: Select_Card 
//*功能: 该函数实现对放入FM1715 操作范围之内的某张卡片进行选择 
//*输入: N/A 
//*输出: FM1715_NOTAGERR: 无卡 
//* FM1715_PARITYERR: 奇偶校验错 
//* FM1715_CRCERR: CRC 校验错 
//* FM1715_BYTECOUNTERR: 接收字节错误 
//* FM1715_OK: 应答正确 
//* FM1715_SELERR: 选卡出错 
//****************************************************************
uchar Select_Card(void)
{
	uchar temp,i;
	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	buffer[0] = RF_CMD_SELECT;
	buffer[1] = 0x70;
	for(i = 0; i < 5; i++)
	{
		buffer[i+2]=UID[i];
	}
	ChannelRedundancyW(0x0f); //开启CRC,奇偶校验校验
	temp=Command_Send(7,buffer,Transceive);
	if(temp==FALSE)
	{
		return(FM1715_NOTAGERR);
	}
	else
	{
		temp=ErrorFlagR;
		if ((temp & 0x02)==0x02)
			return(FM1715_PARITYERR);
		if((temp & 0x04)==0x04)
			return(FM1715_FRAMINGERR);
		if ((temp & 0x08)==0x08)
			return(FM1715_CRCERR);
		temp=FIFO_LengthR;
		if (temp!=1)
			return(FM1715_BYTECOUNTERR);
		Read_FIFO(buffer); //从FIFO 中读取应答信息
		temp = buffer[0];
//		if ((temp==0x08) || (temp==0x88) || (temp==0x53)) //判断应答信号是否正确
		if (temp!=0) //判断应答信号是否正确			//?????????
			return(FM1715_OK);
		else
			return(FM1715_SELERR);
	}
}


//第 36 页 共 52 页



//5.4.2 LOADKEY
//****************************************************************
//*名称: Load_keyE2 
//*功能: 该函数实现把E2中密码存入FM1715的keybuffer中 
//*输入: Secnr: EE起始地址 
//*输出: True: 密钥装载成功 
//* False: 密钥装载失败 
//* 本程序是用E2P密码认证时使用的,是通过把FM1715的E2PROM里保存的密码发送到认证缓冲区进行卡密码认证
//****************************************************************
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 = ErrorFlagR & 0x40;
	if (temp == 0x40)
	{
		return FALSE;
	}
	return TRUE;
}


//第 31 页 共 52 页
//5.4.2 LOADKEY
//****************************************************************
//*名称: Load_key_CPY 
//*功能: 该函数实现把MCU单元中的密码存入FM1715 的keybuffer 中 
//*输入: keybuffer: 密钥存放缓冲区 
//*输出: True: 密钥装载成功 
//* False: 密钥装载失败 
//* 本程序是直接密码认证时使用的,是直接把MCU里保存的密码发送给FM1715的密码认证缓冲区进行卡密码认证
//****************************************************************
uchar Load_key_CPY(void)
{
	uchar temp,i;
	uchar ln = 0;
	uchar hn = 0;
	for(i = 0; i < 6; i++) //密码转换成RC531 密码格式?
	{
		ln =keybuffer[i] & 0x0f; //低4 位
		hn = keybuffer[i] >> 4; //高4 位
		buffer[i * 2 + 1] = (~ln << 4) | ln;
		buffer[i * 2] = (~hn << 4) | hn;
	}
		temp = Command_Send(12, buffer, LoadKey);
		temp = ErrorFlagR & 0x40;
	if (temp == 0x40)
	{
		return FALSE;
	}
	return TRUE;
}


//第 32 页 共 52 页

//5.4.6 AUTHENTICATION
//****************************************************************
//*名称: Authentication 
//*功能: 该函数实现密码认证的过程 
//*输入: UID: 卡片序列号地址 
//* SecNR: 扇区号 
//* Mode: 认证模式  =0表示用密码A认证,=1表示用密码B认证
//*输出: FM1715_NOTAGERR: 无卡 
//* FM1715_PARITYERR: 奇偶校验错 
//* FM1715_CRCERR: CRC 校验错 
//* FM1715_OK: 应答正确 
//* FM1715_AUTHERR: 权威认证有错 
//****************************************************************
uchar Authentication(uchar idata *UID,uchar SecNR,uchar mode)
{
	uchar idata i;
	uchar idata temp,temp1;
	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	ModConductanceW(0x3f);
	temp1 = ControlR;
	temp1 = temp1 & 0xf7;
	ControlW(temp1);
	if (mode == 1) //AUTHENT1
		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];
	}
	ChannelRedundancyW(0x0f); //开启CRC,奇偶校验校验
	temp = Command_Send(6, buffer, Authent1);
	if (temp == FALSE)
	{
		return FM1715_NOTAGERR;
	}
	temp = ErrorFlagR;
	if ((temp & 0x02) == 0x02)
		return FM1715_PARITYERR;
	if((temp & 0x04) == 0x04)
		return FM1715_FRAMINGERR;
	if ((temp & 0x08) == 0x08)
		return FM1715_CRCERR;
	temp = Command_Send(0, buffer, Authent2); //AUTHENT2
	if(temp == FALSE)
	{
		return FM1715_NOTAGERR;
//第 37 页 共 52 页
	}
	temp = ErrorFlagR;
	if ((temp & 0x02) == 0x02)
		return FM1715_PARITYERR;
	if((temp & 0x04) == 0x04)
		return FM1715_FRAMINGERR;
	if ((temp & 0x08) == 0x08)
	return FM1715_CRCERR;
		temp1 = ControlR;
	temp1 = temp1 & 0x08; //Crypto1on=1,验证通过
	if (temp1 == 0x08)
	{
		return FM1715_OK;
	}
	return FM1715_AUTHERR;
}


//第 38 页 共 52 页
//5.4.7 READ
//****************************************************************
//*名称: MIF_Read 
//*功能: 该函数实现读MIFARE 卡块的数值 
//*输入: buff: 缓冲区首地址 
//* Block_Adr: 块地址 
//*输出: FM1715_NOTAGERR: 无卡 
//* FM1715_PARITYERR: 奇偶校验错 
//* FM1715_CRCERR: CRC 校验错 
//* FM1715_BYTECOUNTERR: 接收字节错误 
//* FM1715_OK: 应答正确 
//****************************************************************
uchar MIF_READ(uchar idata *buff,uchar Block_Adr)
{
	uchar idata temp;
	CRCPresetLSBW(0x63);
	CWConductanceW(0x3f);
	ModConductanceW(0x3f);
	ChannelRedundancyW(0x0f);

⌨️ 快捷键说明

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