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

📄 fm1715.c

📁 射频读卡芯片FM1715的C驱动程序。实现对FM1715初始化操作;实现对FM1715操作的总线方式(并行总线,SPI)选择;该函数实现从FM1715的EEPOM中读出数据等功能函数
💻 C
📖 第 1 页 / 共 3 页
字号:

#pragma small

#include <REG52.h>
#include "INTRINS.H"
//#include <string.h>
#include "FM1715.H"

extern void delay_1ms (uchar _1ms);
extern void delay_50us (uchar _50us);

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



//******************* FM1715 变量定义********************
//uchar idata PRO_SendBuf[16] _at_ 0x0080; //发送处理缓冲区 16 BYTE
//uchar idata PRO_RecvBuf[16] _at_ 0x0080; //接收处理缓冲区 16 BYTE

//uchar idata buffer[7];//[24];// _at_ 0x0060; //FM1715 命令发送接收缓冲区

//uchar idata UID[5];// _at_ 0x007a; //序列号
//uchar idata Secnr;// _at_ 0x0090; //扇区号
//uchar idata keybuffer[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} ; //密钥存放区



#ifdef FM_Serial

void SPI_W(uchar W_Byte);//向SPI串行总线发送数据
void WRITE_FM(uchar Adr,uchar BD);//向FM系列读写卡芯片发送数据
uchar READ_FM(uchar Adr);//从FM系列读写卡芯片读取数据



//FM1715 管脚定义
sbit FM_SPICS=P3^4; //片选脚
#define FM_SPICS_L FM_SPICS=0;
#define FM_SPICS_H FM_SPICS=1;

sbit FM_SPISI=P2^1; //串行数据输入脚
sbit FM_SPISO=P2^2; //串行数据输出脚
sbit FM_SPISCK=P2^0;//串行时钟输入脚



//注意:FM芯片的SPI接口可以对同一地址连续写入不同的数据,只需发送一次地址
//      而读数据就必须是发一个地址读一个数据。
/****************************************************************/
/*名称: WRITE_FM */
/*功能: 该函数实现把数据写入FM系列芯片的寄存器中 */
/*输入: Adr:FM芯片的寄存器地址
/*      BD:要写入的数据*/
/*输出: N/A */
/****************************************************************/
void WRITE_FM(uchar Adr,uchar BD)	
{
	Adr=(Adr<<1)&0x7E;	//要发送的命令是写命令
//	FM_SPICS=0;			//片选FM读写卡芯片
	FM_SPICS_L;
	SPI_W(Adr);			//发送写命令和地址
	SPI_W(BD);			//发送数据
//	FM_SPICS=1;			//关闭片选
	FM_SPICS_H;
}

/****************************************************************/
/*名称: READ_FM */
/*功能: 该函数实现读取FM系列芯片的寄存器中的内容 */
/*输入: Adr:要读取的FM芯片的寄存器地址
/*输出: 返回读出的内容 */
/****************************************************************/
uchar READ_FM(uchar Adr)	
{
	uchar i;
	uchar R_Byte;

//	FM_SPICS=0;			//片选FM读写卡芯片
	FM_SPICS_L;
	Adr=(Adr<<1)&0x7E|0x80;	//要发送的命令是读命令
	SPI_W(Adr);			//发送读命令和地址

	for(i=8;i>0;i--)
	{
		FM_SPISO=1;
		_nop_();
		FM_SPISCK = 1;
//		Delay_10_uS();
		_nop_(); _nop_(); _nop_();
    	_movcb_(FM_SPISO);//或用CY = FM_SPISO
    	_rlca_();
		FM_SPISCK = 0;
//		Delay_10_uS();
		_nop_();
	}
	_movra_(R_Byte);//或用R_Byte = ACC;

//	FM_SPICS=1;			//关闭片选
	FM_SPICS_H;
/*
	R_Byte=0;
	for(i=0; i<8; i++)
	{
		FM_SPISO=1;
		FM_SPISCK = 0;
		_nop_();_nop_(); _nop_(); _nop_();
		R_Byte *= 2;
		FM_SPISCK = 1;
		FM_SPISO=1;
		_nop_(); _nop_(); _nop_(); _nop_();
		if (FM_SPISO)   R_Byte++;
	}  // for i
*/
	return R_Byte;
}



/****************************************************************/
/*名称: SPI_W */
/*功能: 该函数实现把送据传送给FM系列芯片 */
/*输入: W_Byte:要传送的内容
/*输出: N/A  */
/****************************************************************/
void SPI_W(uchar W_Byte)
{
	uchar i;

	_movar_(W_Byte);//或用ACC = W_Byte
	for(i = 8; i >0; i--)
	{
		_rlca_();
		_movbc_(FM_SPISI);//或用FM_SPISI = CY;

		FM_SPISCK = 1;
//		Delay_10_uS();
		_nop_(); _nop_(); _nop_();
		FM_SPISCK = 0;
//		Delay_10_uS();
		_nop_();
	}

/*
	for(i=0;i<8;i++) 
	{
		FM_SPISCK = 0;  //准备改变数据线的数据
		_nop_(); _nop_();	_nop_(); _nop_();
		FM_SPISI = (bit)(W_Byte & 0x80);
		W_Byte= W_Byte << 1;    // RLC 左移1位
		_nop_(); _nop_(); _nop_(); _nop_(); //delay_1us(8);
		FM_SPISCK = 1; //写入一位
		_nop_(); _nop_();	_nop_(); _nop_();
	}  // for i	

*/


 }

#endif

/*
void DELAY_20us()
{
	uchar i;
	for(i=8;i>0;i--){};
}
*/
//5.2.1 接收到的卡片UID 号的判别
//****************************************************************
//*名称: Check_UID 
//*功能: 该函数实现对收到的卡片的序列号的判断 
//*输入: N/A */
//*输出: TRUE: 序列号正确 
//* FALSE: 序列号错误 
//****************************************************************
uchar Check_UID(uchar *CardID)
{
	uchar temp;
	uchar i;
	temp = 0x00;
	for(i = 0;i < 5; i++)
	{
		temp = temp ^ CardID[i];
	}
	if(temp == 0)
	{
		return TRUE;
	}
	return FALSE;
}

/*
//第 19 页 共 52 页
//5.2.2 保存卡片的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;
//				第 20 页 共 52 页
				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];
		}
	}
}
*/

//第 21 页 共 52 页
//5.2.3 设置待发送数据的字节数
//****************************************************************
//*名称: 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;
			break;
		case 4:
			buffer[1] = 0x60;
			break;
		default:
			break;
	}
	switch(col)
	{
		case 0:
			Bit_FrameW(0x00);
			break;
		case 1:
			Bit_FrameW(0x11);
			buffer[1] = (buffer[1] | 0x01);
			break;
		case 2:
			Bit_FrameW(0x22);
//第 22 页 共 52 页
			buffer[1] = (buffer[1] | 0x02);
			break;
		case 3:
			Bit_FrameW(0x33);
			buffer[1] = (buffer[1] | 0x03);
			break;
		case 4:
			Bit_FrameW(0x44);
			buffer[1] = (buffer[1] | 0x04);
			break;
		case 5:
			Bit_FrameW(0x55);
			buffer[1] = (buffer[1] | 0x05);
			break;
		case 6:
			Bit_FrameW(0x66);
			buffer[1] = (buffer[1] | 0x06);
			break;
		case 7:
			Bit_FrameW(0x77);
			buffer[1] = (buffer[1] | 0x07);
			break;
		default:
			break;
	}
}
*/

//第 23 页 共 52 页
//5.3 FM1715 基本函数
//5.3.1 总线选择
//****************************************************************
//*名称: FM1715_Bus_Sel 
//*功能: 该函数实现对FM1715 操作的总线方式(并行总线,SPI)选择 
//*输入: N/A 
//*输出: TRUE, 总线选择成功 
//* FALSE, 总线选择失败 
//****************************************************************
uchar FM1715_Bus_Sel(void)
{
	uchar i;
	Page_SelW(0x80); //表示PageSelect的值做为寄存器地址A5,A4 和A3,低
//三位寄存器地址A2-A0 由//外部地址线A2-A0 决定
	for(i = 0; i < RF_TimeOut; i++) //延时
	{
		if(CommandR == 0x00) //读命令执行结果, bit7为0表示接口检测结束
		{
			Page_SelW(0x00);
			return TRUE;
		}
	}
	return FALSE;
}

//第 24 页 共 52 页
//5.3.2 FM1715 初始化
//****************************************************************
//*名称: Init_FM1715 
//*功能: 该函数实现对FM1715 初始化操作 
//*输入: mode:工作模式, 0:TYPEA 模式 
//* 1:TYPEB模式 
//* 2:上海模式 
//*输出: N/A 
//****************************************************************
uchar Init_FM1715(void)
{
	uchar idata temp;
//	uchar idata rbt[8];
	int i;

/*
FM1715RST_H;
	for (i = 0; i < 0x1fff; i++)
	{
		_nop_();
	}
	for (i = 0; i < 0x1fff; i++)
	{
		_nop_();
	}
	FM1715RST_L;
	for (i = 0; i < 0x1fff; i++)
	{
		_nop_();
	}
	for (i = 0; i < 0x1fff; i++)
	{
		_nop_();
	}
	while(CommandR != 0) //等待Command = 0,FM1715 复位成功
	{
		_nop_();
	}
*/

//	FM1715RST_L;
//	delay_1ms(25);//25ms
	FM1715RST_H;
	delay_50us(50);//2.5ms
	FM1715RST_L;
	delay_1ms(25);//25ms

	i=2100;

	while(i>0) //等待Command = 0,FM1715 复位成功
	{
		if((CommandR&0x3F) == 0)
			break;
		delay_1ms (1);
		i--;
	}
	if(i<=0)
	{
		return FALSE;
	}

	if(FM1715_Bus_Sel()) //FM1715总线选择
	{
		TimerClockW(0x0b); //151us/per
		TimerControlW(0x02); //发送结束开定时器,接收开始关定时器
		TimerReloadW(0x42); //10ms 定时
		InterruptEnW(0x7f); //关所有中断
		temp = InterruptEnR;
		Int_ReqW(0x7f);
		MFOUTSelectW(0x02); //调试用
		TxControlW(0x5b); //开启TX1、TX2
		TypeSHW(0x00);
//	i=Read_E2(8,0,4,rbt);//该函数实现从FM1715的EE中读出数据,现在是把芯片的4字节ID号读出来



//MfInOutSlaveConfig();//重新初始化FM1702的内部寄存器值

		return TRUE;

	}
	return FALSE;	
}


//第 26 页 共 52 页
//5.3.3 命令传输
//****************************************************************
//*名称: Command_Send 
//*功能: 该函数实现向FM1715 发送命令集的功能 
//*输入: count, 待发送命令集的长度 
//* buff, 指向待发送数据的指针 
//* Comm_Set, 命令码 
//*输出: TRUE, 命令被正确执行 
//* FALSE, 命令执行错误 
//****************************************************************
uchar Command_Send(uchar count, uchar idata * buff, uchar Comm_Set)
{
//	uint j;
	uchar j;
	uchar  temp,temp1;
	CommandW(0x00);
	Clear_FIFO();
Int_ReqW(0);
	Write_FIFO(count, buff);
	temp = MFOUTSelectR;
	CommandW(Comm_Set); //命令执行
	for(j = 0; j< RF_TimeOut; j++) //检查命令执行否
	{
	delay_1ms(5);//5ms

//		temp = MFOUTSelectR;
		temp = CommandR;

/*
		temp1 = Int_ReqR & 0x80;
		if((temp == 0x00) || (temp1 == 0x80))
		{
			//Rxcontrol2=0x41;
			return TRUE;
		}
*/
		temp1 = Int_ReqR ;
		temp1 = temp1 & 0x10;
//		temp1 = Int_ReqR & 0x10;
		if((temp == 0x00) || (temp1 == 0x10))
		{
			return TRUE;
		}

	}
	return FALSE;
}

//第 27 页 共 52 页
//5.3.4 清除FM1715 的FIFO 中的数据
//****************************************************************
//*名称: Clear_FIFO 
//*功能: 该函数实现清空FM1715 中FIFO 的数据 
//*输入: N/A 
//*输出: TRUE, FIFO 被清空 
//* FALSE, FIFO 未被清空 
//****************************************************************
uchar Clear_FIFO(void)
{
	uchar temp;
	uint i;
	ControlW(ControlR|0x01); //清空FIFO
	for(i = 0; i < RF_TimeOut; i++) //检查FIFO 是否被清空
	{
		temp = FIFO_LengthR;
		if(temp == 0)
		{
			return TRUE;
		}
	}
	return FALSE;
}


//第 28 页 共 52 页
//5.3.5 向FM1715 的FIFO 中写入x 字节数据
//****************************************************************
//*名称: Write_FIFO 
//*功能: 该函数实现向FM1715 的FIFO 中写入x bytes 数据 
//*输入: count, 待写入字节的长度 
//* buff, 指向待写入数据的指针 
//*输出: N/A 
//****************************************************************
void Write_FIFO(uchar count,uchar idata *buff)
{
	uchar i;

#ifdef FM_Serial

//	FM_SPICS=0;			//片选FM读写卡芯片
	FM_SPICS_L;
	SPI_W(4);			//发送写命令和地址

	for(i = 0; i < count; i++)
	{
		SPI_W(*(buff + i));//发送数据
	}

//	FM_SPICS=1;			//关闭片选
	FM_SPICS_H;

⌨️ 快捷键说明

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