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

📄 fm1702.c

📁 用c51驱动fm1702sl
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <string.h>#include <stdio.h>#include <absacc.h>#include <intrins.h>#include "FM1702.h"#include "reg52.h"#define NO_TIMER2           1bit CmdValid;unsigned char cardtype;uchar idata	tagtype[2];	            /* 卡片标识字符 *//* FM1715变量定义 */uchar idata	buffer[30];             /* FM1715命令发送接收缓冲区 */uchar idata	UID[5];                 /* 序列号 */uchar idata Secnr;			        /* 扇区号 */extern unsigned char read_reg(unsigned char idata SpiAddress);extern void write_reg(unsigned char idata SpiAddress,unsigned char dat);extern void delay1(uchar dlength);/****************************************************************//*名称: Clear_FIFO                                                                                            *//*功能: 该函数实现清空RC531中FIFO的数据                          *//*												       			                                                            *//*输入:                                                                                                               *//*      N/A                                                                                                                *//*                                                                                                                            *//*输出:                                                                                                               *//*	TRUE, FIFO被清空                                                                                     *//*	FALSE, FIFO未被清空  	                                                                        *//****************************************************************/uchar Clear_FIFO(void){	uchar temp;	uint  i;		temp =read_reg(Control);						//清空FIFO	temp = (temp | 0x01);	write_reg(Control, temp);	for(i = 0; i < RF_TimeOut; i++)				//检查FIFO是否被清空	{		temp = read_reg(FIFO_Length);		if(temp == 0)		{			return TRUE;		}	}	return FALSE;}/****************************************************************//*名称: Write_FIFO                                              *//*功能: 该函数实现向RC531的FIFO中写入x bytes数据                *//*												       			*//*输入:                                                         *//*      count, 待写入字节的长度                                 *//*	buff, 指向待写入数据的指针                                  *//*                                                              *//*输出:                                                         *//*	N/A                                                 		*//****************************************************************/void Write_FIFO(uchar count,uchar idata *buff){	uchar i;		for(i = 0; i < count; i++)	{		write_reg(FIFO,*(buff + i));	}}/****************************************************************//*名称: Read_FIFO                                               *//*功能: 该函数实现从RC531的FIFO中读出x bytes数据                *//*												        		*//*输入:                                                         *//*       buff, 指向读出数据的指针                               *//*                                                              *//*输出:                                                         *//*	 N/A                                                 		*//****************************************************************/uchar Read_FIFO(uchar idata *buff){	uchar temp;	uchar i;		temp =read_reg(FIFO_Length);	if (temp == 0)	{		return 0;	}	if (temp >= 24)						//temp=255时,会进入死循环	{									//因此增加FIFO_Length越限判断		temp = 24;						//yanshouli,2003-12-2	}	for(i = 0;i < temp; i++)	{ 		*(buff + i) =read_reg(FIFO);	}	return temp; }/****************************************************************//*名称: Judge_Req                                               *//*功能: 该函数实现对卡片复位应答信号的判断                      *//*												       			*//*输入:                                                         *//*       *buff, 指向应答数据的指针                              *//*                                                              *//*输出:                                                         *//*	 TRUE, 卡片应答信号正确                                     *//*   FALSE, 卡片应答信号错误                                    *//****************************************************************/uchar Judge_Req(uchar idata *buff){	uchar temp1,temp2;		temp1 = *buff;	temp2 = *(buff + 1);	//if(((temp1 == 0x03) || (temp1 == 0x04) || (temp1 == 0x05) || (temp1 == 0x53)) && (temp2 == 0x00))	//change by hbp  S70 temp1 = 0x02	if((temp1 != 0x00) && (temp2 == 0x00))	{		return TRUE;	}	return FALSE;}/****************************************************************//*名称: 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;}/****************************************************************//*名称: 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; break;	case 4:		buffer[1] = 0x60; break;	default:	break;	}	switch(col)	{	case 0:		write_reg(0x0F,0x00);  break;	case 1:		write_reg(0x0F,0x11); buffer[1] = (buffer[1] | 0x01); break;	case 2:		write_reg(0x0F,0x22); buffer[1] = (buffer[1] | 0x02); break;	case 3:		write_reg(0x0F,0x33); buffer[1] = (buffer[1] | 0x03); break;	case 4:		write_reg(0x0F,0x44); buffer[1] = (buffer[1] | 0x04); break;	case 5:		write_reg(0x0F,0x55); buffer[1] = (buffer[1] | 0x05); break;	case 6:		write_reg(0x0F,0x66); buffer[1] = (buffer[1] | 0x06); break;	case 7:		write_reg(0x0F,0x77); buffer[1] = (buffer[1] | 0x07); break;	default:	break;	}}/****************************************************************//*名称: Rc531_Bus_Sel                                                                                     *//*功能: 该函数实现对RC531操作的总线方式(并行总线,SPI)选择       */ /*												       			*//*输入:                                                         *//*      N/A                                                     *//*                                                              *//*输出:                                                         *//*	TRUE,  总线选择成功                                         *//*	FALSE, 总线选择失败  	                                    *//****************************************************************/uchar FM1715_Bus_Sel(void){	uchar i,temp;		write_reg(Page_Sel,0x80);	for(i = 0; i < RF_TimeOut; i++)	{		temp=read_reg(Command);		if(temp == 0x00)		{			write_reg(Page_Sel,0x00);			return TRUE;		}	}	return FALSE;}void Init_FM1715(void){	    uint	i,dat;			MFRST = 1;					//RC531复位	for (i = 0; i < 0x3fff; i++)	{	    _nop_();	}	MFRST = 0;	for (i = 0; i < 0x3fff; i++)	{	    _nop_();	}	sck=0;	dat=read_reg(0x01);  	while(dat!=0x00) dat=read_reg(0x01); 	FM1715_Bus_Sel();		 	//RC531总线选择}/****************************************************************//*名称: Command_Send                                            *//*功能: 该函数实现向RC531发送命令集的功能                       *//*												        		*//*输入:                                                         *//*       count, 待发送命令集的长度                              *//*	 buff, 指向待发送数据的指针                                 *//*       Comm_Set, 命令码                                       *//*												       			*//*输出:                                                         *//*	TRUE, 命令被正确执行                                        *//*	FALSE, 命令执行错误  	                                    *//****************************************************************/uchar Command_Send(uchar count,uchar idata * buff,uchar Comm_Set){	uint  j;	uchar idata temp;		write_reg(Command, 0x00);	Clear_FIFO();    if (count != 0)    {	   Write_FIFO(count, buff);    }	 	temp =read_reg(FIFO_Length);		write_reg(Command, Comm_Set);					//命令执行		for(j = 0; j< RF_TimeOut; j++)				//检查命令执行否	{		temp =read_reg(Command);		if(temp == 0x00)  		{			return TRUE;		}	}	return FALSE;	}#if 0/****************************************************************//*名称: Read_E2 *//*功能: 该函数实现从FM1715的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 = read_reg(0x05);	temp = temp & 0x40;	if(temp == 0x40)	{		return TRUE;	}	return FALSE;}#endif/****************************************************************//*名称: MIF_Halt *//*功能: 该函数实现暂停MIFARE卡*//*输入: N/A *//*输出: FM1715_OK: 应答正确*//* FM1715_PARITYERR: 奇偶校验错*//* FM1715_CRCERR: CRC校验错*//* FM1715_NOTAGERR: 无卡*//****************************************************************/uchar MIF_Halt(void){	/*~~~~~~~~~*/	uchar	temp;	uint	i;	/*~~~~~~~~~*/	write_reg(0x23,0x63);	write_reg(0x12,0x3f);	write_reg(0x22,0x07);               //change by hbp 03-->07	*buffer = RF_CMD_HALT;	*(buffer + 1) = 0x00;	temp = Command_Send(2, buffer, Transmit);	if(temp == TRUE)	{		for(i = 0; i < 0x50; i++)		{			_nop_();		}		return FM1715_OK;	}	else	{		temp = read_reg(0x0A);		if((temp & 0x02) == 0x02)		{			return(FM1715_PARITYERR);		}		if((temp & 0x04) == 0x04)		{			return(FM1715_FRAMINGERR);		}		return(FM1715_NOTAGERR);	}}///////////////////////////////////////////////////////////////////////// 转换密钥格式///////////////////////////////////////////////////////////////////////char M500HostCodeKey(unsigned char *uncoded, unsigned char *coded)   {    char idata status = FM1715_OK;    unsigned char idata cnt = 0;    unsigned char idata ln  = 0;         unsigned char idata hn  = 0;              for (cnt = 0; cnt < 6; cnt++)    {        ln = uncoded[cnt] & 0x0F;        hn = uncoded[cnt] >> 4;        coded[cnt * 2 + 1] = (~ln << 4) | ln;        coded[cnt * 2 ] = (~hn << 4) | hn;    }    return FM1715_OK;}/****************************************************************//*名称: Load_keyE2 *//*功能: 该函数实现把E2中密码存入FM1715的keybuffer中*//*输入: Secnr: EE起始地址*//*输出: True: 密钥装载成功*//* False: 密钥装载失败*//****************************************************************/uchar Load_keyE2_CPY(uchar *uncoded_keys){    uchar temp;    unsigned char coded_keys[13];        M500HostCodeKey(uncoded_keys, coded_keys);	temp = Command_Send(12, coded_keys, LoadKey);	temp = read_reg(0x0A) & 0x40;	if (temp == 0x40)	{		return FALSE;	}	return TRUE;}/****************************************************************//*名称: Request                                                 *//*功能: 该函数实现对放入RC531操作范围之内的卡片的Request操作    */ /*												       			*//*输入:                                                         *//*       mode: ALL(监测所以RC531操作范围之内的卡片)			   	*//*	       STD(监测在RC531操作范围之内处于HALT状态的卡片)       *//*                                                              *//*输出:                                                         *//*	 FM222_NOTAGERR: 无卡                                       *//*   FM222_OK: 应答正确                                         *//*	 FM222_REQERR: 应答错误										*//****************************************************************/uchar Request(uchar mode){    uchar  temp;    write_reg(TxControl,0x58);    delay1(1);    write_reg(TxControl,0x5b);		     write_reg(CRCPresetLSB,0x63);    write_reg(CWConductance,0x3f);    buffer[0] = mode;					//Request模式选择    write_reg(Bit_Frame,0x07);			//发送7bit    write_reg(ChannelRedundancy,0x03);	//关闭CRC    write_reg(TxControl,0x5b);     write_reg(Control,0x01); //temp;						//屏蔽CRYPTO1位    temp = Command_Send(1, buffer, Transceive);    if(temp == FALSE)    {	    return FM1715_NOTAGERR;    }		    Read_FIFO(buffer);					//从FIFO中读取应答信息    temp = Judge_Req(buffer);			//判断应答信号是否正确    if (temp == TRUE)    {        tagtype[0] = buffer[0];        tagtype[1] = buffer[1];        return FM1715_OK;    }    return FM1715_REQERR;}/****************************************************************//*名称: AntiColl *//*功能: 该函数实现对放入FM1715操作范围之内的卡片的防冲突检测*//*输入: N/A *//*输出: FM1715_NOTAGERR: 无卡*//* FM1715_BYTECOUNTERR: 接收字节错误*//* FM1715_SERNRERR: 卡片序列号应答错误*//* FM1715_OK: 卡片应答正确*//****************************************************************/uchar AntiColl(void){	/*~~~~~~~~~~~~~*/	uchar	temp;	uchar	i;	uchar	row, col;	uchar	pre_row;	/*~~~~~~~~~~~~~*/	row = 0;	col = 0;

⌨️ 快捷键说明

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