当前位置:文档之家› 可以用的fm1702读卡源代码

可以用的fm1702读卡源代码

#include "typedef.h"
#include "function.h"
#include "global.h"

//总线选择



unsigned char FM1702_SPI_Init(void)
{
unsigned int i;
SPI_MasterWriteData(Page_Reg,0x80);//写
for(i=0;i<0xfff;i++)
{
if(SPI_MasterReadData(Page_Reg)==0x80)
{
SPI_MasterWriteData(Page_Reg,0x00); //1702选通SPI接口
for(i=0;i<0xfff;i++)
{
if(SPI_MasterReadData(Page_Reg)==0)
return 1;
}
}
}
return 0;
}

//复位

void FM1702_Rset(void)
{
BIT_SET(SPI_CTRL_POUT,SPI_RST_PIN);
Delay_us(500);
BIT_CLEAR(SPI_CTRL_POUT,SPI_RST_PIN);
Delay_us(500);
}


//启动外部晶振
void Rf_On(void)
{
SPI_MasterWriteData(TxControl_Reg,0x5B);
}


//FM1702初始化
unsigned char FM1702_Init(void)
{
unsigned char i;
FM1702_Rset();
i = FM1702_SPI_Init();
if(i)
{
Rf_On();
return OK;
}
return ERROR;
}



/********************************************************************************************************/
/*名称: Command_Send */
/*功能: 该函数实现向RC531发送命令集的功能 */
/* */
/*输入: */
/* count, 待发送命令集的长度 */
/* buff, 指向待发送数据的指针 */
/* Comm_Set, 命令码 */
/* */
/*输出: */
/* OK: 命令被正确执行 */
/* ERROR: 命令执行错误 */
/********************************************************************************************************/
unsigned char Command_Send(unsigned char count,unsigned char * buff,unsigned char Comm_Set)
{

unsigned char temp,temp1;

SPI_MasterWriteData(InterruptRq_Reg,0x7f); //清除中断标识
SPI_MasterWriteData(InterruptEn_Reg,0xbf); //中断使能
SPI_MasterWriteData(TimerControl_Reg,0x02); //数据发送结束后,定时器开始计时
SPI_MasterWriteData(Command_Reg,0x00);
Clear_FIFO();
Write_FIFO(count,buff);
SPI_MasterWriteData(Command_Reg,Comm_Set); //命令执行
while(1) //检查中断标识
{
temp=SPI_MasterReadData(InterruptRq_Reg);
if(temp&0x04) //IdelIRq
{
temp1=ERROR_SUCCESS;
break;
}
if(temp&0x08) //RxIRq
{
temp1=ERROR_SUCCESS;
break;
}
if(temp&0x20) //TimerIRq 定时器时

间用尽
{
temp1=ERROR_NOTAG;
break;
}
}
return(temp1);
}


/********************************************************************************************************/
/*名称: Request */
/*功能: 该函数实现对放入RC531操作范围之内的卡片的Request操作 */
/* */
/*输入: */
/* mode: WAKEUP(监测所以FM17XX操作范围之内的卡片) */
/* STD(监测在FM17XX操作范围之内处于HALT状态的卡片) */
/* */
/*输出: */
/* tagtype[0],tagtype[1] =ATQA */
/* OK: 应答正确 */
/* ERROR: 应答错误 */
/********************************************************************************************************/
unsigned char Request(unsigned char mode)
{
unsigned char temp;
FIFO_Buff[0]=mode; //Request模式选择
SPI_MasterWriteData(BitFraming_Reg,0x07); //发送7bit
SPI_MasterWriteData(ChannelRedundancy_Reg,0x03); //关闭CRC和奇偶校验
temp=SPI_MasterReadData(Control_Reg);
temp=temp & (0xf7);
SPI_MasterWriteData(Control_Reg,temp); //屏蔽CRYPTO1位
SetTime_delay(5); //设置超时时间
temp=Command_Send(1,FIFO_Buff,Transceive);
if(temp == ERROR_NOTAG)
{
return(ERROR_NOTAG);
}
if(SPI_MasterReadData(FIFOLength_Reg)!=2)
return(ERROR);
//Read_FIFO(FIFO_Buff); //从FIFO中 read取应答信息
//tagtype[0]=FIFO_Buff[0];
//tagtype[1]=FIFO_Buff[1];
return(ERROR_SUCCESS);

}


/********************************************************************************************************/
/*名称: AntiColl */
/*功能: 该函数实现对放入RC531操作范围之内的卡片的防冲突检测 */
/* */
/*输入: */
/* N/A */
/* */
/*输出:

*/
/* OK: 防冲突完成 */
/* ERROR: 防冲突失败 */
/********************************************************************************************************/
unsigned char AntiColl(void)
{
unsigned char temp;
unsigned char i;
unsigned char row,col;
unsigned char pre_row;

row=0;
col=0;
pre_row=0;
SPI_MasterWriteData(ChannelRedundancy_Reg,0x03); //关闭CRC,打开奇偶校验
FIFO_Buff[0]=Anticoll;
FIFO_Buff[1]=0x20;
SetTime_delay(50);
temp=Command_Send(2,FIFO_Buff,Transceive);
while(1)
{
if(temp==ERROR_NOTAG)
return(ERROR_NOTAG);

temp=SPI_MasterReadData(FIFOLength_Reg);
if (temp==0)
return(ERROR_NOTAG);
Read_FIFO(FIFO_Buff);
Save_UID(row,col,temp); //将收到的UID放入UID数组中

temp=SPI_MasterReadData(ErrorFlag_Reg); //判断接収数据是否出错
temp=temp & 0x01;
if(temp==0x00)
{
temp=Check_UID(); //校验收到的UID
if(temp==ERROR_SERNR)
return(ERROR_SERNR);
return(ERROR_SUCCESS);
}
else
{
temp=SPI_MasterReadData(CollPos_Reg); // read取冲突检测寄存器
row=temp/8;
col=temp%8;
FIFO_Buff[0]=Anticoll;
Set_BitFraming(row+pre_row,col); //设置待发送数据的字节数
pre_row=pre_row+row;
for(i=0;iFIFO_Buff[i+2]=UID[i];
if(col!=0x00)
row=pre_row+1;
else
row=pre_row;
temp=Command_Send(row+2,FIFO_Buff,Transceive);
}
}
}


/********************************************************************************************************/
/*名称: Select_Card */
/*功能: 该函数实现对放入FM17XX操作范围之内的某张卡片进行选择 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* OK: 选卡成功 */
/* ERROR:选卡失败 */
/********************************************************************************************************/
unsigned char Select_Card(void)
{
unsigned char temp,i;
FIFO_Buff[0]=Select;
FIFO_Buff[1]=0x70;
for(i=0;i<5;i++)
FIFO_Buff[i+2]=UID[i];
SPI_MasterWriteData(ChannelRedundancy_Reg,0x0f);

//开启CRC,奇偶校验校验
SetTime_delay(10);
temp=Command_Send(7,FIFO_Buff,Transceive);
if(temp==ERROR_NOTAG)
return(ERROR_NOTAG);
else
{
temp=SPI_MasterReadData(FIFOLength_Reg);
if (temp!=1)
return(ERROR_NOTAG);
Read_FIFO(FIFO_Buff); //read FIFO
SAK=FIFO_Buff[0];
return(ERROR_SUCCESS);
}
}



/*******************************************************************************************************/
/*名称: Clear_FIFO */
/*功能: 该函数实现清空FM17XX中FIFO的数据 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* OK: FIFO被清空 */
/* ERROR: FIFO未被清空 */
/*******************************************************************************************************/
unsigned char Clear_FIFO(void)
{
unsigned char temp;
unsigned char i;

temp=SPI_MasterReadData(Control_Reg); //清空FIFO
temp=(temp | 0x01);
SPI_MasterWriteData(Control_Reg,temp);
for(i=0;i<0x0FF;i++) //检查FIFO是否被清空
{
temp=SPI_MasterReadData(FIFOLength_Reg);
if(temp==0)
return(OK);
}
return(ERROR);
}


/********************************************************************************************************/
/*名称: Write_FIFO */
/*功能: 该函数实现向FM17XX的FIFO中写入数据 */
/* */
/*输入: */
/* count, 待写入字节的长度 */
/* buff, 指向待写入数据的指针 */
/* */
/*输出: */
/* N/A */
/********************************************************************************************************/
void Write_FIFO(unsig

ned char count,unsigned char *buff)
{
unsigned char i;
for(i=0;iSPI_MasterWriteData(FIFO_Reg,*(buff+i));
}

/********************************************************************************************************/
/*名称: Read_FIFO */
/*功能: 该函数实现从RC531的FIFO中 read出x bytes数据 */
/* */
/*输入: */
/* buff, 指向 read出数据的指针 */
/* */
/*输出: */
/* N/A */
/********************************************************************************************************/
void Read_FIFO(unsigned char *buff)
{
unsigned char temp;
unsigned char i;
temp=SPI_MasterReadData(FIFOLength_Reg);
for(i=0;i*(buff+i)=SPI_MasterReadData(FIFO_Reg);
}


/********************************************************************************************************/
/*名称: SetTime_delay */
/*功能: 设置FM17XX定时值 */
/* */
/*输入: delaytime(ms) */
/* */
/* */
/*输出: */
/* N/A */
/********************************************************************************************************/
void SetTime_delay(unsigned long delaytime)
{
unsigned long temp,TimeLoad;
unsigned char Prescalar;
temp=1;
Prescalar=0;
TimeLoad=0;
while(1)
{
temp=temp*2;
TimeLoad = (delaytime*13560)/temp ;
Prescalar++;
if( TimeLoad<256 )
break;
if(Prescalar>21)
break;

}
if(Prescalar<21)
{
SPI_MasterWriteData(TimerClock_Reg,Prescalar);
SPI_MasterWriteData(TimerReload_Reg,TimeLoad);
}
else
{
SPI_MasterWriteData(TimerClock_Reg,21); //默认值为最大延时时间
SPI_MasterWriteData(TimerReload_Reg,255); //默认

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

if(row==0x00 && col==0x00)
for(i=0;iUID[i]=FIFO_Buff[i];
else
{
temp=FIFO_Buff[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;
}
FIFO_Buff[0]=temp;
UID[row-1]=temp1 | temp;
for(i=1;i{
UID[row-1+i]=FIFO_Buff[i];
}
}
}


/********************************************************************************************************/
/*名称: Check_UID */
/*功能: 该函数实现对收到的卡片的序列号的判断 */
/* */
/*输入: */
/* N/A */
/* */
/*输出:

*/
/* TRUE: 序列号正确 */
/* FALSE: 序列号错误 */
/********************************************************************************************************/
unsigned char Check_UID(void)
{
unsigned char temp;
unsigned char i;

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


/********************************************************************************************************/
/*名称: Set_BitFraming */
/*功能: 该函数实现对收到的卡片的序列号的判断 */
/* */
/*输入: */
/* row: 产生冲突的行 */
/* col: 产生冲突的列 */
/* */
/*输出: */
/* N/A */
/********************************************************************************************************/
void Set_BitFraming(unsigned char row,unsigned char col)
{
switch(row)
{
case 0:
FIFO_Buff[1]=0x20;
break;
case 1:
FIFO_Buff[1]=0x30;
break;
case 2:
FIFO_Buff[1]=0x40;
break;
case 3:
FIFO_Buff[1]=0x50;
break;
case 4:
FIFO_Buff[1]=0x60;
break;
default:
break;
}

switch(col)
{
case 0:
SPI_MasterWriteData(BitFraming_Reg,0x00);
break;
case 1:
SPI_MasterWriteData(BitFraming_Reg,0x11);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x01);
break;
case 2:
SPI_MasterWriteData(BitFraming_Reg,0x22);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x02);
break;
case 3:
SPI_MasterWriteData(BitFraming_Reg,0x33);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x03);
break;
case 4:
SPI_MasterWriteData(BitFraming_Reg,0x44);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x04);
break;
case 5:
SPI_MasterWriteData(BitFraming_Reg,0x55);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x05);
break;
case 6:
SPI_MasterWriteData(BitFraming_Reg,0x66);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x06);
break;
case 7:
SPI_MasterWriteData(BitFraming_Reg,0x77);
FIFO_Buff[1]=(FIFO_Buff[1] | 0x07);
break;
default:
break;
}
}


void Get_Card(void)
{
unsigned char tem;
unsigned char i;
tem = FM1702_Init();//初始化fm1702
if (!tem)
{
for(i=0;i<5;i++)
{
tem = Request(Req_Std);//监测

在FM1702操作范围之内处于HALT状态的卡片(寻卡)
if(!tem)
{
tem = AntiColl();//防冲突
if(!tem)
{
tem = Select_Card();//选卡
g_cGetCard = 1;
return;
}
}
}
}
}



unsigned char ChackCard(void)
{
unsigned char i,j=58;
Read_Flash((unsigned char*)0x1000);
if(((g_cUseData[0]==0)||(g_cUseData[0]==1))&&(g_cUseData[1]==0))
{//没有卡用户和开门码的时候任意卡可以比对通过,成功后的卡将被注册成管理员卡
g_cCardUseNumb = 0;
return (ERROR_SUCCESS);
}
else
{//有卡用户后比对卡
for(i=0;i<4;i++)
{
if(g_cUseData[j] != UID[i])
{
j=4;
Read_Flash((unsigned char*)0x1040);
for(i=0;i<4;i++)
{
if(g_cUseData[j] != UID[i])
{
j = (j/10)*10+14;
i = 0;
if(j>44)
{
j=4;
Read_Flash((unsigned char*)0x1080);
for(i=0;i<4;i++)
{
if(g_cUseData[j] != UID[i])
{
j = (j/10)*10+14;
i = 0;
if(j>54)
{
g_cCardUseNumb = 0;
return (ERROR_AUTH);
}
}
j++;
}
Read_Flash((unsigned char*)0x1000);
g_cCardUseNumb = j/10+7; //取c区当前用户编号8~12
if ((g_cUseData[1]>>(g_cCardUseNumb-7))&0x01)
return (ERROR_SUCCESS);
else
{
g_cCardUseNumb = 0;
return (ERROR_AUTH);
}
}
}
j++;
}
Read_Flash((unsigned char*)0x1000);
g_cCardUseNumb = j/10+2; //取b区当前用户编号2~7
if ((g_cUseData[0]>>(g_cCardUseNumb+1))&0x01)
return (ERROR_SUCCESS);
else

{
g_cCardUseNumb = 0;
return (ERROR_AUTH);
}
}
j++;
}
g_cCardUseNumb = 1;
return (ERROR_SUCCESS);
}
}

//添加卡操作
// 管理员卡不存在的时候注册管理员卡
//管理员卡存在的时候 刷已注册的卡=删除 刷未注册的卡=添加
void AddUserCard(void)
{
unsigned char i,j;
unsigned char UseData;

Read_Flash((unsigned char*)0x1000);
if((g_cUseData[0]<2)&&(g_cUseData[1] ==0))
{//管理卡不存在并且不存在开门码注册管理卡
j=58;
g_cUseData[0] |= 0x04;
g_cUseData[1] = 0x00;
g_cUseData[54]= 0x0F;
for(i=0;i<4;i++)
{
g_cUseData[j++] = UID[i];
}
g_cUseData[j]=0XF0;
Write_Flash((unsigned char*)0x1000);
}
else
{//存在管理卡
Get_Card();
if(g_cGetCard == 1)
{
g_c1SCount = 0;//清楚定时器从新开始5秒记录时
g_cGetCard =0;
if(ChackCard() == ERROR_SUCCESS)
{//卡已注册,若当前卡号为管理卡则全部删除恢复默认密码,否则删除相应卡。
if(g_cCardUseNumb == 1)
{//注册的时候刷管理卡删除所有用户,默认密码1234默认密码只有开门功能
Read_Flash((unsigned char*)0x1000);
g_cUseData[0] = 0x04;
g_cUseData[1] = 0x00;
g_cUseData[2] = 0xF0;
g_cUseData[3] = 0xF0;
g_cUseData[4] = 0xF0;
g_cUseData[5] = 0xF0;
g_cUseData[27] = 0x12;
g_cUseData[28] = 0x34;
for(i=0;i<4;i++)
{
g_cUseData[58+i]=UID[i];
}
g_cCardUseNumb = 0;
Write_Flash((unsigned char*)0x1000);
}
else if(g_cCardUseNumb < 7)
{
Read_Flash((unsigned char*)0x1000);
i = 0x01;
i = i<< (g_cCardUseNumb+1);
g_cUseData[0] &= (~i);
g_cCardUseNumb = 0;
Write_Flash((unsigned char*)0x1000);
}
else
{
Read_Flash((unsigned char*)0x1000);
i = 0x01;
i = i<< (g_cCardUseNumb-7);
g_cUseData[1] &= (~i);
g_cCardUseNumb = 0;
Write_Flash((unsigned char*)0x1000);
}
}
else
{
Read_Flash((unsigned char*)0x100

0);
if((g_cUseData[0] | 0x03) !=0xFF )
{//比对不通过,B区没有写满,新注册的用户写入B区
Read_Flash((unsigned char*)0x1000);
UseData = g_cUseData[0]>>3;
for(i=0;i<5;i++)
{//找出b区空位置
if(UseData & 0x01)
{
UseData = UseData>>1;

}
else
{
break;
}
}
g_cUseData[0] |= (0x01<<(i+3));
j = i*10;
Write_Flash((unsigned char*)0x1000);//改写用户数
Read_Flash((unsigned char*)0x1040); //改写用户信息
g_cUseData[j]=0XF0;
j += 4;
for(i=0;i<4;i++)
{
g_cUseData[j++] = UID[i];
}
g_cUseData[j]=0XF0;
Write_Flash((unsigned char*)0x1040);

}
else if((g_cUseData[1] | 0xC0) !=0xFF )
{
UseData = g_cUseData[1];
for(i=0;i<6;i++)
{//找出C区空位置
if(UseData & 0x01)
{
UseData = UseData>>1;

}
else
{
break;
}
}
g_cUseData[1] |= (0x01<j = i*10;
Write_Flash((unsigned char*)0x1000);//改写用户数
Read_Flash((unsigned char*)0x1080); //改写用户信息
g_cUseData[j]=0XF0;
j += 4;
for(i=0;i<4;i++)
{
g_cUseData[j++] = UID[i];
}
g_cUseData[j]=0XF0;
Write_Flash((unsigned char*)0x1080);
}
}
}
}
g_cGreenLEDFlash = 0;
}

相关主题
文本预览
相关文档 最新文档