?? rf.c
字號:
#include <pic.h>
__CONFIG(HS&PROTECT&PWRTEN&BOREN&WDTEN);
//pic16f73//單片機端口定義
#define cs RC0
#define so RC1
#define sck RC2
#define si RC3
#define msi TRISC3
#define data1 RC4
#define data0 RC5
#define hold RC6
#define cardin RC7
#define led RA2
#define rst1702 RA3
#define nop() asm("nop")
#define clrwdt() asm("clrwdt")
#define testbit(myvar,bit) ((myvar)&(1<<(bit)))
#define clrbit(myvar,bit) ((myvar)&=~(1<<(bit)))
#define setbit(myvar,bit) ((myvar)|=(1<<(bit)))
//;==============================================
//;FM1702SL控制寄存器定義
//;==============================================
#define Page_Reg 0x00
#define Command_Reg 0x01
#define FIFO_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
//;==============================================
//;FM1702SL發送命令代碼
//;==============================================
#define WriteEE 0x01
#define LoadKeyE2 0x0B
#define Transmit 0x1A
#define Transceive 0x1E
#define Authent1 0x0C
#define Authent2 0x14
////////////////////////////////////////////////////////////
bit rf_over;
char ack,retc,m,buff[48],Card_UID[5];
char mm[6]={0xff,0xff,0xff,0xff,0xff,0xff};
////===============================================
//以下為FM1702讀寫的子程序
//===============================================
char SPIRead(char SpiAddress,char *ramadr,char width);
char SPIWrite(char SpiAddress,char *ramadr,char width);
char SPI_Init();
char FM1702SL_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 *ramadr,char n);
///+++++++++++++++++card++++++++++++++++++++++++///
void wiegend(char *ramadr,char n);
void inisub();
void rddel();
void delay50us();
void delay1ms(char k);
main()
{di();
inisub();//初始化端口
while(1)
{clrwdt();
delay1ms(40);
rst1702=0;
delay1ms(20);
retc=SPI_Init();
if(retc) goto cardsub_end1;//錯誤
retc=FM1702SL_Init();
if(retc) goto cardsub_end1;
retc=Request();
if(retc)
{rf_over=0;
led=1;
cardin=1;
goto cardsub_end1;}
if(rf_over) 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;
di();
// 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=Read_Block(0x5);
// retc=Read_Block(0x6);
//for(m=0;m<16;m++)
// buff[m]=m+1; //
retc=Write_Block(buff,0x4);
if(retc){goto cardsub_end1;}
//
//for(m=0;m<16;m++)
// buff[m]=0;
//retc=Read_Block(0x4);
rf_over=1;
led=0;
cardin=0;
m=0;
ack=1;
while(hold)
{ rddel();
m++;
if(m>250)
{ ack=0;
break;}
}
if(ack)
wiegend(buff,16);
cardsub_end1:
rst1702=1;
}
}
////////////////////延時////////////////////
void rddel()
{ nop();
nop();
nop();
nop();
nop();
}
void delay1ms(char k) //延時kMs
{char i,j;
for (i=k;i>0;i--)
for(j=76;j>0;j--) rddel();
}
void delay50us()
{char i,j;
for (i=3;i>0;i--)
rddel();
}
////////////////初始化//////////////////////////////////
void inisub()
{//ADCON0=0x0;
ADCON1=0x7;
TRISA=0;
PORTA=0xc;
TRISC=0x48;
PORTC=0xff;
OPTION=0x2;
}
//維庚讀寫//////////////////////
void wiegend(char *ramadr,char n)
{char i,j;
CLRWDT();
for(j=0;j<n;j++)
for(i=8;i>0;i--)
{if(testbit(ramadr[j],i-1))
{data1=0;
delay50us();delay50us();
data1=1;// delay50us();
rddel();
rddel();
}
else
{data0=0;
delay50us();delay50us();
data0=1;
rddel();// delay50us();
rddel();
}
}
}
////////////////SPI讀//////////////////////////////////////
char SPIRead(char SpiAddress,char *ramadr,char width)
{ char i,j,adrtemp;
adrtemp=SpiAddress;
if((adrtemp&0xc0)==0)
{adrtemp=((adrtemp<<1)|0x80);
cs=0;
for(i=0;i<8;i++)
{if((adrtemp<<i)&0x80)so=1;
else so=0;
sck=1;nop();nop();nop();nop();
sck=0;
// adrtemp=adrtemp<<1;
}
for(j=0;j<width;j++)
{if(j!=width-1) adrtemp=(SpiAddress|0x40)<<1;
else adrtemp=0;
ramadr[j]=0;
for(i=0;i<8;i++)
{if((adrtemp<<i)&0x80)so=1;
else so=0;
sck=1;
ramadr[j]=ramadr[j]<<1;
if(si)ramadr[j]+=0x1;
sck=0;
// adrtemp=adrtemp<<1;
}
}
cs=1;
return(0);
}
else return(1);
}
//=======================================================
//SPI寫入程序
//入口:
//SpiAddress: 要寫到FM1702SL內的寄存器地址[0x01~0x3f]
//*ramadr 要寫入的數據在Ram中的首地址
//width: 要寫入的字節數
//出口: 0:成功,1:失敗
//作者: 張
//====================================================
char SPIWrite(char SpiAddress,char *ramadr,char width)
{char i,j,adrtemp;
adrtemp=SpiAddress;
if((adrtemp&0xc0)==0)
{adrtemp=((adrtemp<<1)&0x7e);
cs=0;
for(i=0;i<8;i++)
{if((adrtemp<<i)&0x80)so=1;
else so=0;
sck=1;nop();nop();nop();
sck=0;
// adrtemp=adrtemp<<1;
}
for(j=0;j<width;j++)
{adrtemp= ramadr[j];
for(i=0;i<8;i++)
{if((adrtemp<<i)&0x80)so=1;
else so=0;
sck=1; nop();nop();nop();
sck=0;
// adrtemp=adrtemp<<1;
}
}
cs=1;
return(0);
}
else return(1);
}
char SPI_Init()
{char acktemp,temp[1];
acktemp=SPIRead(Command_Reg,temp,1);
if(acktemp) return(1);
if(temp[0]) return(1);
else
{ temp[0]=0x80;
acktemp=SPIWrite(Page_Reg,temp,1);
if(acktemp) return(1);
acktemp=SPIRead(Command_Reg,temp,1);
if(acktemp) return(1);
if(temp[0]) return(1);
acktemp=SPIWrite(Page_Reg,temp,1);
if(acktemp) return(1);
return(0);
}
}
char FM1702SL_Init()
{char acktemp,temp[1];
temp[0]=0x7f;
acktemp=SPIWrite(InterruptEn_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x7f;
acktemp=SPIWrite(InterruptRq_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x5b;
acktemp=SPIWrite(TxControl_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x1;
acktemp=SPIWrite(RxControl2_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x7;
acktemp=SPIWrite(RxWait_Reg,temp,1);
if(acktemp) return(1);
// acktemp=SPIRead(RxWait_Reg,temp,1);
// if(acktemp) return(1);
return(0);
}
////使FM1702SL進入軟件powerdown模式
////;FM1702_Standby 發送FM1702_Standby信號
//char FM1702_Standby()
//{char acktemp,temp[1];
// acktemp=SPIRead(Control_Reg,temp,1);
// if(acktemp) return(1);
// temp[0]=0x20;
// acktemp=SPIWrite(Control_Reg,temp,1);
// if(acktemp) return(1);
// temp[0]=0x58;
// acktemp=SPIWrite(TxControl_Reg,temp,1);
// if(acktemp) return(1);
// return(0);
// }
////;使FM1702SL進入工作模式
////FM1702_Wakeup 發送FM1702_Wakeup信號
//char FM1702_Wakeup()
//{char acktemp,temp[1];
// acktemp=SPIRead(Control_Reg,temp,1);
// if(acktemp) return(1);
// temp[0]=0xdf;
// acktemp=SPIWrite(TxControl_Reg,temp,1);
// if(acktemp) return(1);
// acktemp=SPIRead(Control_Reg,temp,1);
// if(acktemp) return(1);
// if(temp[0]&0x20)return(1);
// temp[0]=0x5b;
// acktemp=SPIWrite(TxControl_Reg,temp,1);
// if(acktemp) return(1);
// return(0);
//
// }
char Request()
{char acktemp,temp[1];
temp[0]=0x7;
acktemp=SPIWrite(BitFraming_Reg,temp,1);
if(acktemp) return(1);
// temp[0]=0x7;
acktemp=SPIRead(Control_Reg,temp,1);
if(acktemp) return(1);
temp[0]&=0xf7;
acktemp=SPIWrite(Control_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x3;
acktemp=SPIWrite(ChannelRedundancy_Reg,temp,1);
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]!=0x2)|(buff[0]!=0x4)|(buff[1]!=0x0))
return(1);
return(0);
}
char Clear_FIFO()
{char acktemp,temp[1],i;
acktemp=SPIRead(Control_Reg,temp,1);
if(acktemp) return(1);
temp[0]|=0x1;
acktemp=SPIWrite(Control_Reg,temp,1);
if(acktemp) return(1);
for(i=0;i<5;i++)
{acktemp=SPIRead(FIFOLength_Reg,temp,1);
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);
// for(i=0;i<width;i++)
acktemp=SPIWrite(FIFO_Reg,ramadr,width);
if(acktemp) return(1);
return(0);
}
char Read_FIFO(char *ramadr)
{char acktemp,i;
acktemp=SPIRead(FIFOLength_Reg,ramadr,1);
if(acktemp) return(1);
if(ramadr[0]==0)return(1);
if(ramadr[0]>16)return(1);
i=ramadr[0];
acktemp=SPIRead(FIFO_Reg,&buff[0],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=Read_FIFO(temp);
// if(acktemp) return(1);
// buff[0]=0x12;buff[1]=0x34;buff[2]=0x56;
// acktemp=Write_FIFO(buff,3);
// if(acktemp) return(1);
// buff[0]=0;buff[1]=0;buff[2]=0;
// acktemp=Read_FIFO(temp);
// if(acktemp) return(1);
/////////////////////////////////////////////
acktemp=Write_FIFO(ramadr,width);
if(acktemp) return(1);
acktemp=SPIWrite(Command_Reg,&comm,1);
if(acktemp) return(1);
for(i=0;i<16;i++)
{
acktemp=SPIRead(Command_Reg,temp,1);
if(acktemp==0)
{if(temp[0]==0)return(0);}
}
return(1);
}
char Get_UID()
{char acktemp,temp[2],i;
temp[0]=0x3;
acktemp=SPIWrite(ChannelRedundancy_Reg,temp,1);
if(acktemp) return(1);
temp[0]=0x93;temp[1]=0x20;
acktemp=Command_Send(Transceive,temp,2);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(temp[0]!=0x5)return(1);
acktemp=0;
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]=0xf;
acktemp=SPIWrite(ChannelRedundancy_Reg,temp,1);
if(acktemp) return(1);
buff[0]=0x93;buff[1]=0x70;
for(i=0;i<5;i++)
buff[i+2]=Card_UID[i];
acktemp=Command_Send(Transceive,buff,7);
if(acktemp) return(1);
acktemp=Read_FIFO(temp);
if(temp[0]!=0x1)return(1);
if(buff[0]!=0x8)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]=0x0;
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]&0xf)|(~(temp[0]&0xf)<<4));
}
acktemp=Command_Send(WriteEE,buff,0x0e);
delay1ms(4);
acktemp=SPIRead(SecondaryStatus_Reg,temp,1);
if(acktemp) return(1);
if(temp[0]&0x40)
{temp[0]=0x0;
acktemp=SPIWrite(Command_Reg,temp,0x1);
if(acktemp) return(1);
return(0);}
temp[0]=0x0;
acktemp=SPIWrite(Command_Reg,temp,0x1);
return(1);
}
//加載密鑰
//入口:buff[0]密鑰密鑰地址
//buff[1]:0
char Load_Key_EE(char n)
{char acktemp,temp[2];
temp[0]=n;temp[1]=0x0;
acktemp=Command_Send(LoadKeyE2,temp,0x2);
if(acktemp) return(1);
acktemp=SPIRead(ErrorFlag_Reg,temp,1);
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=SPIWrite(ChannelRedundancy_Reg,temp,0x1);
if(acktemp) return(1);
temp[0]=0x61;
temp[1]=sq;
for(i=0;i<4;i++)
temp[2+i]=Card_UID[i];
acktemp=Command_Send(Authent1,temp,0x6);
if(acktemp) return(1);
acktemp=SPIRead(ErrorFlag_Reg,temp,1);
if(acktemp) return(1);
if(temp[0]&0xe)return(1);
acktemp=Command_Send(Authent2,temp,0);
if(acktemp) return(1);
acktemp=SPIRead(ErrorFlag_Reg,temp,1);
if(acktemp) return(1);
if(temp[0]&0xe)return(1);
acktemp=SPIRead(Control_Reg,temp,1);
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=SPIWrite(ChannelRedundancy_Reg,temp,0x1);
if(acktemp) return(1);
temp[0]=0x30;temp[1]=n;
acktemp=Command_Send(Transceive,temp,2);
if(acktemp) return(1);
acktemp=SPIRead(ErrorFlag_Reg,temp,1);
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 *ramadr,char n)
{char acktemp,temp[2];
temp[0]=0x7;
acktemp=SPIWrite(ChannelRedundancy_Reg,temp,0x1);
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 + -