#include
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define GetRegPage(addr) (0x80 | (addr>>3))
idata struct TranSciveBuffer{uchar MfCommand;
uchar MfLength;
uchar MfData[19];
};
void delay(uchar t)
{
uchar i,j;
for(i=0;i
for(j=0;j<110;j++);
}
void WriteRawIO(unsigned char Address,unsigned char value)
{
XBYTE[Address]=value;
}
unsigned char ReadRawIO(unsigned char Address)
{
return XBYTE[Address];
}
void WriteRC(unsigned char Address, unsigned char value)
{
WriteRawIO(0x00,GetRegPage(Address));
WriteRawIO(Address,value);
}
unsigned char ReadRC(unsigned char Address)
{
WriteRawIO(0x00,GetRegPage(Address));
return ReadRawIO(Address);
}
void ClearBitMask(uchar reg,uchar mask)
{
char tmp=0x0;
tmp = ReadRC(reg);
WriteRC(reg,tmp & ~mask);
}
void SetBitMask(uchar reg,uchar mask)
{
char tmp=0x0;
tmp=ReadRC(reg);
WriteRC(reg,tmp|mask);
}
void FlushFIFO(void)
{
SetBitMask(RegControl,0x01);
}
void PcdAntennaOff()
{
ClearBitMask(RegTxControl,0x03);
}
void PcdAntennaOn()
{
SetBitMask(RegTxControl,0x03);
}
void PcdSetTmo(unsigned char tmoLength)
{
switch(tmoLength)
{
case 1:
WriteRC(RegTimerClock,0x07);
WriteRC(RegTimerReload,0x6a);
break;
case 2:
WriteRC(RegTimerClock,0x07);
WriteRC(RegTimerReload,0xa0);
break;
case 3:
WriteRC(RegTimerClock,0x09);
WriteRC(RegTimerReload,0xa0);
break;
case 4:
WriteRC(RegTimerClock,0x09);
WriteRC(RegTimerReload,0xff);
break;
case 5:
WriteRC(RegTimerClock,0x0b);
WriteRC(RegTimerReload,0xff);
break;
case 6:
WriteRC(RegTimerClock,0x0d);
WriteRC(RegTimerReload,0xff);
break;
case 7:
WriteRC(RegTimerClock,0x0f);
WriteRC(RegTimerReload,0xff);
break;
default:
WriteRC(RegTimerClock,0x07);
WriteRC(RegTimerReload,tmoLength);
break;
}
}
char PcdComTransceive(struct TranSciveBuffer *pi)
{
bit recebyte=0;
char status;
uchar irqEn=0x00;
uchar waitFor=0x00;
uchar lastBits;
uchar n;
uint i;
FlushFIFO();
switch(pi->MfCommand)
{
case PCD_IDLE:
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2:
irqEn = 0x07;
waitFor = 0x04;
recebyte=1;
break;
case PCD_LOADCONFIG:
case PCD_LOADKEYE2:
case PCD_AUTHENT1:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2:
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE:
irqEn = 0x06;
waitFor = 0x04;
recebyte=1;
break;
case PCD_LOADKEY:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE:
irqEn = 0x3D;
waitFor = 0x04;
recebyte=1;
break;
default:
pi->MfCommand=MI_UNKNOWN_COMMAND;
break;
}
if(pi->MfCommand!=MI_UNKNOWN_COMMAND)
{
WriteRC(RegPage,0x00);
WriteRC(RegInterruptEn,0x7F);//使能所有的中断
WriteRC(RegInterruptRq,0x7F);//
WriteRC(RegCommand,PCD_IDLE);//闲置状态
SetBitMask(RegControl,0x01);//清除FIFO
WriteRC(RegInterruptEn,irqEn|0x80); //允许对应的专断
for(i=0;iMfLength;i++)
{
WriteRC(RegFIFOData,pi->MfData[i]);//写数据至FIFO
}
WriteRC(RegCommand,pi->MfCommand);//执行命令
i=0x2000;
do
{
n=ReadRC(RegInterruptRq);
i--;
}
while((i!=0)&&!(n&irqEn&0x20)&&!(n&waitFor));//等待数据发送完 n&waitFor表示命令自动结束
status=MI_COM_ERR;
if((i!=0)&&!(n&irqEn&0x20))//FIFO数据超限或i=0
{
if(!(ReadRC(RegErrorFlag)&0x17))//没出错
{
status=MI_OK;
if(recebyte)//表示有返回数据
{
n=ReadRC(RegFIFOLength);//读出返回的数据长度
lastBits=ReadRC(RegSecondaryStatus)&0x07;
if(lastBits)
{
pi->MfLength=(n-1)*8+lastBits;
}
else
{
pi->MfLength=n*8;
}
if(n==0)
{
n=1;
}
for(i=0;i
{
pi->MfData[i]=ReadRC(RegFIFOData);
}
}
}
}
else if(n&irqEn&0x20)//FIFO数据超限
{
status=MI_NOTAGERR;
}
else
{
status=MI_COM_ERR;
}
WriteRC(RegInterruptEn,0x7F);
delay(10);
WriteRC(RegInterruptRq,0x7F);
}
return status;
}
char PcdRequest(uchar req_code)
{
char status;
idata struct TranSciveBuffer MfComData;
struct TranSciveBuffer *pi;
pi=&MfComData;
PcdSetTmo(106);
PcdAntennaOn();
WriteRC(RegChannelRedundancy,0x03);
ClearBitMask(RegControl,0x08);//Crypto1on=0
WriteRC(RegBitFraming,0x07);
MfComData.MfCommand=PCD_TRANSCEIVE;
MfComData.MfLength=1;
MfComData.MfData[0]=req_code;
status=PcdComTransceive(pi);
if(!status)
{
if(MfComData.MfLength!=0x10)
{
status=MI_BITCOUNTERR;
}
}
return status;
}
uchar PiccCascAnticoll(uchar *snr) //这个指针变量没有用,但少了就会报错
{
uchar i;
uchar snr_check=0;
char status=MI_OK;
idata struct TranSciveBuffer MfComData;
struct TranSciveBuffer *pi;
pi=&MfComData;
PcdAntennaOn();
PcdSetTmo(106);//设置定时器
WriteRC(RegDecoderControl,0x28);//设置碰撞后接收的所有位都用0表示
ClearBitMask(RegControl,0x08);//Crypto1=0
WriteRC(RegChannelRedundancy,0x03);//使能奇校验
MfComData.MfCommand=PCD_TRANSCEIVE;//发送接收命令
MfComData.MfLength=2;//发送两个字节
MfComData.MfData[0]=PICC_ANTICOLL1;//PICC_ANTICOLL1=93H,PiCC反碰撞指令
MfComData.MfData[1]=0x20;//反碰撞还需要在发送一个20H,即想picc发送两个字节
status=PcdComTransceive(pi);//PcdComTransceive函数将Mfdate中的数据发送给Picc
if(!status)//表示执行命令没出错
{
for(i=0;i<4;i++)//执行命令后返回的前4个字节
{
snr_check^=MfComData.MfData[i];//接收到的前四个字节按位异或存入snr_check中
}
if(snr_check!=MfComData.MfData[i])//判断所接收序列号是否正确
{
status=MI_SERNRERR;//接收到的5个字节出错
}
else
{
for(i=0;i<5;i++)
{
*(snr+i)=MfComData.MfData[i];
}
}
}
ClearBitMask(RegDecoderControl,0x20);
return status;
}
char PcdSelect(uchar *snr,uchar *sar)
{
uchar i;
char status;
uchar snr_check=0;
idata struct TranSciveBuffer{uchar MfCommand;
uchar MfLength;
uchar MfData[7];
}MfComData;
struct TranSciveBuffer *pi;
pi=&MfComData;
PcdSetTmo(106);
WriteRC(RegChannelRedundancy,0x0F);
ClearBitMask(RegControl,0x08);
MfComData.MfCommand=PCD_TRANSCEIVE;
MfComData.MfLength=7;
MfComData.MfData[0]=PICC_ANTICOLL1;
MfComData.MfData[1]=0x70;
for(i=0;i<4;i++)
{
snr_check^=*(snr+i);
MfComData.MfData[i+2]=*(snr+i);
}
MfComData.MfData[6]=snr_check;//select要传7个字节
status=PcdComTransceive(pi);
if(status==MI_OK)
{ if(MfComData.MfLength!=0x8)
{
status = MI_BITCOUNTERR;
}
*sar=MfComData.MfData[0];
}
return status;
}
void init()
{
delay(500);
RC500CS=1;//这个位定义在rc500文件里
RC500RST=1;
delay(100);
RC500RST=0;
TMOD=0x20;//串口通讯的设置,采用9600波特率
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0x52;
PCON&=0x7f;
TI=0;
delay(10);//这个延时很重要,否则会写不进数据到RC500
}
void main()
{
uchar i,a[5],b[5],status,*snr,c;//传递数组的首地址可以,传递指针必须初始化,且每个指针都要知道指向的地址,所以传递数组比较好
snr=&c;
init();
PcdRequest(PICC_REQALL);
PiccCascAnticoll(a);
for(i=0;i<5;i++)
{
b[i]=a[i];
SBUF=b[i];
while(!TI);
TI=0;
}
status=PcdSelect(b,snr);
SBUF=status;
while(!TI);
TI=0;
SBUF=*snr;
while(!TI);
TI=0;
while(1);
}