📄 fm1702.c
字号:
#include "reg51.h"
#include "intrins.h"
#include "ABSACC.H"
sbit IRQ = P3^2;
sbit FM1702_RD = P3^7;
sbit FM1702_WR = P3^6;
sbit RSTPD = P1^2;
sbit SPEAKER = P2^3;
#define uchar unsigned char
//;==============================================
//;FM1702N控制寄存器定义
//;==============================================
#define Pge_Reg 0x00
#define Command_Reg 0x01
#define FIFOData_Reg 0x02
#define FIFOLength_Reg 0x04
#define SecondaryStatus_Reg 0x05
#define InterruptEn_Reg 0x06
#define InterruptRq_Reg 0x07
#define Control_Reg 0x09
#define ErrorFlag_Reg 0x0A
#define BitFraming_Reg 0x0F
#define TxControl_Reg 0x11
#define CwConductance_Reg 0x12
#define RxControl2_Reg 0x1E
#define ChannelRedundancy_Reg 0x22
#define RxWait_Reg 0x21
#define IRqPinConfig_Reg 0x2D
//;==============================================
//;FM1702N发送命令代码
//;==============================================
#define WriteEE 0x01
#define LoadKeyE2 0x0B
#define Transmit 0x1A
#define Transceive 0x1E
#define Authent1 0x0C
#define Authent2 0x14
#define StartUp 0x3F
#define Idle 0x00
#define Receive 0x16
#define ReadE2 0x03
#define LoadKey 0x19
#define LoadConfig 0x07
#define CalcCRC 0x12
////////////////////////////////////////////////////////////
char ack,retc,m,buff[48],Card_UID[5];
char mm[6]={0xff,0xff,0xff,0xff,0xff,0xff};
////===============================================
//以下为FM1702读写的子程序
//===============================================
char FM1702N_Init();
char Clear_FIFO();
char Write_FIFO(char *ramadr,char width);
char Read_FIFO(char *ramadr);
char Request();
char Command_Send(char comm,char *ramadr,char width);
char Get_UID();
char Select_Tag();
char Load_Key(char n,char *ramadr);
char Load_Key_EE(char n);
char Authentication(char n);
char rdbuff(char sq,char n);
char Read_Block(char n);
char Write_Block(char n);
/////////////////////////////////////////////////////////
void delay50us();
void delay1ms(char k);
main()
{
SPEAKER = 0;
while(1)
{
retc=FM1702N_Reset();
if(retc) goto cardsub_end1;
retc=FM1702N_Init();
if(retc) goto cardsub_end1;
retc=Request();
if(retc) goto cardsub_end1;
retc=Get_UID();
if(retc)
{
delay1ms(10);
retc=Get_UID();}
if(retc) goto cardsub_end1;
/* retc=Select_Tag();
if(retc)goto cardsub_end1;
// gettime();
//**********寻卡结束********************/
/* retc=Load_Key(0x80,mm);//加载购电区的密钥
if(retc)goto cardsub_end1;//待定
retc=Load_Key_EE(0x80);//加载购电区的密钥
if(retc)goto cardsub_end1;//待定
//***********开始卡操作******************Load_Key Load_Key_EE
/* retc=rdbuff(0x7,0x4);//读块0
//if(retc){beep=1;beep_bad=1;goto cardsub_end1;}
if(retc){goto cardsub_end1;}
retc=Write_Block(0x4);
if(retc){goto cardsub_end1;}
// wiegend(buff,16);*/
cardsub_end1: ;
// rst1702=1;
}
}
////////////////////延时////////////////////
void rddel()
{
_nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();
}
void delay1ms(char k) //延时kMs
{
char i,j;
for (i=k;i>0;i--)
for(j=100;j>0;j--) rddel();
}
void delay50us()
{
char i;
for (i=3;i>0;i--)
rddel();
}
char FM1702_Read(uchar Addr,char *ramadr)
{
if((Addr&0xc0)==0)
{
*ramadr=XBYTE[Addr];
return 0;
}
else return 1;
}
char FM1702_Write(char Addr,char *ramadr)
{
if((Addr&0xc0)==0)
{
XBYTE[Addr]=*ramadr;
return 0;
}
else return 1;
}
char FM1702N_Reset()
{
RSTPD=0;
delay1ms(25);
RSTPD=1;
delay1ms(3);
RSTPD=0;
delay1ms(2100);
while(Read(RegCommand)!=0x00);//判command是否为00h
Write(RegPage ,0x80);
if(Read(RegCommand)==0x00)
{
Write(RegPage,0x00);//线性模式
return 0;
}
else
return 1;
}
char FM1702N_Init()
{
char acktemp,temp[1];
temp[0]=0x7f;
acktemp=FM1702_Write(InterruptEn_Reg,temp);
if(acktemp) return(1);
temp[0]=0x7f;
acktemp=FM1702_Write(InterruptRq_Reg,temp);
if(acktemp) return(1);
temp[0]=0x5b;
acktemp=FM1702_Write(TxControl_Reg,temp);
if(acktemp) return(1);
temp[0]=0x01;
acktemp=FM1702_Write(RxControl2_Reg,temp);
if(acktemp) return(1);
temp[0]=0x03;
acktemp=FM1702_Write(IRqPinConfig_Reg,temp);
if(acktemp) return(1);
temp[0]=0x00;
acktemp=FM1702_Write(Pge_Reg,temp);
if(acktemp) return(1);
temp[0]=0x07;
acktemp=FM1702_Write(RxWait_Reg,temp);
if(acktemp) return(1);
return(0);
}
char Request()
{
char acktemp,temp[1];
temp[0]=0x07;
acktemp=FM1702_Write(BitFraming_Reg,temp);
if(acktemp) return(1);
acktemp=FM1702_Read(Control_Reg,temp);
if(acktemp) return(1);
temp[0]&=0xf7;
acktemp=FM1702_Write(Control_Reg,temp);
if(acktemp) return(1);
temp[0]=0x03;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
temp[0]=0x52;
acktemp=Command_Send(Transceive,temp,1);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(acktemp) return(1);
if((temp[0]!=0x02)|(buff[0]!=0x04)|(buff[1]!=0x00))
return(1);
return(0);
}
char Clear_FIFO()
{
char acktemp,temp[1],i;
acktemp=FM1702_Read(Control_Reg,temp);
if(acktemp) return(1);
temp[0]|=0x01;
acktemp=FM1702_Write(Control_Reg,temp);
if(acktemp) return(1);
for(i=0;i<5;i++)
{
acktemp=FM1702_Read(FIFOLength_Reg,temp);
if(acktemp==0)
{if(temp[0]==0)return(0);}
}
return(1);
}
///////////////////////////////////////////////////
char Write_FIFO(char *ramadr,char width)
{
char acktemp;
if(width==0)return(0);
while(width)
{
acktemp=FM1702_Write(FIFOData_Reg,ramadr++);
if(acktemp) return(1);
width--;
}
return(0);
}
char Read_FIFO(char *ramadr)
{
char acktemp,i,j=0;
acktemp=FM1702_Read(FIFOLength_Reg,ramadr);
if(acktemp) return(1);
if(ramadr[0]==0)return(1);
if(ramadr[0]>16)return(1);
i=ramadr[0];
while(i)
{
acktemp=FM1702_Read(FIFOLength_Reg,&buff[j++]);
if(acktemp) return(1);
i--;
}
return(0);
}
char Command_Send(char comm,char *ramadr,char width)
{
char acktemp,temp[1],i;
acktemp=Clear_FIFO();
if(acktemp) return(1);
acktemp=Write_FIFO(ramadr,width);
if(acktemp) return(1);
acktemp=FM1702_Write(Command_Reg,&comm);
if(acktemp) return(1);
for(i=0;i<16;i++)
{
acktemp=FM1702_Read(Command_Reg,temp);
if(acktemp==0)
{if(temp[0]==0)return(0);}
}
return(1);
}
char Get_UID()
{
char acktemp,temp[2],i;
temp[0]=0x03;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
temp[0]=0x93;
acktemp=Command_Send(Transceive,temp,1);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(acktemp) return(1);
if(temp[0]!=0x05)return(1);
for(i=0;i<5;i++)
acktemp^=buff[i];
if(acktemp) return(1);
for(i=0;i<5;i++)
Card_UID[i]=buff[i];
return(0);
}
char Select_Tag()
{
char acktemp,temp[1],i;
temp[0]=0x0f;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
buff[0]=0x93;buff[1]=0x70;
for(i=0;i<5;i++)
buff[i+2]=Card_UID;
acktemp=Command_Send(Transceive,buff,7);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(temp[0]!=0x1)return(1);
if(buff[0]!=0x88)return(1);
return(0);
}
//存储密钥
//*ramadr:密钥
//buff[0]密钥密钥地址
//buff[1]:0
//buff[2]~buff[9]不能放密码//////////////
char Load_Key(char n,char *ramadr)
{
char acktemp,temp[1],i;
buff[0]=n;buff[1]=0x00;
for(i=0;i<6;i++)
{
temp[0]=ramadr[i];
buff[2+i+i]=(((ramadr[i]&0xf0)>>4)|((~ramadr[i])&0xf0));
buff[3+i+i]=((temp[0]&0x0f)|(~(temp[0]&0x0f)<<4));
}
acktemp=Command_Send(WriteEE,buff,0x0e);
delay1ms(4);
acktemp=FM1702_Read(SecondaryStatus_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0x40)
{
temp[0]=0x00;
acktemp=FM1702_Write(Command_Reg,temp);
if(acktemp) return(1);
return(0);
}
temp[0]=0x00;
acktemp=FM1702_Write(Command_Reg,temp);
return(1);
}
//加载密钥
//入口:buff[0]密钥密钥地址
//buff[1]:0
char Load_Key_EE(char n)
{
char acktemp,temp[2];
temp[0]=n;temp[1]=0x00;
acktemp=Command_Send(LoadKeyE2,temp,0x02);
if(acktemp) return(1);
acktemp=FM1702_Read(ErrorFlag_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0x40)return(1);
return(0);
}
//读卡:
//sq,扇区,n:读N块
char rdbuff(char sq,char n)
{
char acktemp;
acktemp=Authentication(sq);
if(acktemp) return(1);
acktemp=Read_Block(n);
if(acktemp) return(1);
return(0);
}
//三重认证
//N认证的块:
//temp[0]:0x60为A密钥,0x61为B密钥
char Authentication(char sq)
{
char acktemp,temp[6],i;
temp[0]=0xf;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
temp[0]=0x61;
temp[1]=sq;
for(i=0;i<4;i++)
temp[2+i]=Card_UID;
acktemp=Command_Send(Authent1,temp,0x6);
if(acktemp) return(1);
acktemp=FM1702_Read(ErrorFlag_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0xe)return(1);
acktemp=Command_Send(Authent2,temp,0);
if(acktemp) return(1);
acktemp=FM1702_Read(ErrorFlag_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0xe)return(1);
acktemp=FM1702_Read(Control_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0x8)return(0);
return(1);
}
char Read_Block(char n)
{
char acktemp,temp[2];
temp[0]=0xf;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
temp[0]=0x30;temp[1]=n;
acktemp=Command_Send(Transceive,temp,2);
if(acktemp) return(1);
acktemp=FM1702_Read(ErrorFlag_Reg,temp);
if(acktemp) return(1);
if(temp[0]&0xe)return(1);
acktemp=Read_FIFO(temp);
if(acktemp) return(1);
if(temp[0]!=16)return(1);
return(0);
}
char Write_Block(char n)
{
char acktemp,temp[2];
temp[0]=0x7;
acktemp=FM1702_Write(ChannelRedundancy_Reg,temp);
if(acktemp) return(1);
temp[0]=0xa0;temp[1]=n;
acktemp=Command_Send(Transceive,temp,2);
if(acktemp) return(1);
temp[1]= buff[0];
acktemp=Read_FIFO(temp);
if(acktemp) return(1);
if(temp[0]!=1)return(1);
if(buff[0]!=0xa)return(1);
buff[0]=temp[1];
acktemp=Command_Send(Transceive,buff,0x10);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(acktemp) return(1);
if(temp[0]!=1)return(1);
if(buff[0]!=0xa)return(1);
buff[0]=temp[1];
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -