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

📄 fm1702.c

📁 很好用的FM1702的读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:


#include "head_macro.h"
#include "head_IO.h"
#include "head_buf.h"
#include "head_con.h"

#include <absacc.h>
#include <intrins.h>
#include "head_fm1702_Reg.h"

//uchar idata readdata[16];//	_at_	 0x0040;	//读写数据缓冲区
uchar idata value[4];//		_at_ 0x0050;		//增减的数值
uchar  idata KeySet;						//密码的类型
uchar  idata tagtype[2];//  _at_ 0x0096;	//卡片标识字符card indentify character

 //******************FM1715变量定义**********************************
//uchar  idata PRO_SendBuf[16] _at_ 0x0080; //发送处理缓冲区16BYTE
uchar  idata PRO_RecvBuf[16];// _at_ 0x0080; //接收处理缓冲区16BYTE
uchar  idata buffer[24];// _at_ 0x0060;	//fm1715 命令发送接收缓冲区
uchar  idata UID[5];//	_at_ 0x007a;		//序列号User ID
uchar   idata Secnr;// _at_ 0x0090; 		//扇区号

/*
***************************************************************/
/*名称: Judge_Req */
/*功能: 该函数实现对卡片复位应答信号的判断*/
/*输入: *buff, 指向应答数据的指针*/
/*输出: 
		temp1 =03 , 上海标准TOKEN卡
		temp1 =04 , MIFARE标准8K
		temp1 =05 , MIFARE 标准TOKEN卡
		temp1 =53 ,上海标准8K卡
		TRUE, 卡片应答信号正确*/
		/* FALSE, 卡片应答信号错误*/
/***************************************************************
*/
uchar Judge_Req(uchar idata *buff)
{
uchar	temp1, temp2;

temp1 = *buff;
temp2 = *(buff + 1);

if((temp1 == 0x02)||(temp1 == 0x03) || (temp1 == 0x04) || (temp1 == 0x05) 
|| (temp1 == 0x53) && (temp2 == 0x00))
	{
	return TRUE;
	}
return FALSE;
}
/*
******************************************
5.2.2 接收到的卡片UID号的判别
*名称: Check_UID 
*功能: 该函数实现对收到的卡片的序列号的判断 
*输入: N/A 
*输出: TRUE: 序列号正确 
               FALSE : 序列号错误 
******************************************
*/
uchar Check_UID(void)
{
uchar temp;
uchar i;

	
temp = 0x00;
for(i=0;i<5;i++)
	{
	temp=temp ^ UID[i];
	}
if(temp == 0)
	{
	return TRUE;
	}
return FALSE;

}

/*
保存卡片的UID号
***************************************************************
名称: Save_UID 
功能: 该函数实现保存卡片收到的序列号 
输入: 
		row: 产生冲突的行 
 		col: 产生冲突的列 
		length: 接収到的UID数据长度 
输出: N/A 
/***************************************************************
*/
void Save_UID(uchar row,uchar col,uchar length)
{
uchar i;
uchar temp;
uchar temp1;


if((row == 0x00)&&(col==0x00))
	{
	for(i=0;i<length;i++)
		{
		UID[i]=buffer[i];
		}
	}
else
	{
	temp=buffer[0];
	temp1=UID[row-1];
	switch(col)
		{
		case 0:
			temp1=0x00;
			row=row+1;
			break;
		case 1:
			temp=temp&0xFE;
			temp1=temp1&0x01;
			break;
		case 2:
			temp=temp&0xFC;
			temp1=temp1&0x03;
			break;
		case 3:
			temp=temp&0xF8;
			temp1=temp1&0x07;
			break;
		case 4:
			temp=temp&0xF0;
			temp1=temp1&0x0F;
			break;
		case 5:
			temp=temp&0xE0;
			temp1=temp1&0x1F;
			break;
		case 6:
			temp=temp&0xC0;
			temp1=temp1&0x3F;
			break;
		case 7:
			temp=temp&0x80;
			temp1=temp1&0x7F;
			break;
		default:
			break;
		}
	buffer[0]=temp;
	UID[row-1]=temp1 | temp;
	
	for(i=1;i<length;i++)
		{
		UID[row-1+i] =buffer[i];
		}
	}
}
/*
设置待发送数据的字节数
************************************************************
名称: Set_BitFraming 
功能: 该函数设置待发送数据的字节数
输入: 
		row: 产生冲突的行 
		col: 产生冲突的列 
输出: N/A 
*************************************************************
*/
void Set_BitFraming(uchar row,uchar col)
{

switch(row)
	{
	case 0:
		buffer[1]=0x20;
		break;
	case 1:
		buffer[1]=0x30;
		break;
	case 2:
		buffer[1]=0x40;
		break;
	case 3:
		buffer[1]=0x50;
	case 4:
		buffer[1]=0x60;
		break;
	default:
		break;
	}
	
switch(col)
	{
	case 0:
		BitFraming = 0x00;
		break;
	case 1:
		BitFraming =0x11;
		buffer[1]=(buffer[1]|0x01);
		break;
	case 2:
		BitFraming =0x22;
		buffer[1]=(buffer[1]|0x02);
		break;
	case 3:
		BitFraming =0x33;
		buffer[1]=(buffer[1]|0x03);
		break;
	case 4:
		BitFraming =0x44;
		buffer[1]=(buffer[1]|0x04);		
		break;
	case 5:
		BitFraming =0x55;
		buffer[1]=(buffer[1]|0x05);		
		break;
	case 6:
		BitFraming =0x66;
		buffer[1]=(buffer[1]|0x06);		
		break;
	case 7:
		BitFraming =0x77;
		buffer[1]=(buffer[1]|0x07);		
		break;
	default:
		break;
	}
}

/*
总线选择 
**************************************************************
名称: FM1702_Bus_Sel
功能: 该函数实现对FM1702操作的总线方式
	    : (并行总线,SPI)选择 
输入: N/A 
输出: 
		TRUE, 总线选择成功
		FALSE, 总线选择失败 
***************************************************************
*/
uchar FM1702_Bus_Sel(void)
{
uint i;

Page_Sel= 0x80;	//表示PageSelect的值做为寄存器地址A5,A4 和A3,低
					//三位寄存器地址A2---A0 由外部地址线A2---A0 决定
for(i=0;i<RF_TimeOut;i++) //延时
	{
	if(Command == 0x00)	//读命令执行结果, bit7为0表示接口检测结束
		{
		Page_Sel= 0x00; //探测完成。写0X00 切换到线性寻址方式
		return TRUE;
		}
	}
return FALSE;
}

/****************************************************************/
/*名称: Ivoid Init_fm1702(uchar mode)
/*功能: 该函数实现对FM1702初始化操作 */
/*输入: mode:工作模式, 	0:TYPEA模式 				*/
/* 								1:TYPEB模式 				*/
/* 								2:上海模式 				*/
/*输出: N/A */
/****************************************************************/
void Init_fm1702(uchar mode)
{ 
uint i;


MFRST = 1; //FM1715复位 
for (i = 0; i < 0x3fff; i++) 
	{ 
	_nop_(); 
	} 
MFRST = 0; 
for (i = 0; i < 0x3fff; i++)	
	{ 
	_nop_(); 
	} 

while(Command != 0) //等待Command = 0,FM1702复位成功 
	{
	_nop_(); 
	}
while(FM1702_Bus_Sel() == 0) //FM1702总线选择 
	{
	_nop_(); 
	}
//ClockQCControl =0x40;
//bitPhase =0xAD;
//Rxthreshold =0xFF;
//FIFOLevel =0x1A;
//IRQPinConfig =0x03;
/*
CWConductance =0x3F;
ModWidth =0x13;
RXControl1 =0x73;
DecoderControl =0x08;
bitPhase =0xAD;
Rxthreshold =0xFF;
Rxcontrol2 =0x41;
RxWait =0x06;
ChannelRedundancy =0x03;
CRCPresetLSB =0x63;
CRCPresetMSB =0x63;
FIFOLevel =0x08;
TimerClock =0x07;
TimerControl =0x06;
TimerReload =0x0A;
IRQPinConfig =0x02;
CryptoSelect =0x00;
//ClockQCControl =0x4F;
*/
//////////////////////////////
TimerClock =0x2B;	//15us/per
TimerControl = 0x02; //发送结束开定时器接收开始关定时器 
TimerReload = 0x42; //10ms定时 
InterruptEn = 0x7f; //关所有中断 
InterruptRq = 0x7f;  
//MFOUTSelect =0x02; //* mf OUT 选择配置寄存器 */   
//TxControl = 0x5b; //开启TX1 TX2 
TxControl = 0x53; //开启TX1 TX2 
//Rxcontrol2 =0x01;
Rxcontrol2 =0x03;
RxWait =0x06;
bitPhase =0xAD;

RXControl1 =0x73;
bufLed.reg =TxControl ;

if(mode ==TYPEA_MODE)	//TYPE A mode 
	{ 
	CryptoSelect	 = 0x00; 	
	} 
else if(mode == TYPEB_MODE) //TYPEB 模式 
	{ 
	//CoderControl = 0x20; 
	//TypeBFraming = 0x05; 
	//DecoderControl = 0x19; 
	ChannelRedundancy = 0x24; 
	TxControl = 0x4b; 
	CWConductance = 0x3f; 
	ModConductance = 0xaf; 
	} 
else if (mode == SHANGHAI_MODE) //上海模式
	{ 
	CryptoSelect	 = 0x01;
	} 
else	;
	
//Rxcontrol2=0x01; 

}



/****************************************************************/
/*名称: Command_Send */
/*功能: 该函数实现向FM1702发送命令集的功能 */ 
/*输入: 	count, 待发送命令集的长度 				*/ 
/* 			buff, 指向待发送数据的指针 			*/
/* 			Comm_Set, 命令码 */
/*输出:
			TRUE, 命令被正确执行 */
/* 			FALSE, 命令执行错误 */ 
/****************************************************************/
uchar Command_Send(uchar count,uchar idata *buff,uchar Comm_Set)
{ 
uint j; 
uchar idata temp,temp1;

//InterruptEn = 0x7f; 
//InterruptRq = 0x7f;  
Command = 0x00; 
Clear_FIFO();
Write_FIFO(count, buff); 
Command = Comm_Set; 	//命令执行 
ChannelRedundancy = 0x0f; 

//for(j = 0; j<RF_TimeOut; j++) //检查命令执行否 
for(j = 0; j<300; j++) //检查命令执行否 
	{ 
	//temp = MFOUTSelect; 
	//temp = Command ;
	temp = Command ;
	temp1 = InterruptRq & 0x80;
	if((temp == 0x00) || (temp1 == 0x80))
		{ 
		//if(bufTime.ledQF_Delay >=500)
			//{
			//bufTime.ledQF_Delay =0;
			COLON =0;
		//bufLed.reg = 0xFF;
			//}
		return TRUE; 
		} 
	} 
return FALSE; 
}
/*
***************************************************************/ 
/*名称: Read_E2 */
/*功能: 该函数实现从FM1702的EE中读出数据 */ 
/*输入: 
		lsb, EE地址(低字节) */
		/* msb, EE地址(高字节) */
		/* count, 待读出数据EE的字节个数 */
		/* buff, 指向待读出数据的指针 */
/*输出: 
		TRUE, EE数据正确读出 */
		/* FALSE, EE数据读出有误 */
/***************************************************************
*/
uchar Read_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff) 
{ 
uchar temp;

*buff=lsb; 
*(buff+1)=msb; 
*(buff+2)=count; 
temp=Command_Send(3,buff,ReadE2); 
Read_FIFO(buff);
if (temp==FALSE) 
	return(TRUE); 
return(FALSE);
} 
/*
***************************************************************/ 
/*名称: Write_E2 */
/*功能: 该函数实现向FM1715的EE中写入数据 */
/*输入: 
			lsb, EE地址(低字节) */
			/* msb, EE地址(高字节) */
			/* count, 待写入数据EE的字节个数 */
			/* buff, 指向待写入数据的指针 */
/*输出: 
			TRUE, EE数据正确写入 */
			/* FALSE, EE数据写入有误 */ 
/***************************************************************
*/
uchar Write_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff) 
{ 
uchar idata temp,i; 

for(i = 0;i < count; i++) 
	{ 
	*(buff + count - i + 2) = *(buff - i + count); 
	} 
*buff = lsb;
*(buff + 1) = msb; 
temp = Command_Send(count + 2, buff, WriteE2); 
temp = SecondaryStatus; 
temp = temp & 0x40; 
if (temp == 0x40) 
	{ 
	return TRUE; 
	} 
return FALSE;
}
/****************************************************************/
/*名称: Clear_FIFO */
/*功能: 该函数实现清空FM1715中FIFO的数据 */
/*输入: N/A */ 
/*输出: 
			TRUE, FIFO被清空*/
			/* FALSE, FIFO未被清空 */
/****************************************************************/
uchar Clear_FIFO(void)
{
uchar temp;
uint i;

temp =Control;			//Clear FIFO
temp =(temp |0x01);
Control =temp;
//for(i=0;i<RF_TimeOut;i++)   	//检查FIFO是否为空
for(i=0;i<100;i++)   	//检查FIFO是否为空
	{
	temp =FIFOLength;
	if(temp ==0)
		{
		return TRUE;
		}
	}
return FALSE;
}

/****************************************************************/

⌨️ 快捷键说明

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