射频 rc500代码完全注释

更新时间:2024-01-09 22:20:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

#define M500_GLOBALS //PICC=卡?PCD=阅读器 //以下位要包含的头文件

#include /*字符串函数及存储器函数头文件*/ #include /*标准I/O头文件*/

#include /*存储器绝对地址访问定义?与指令MOVX相关*/ #include /*内部函数定义?与循环指令?例如RR)?位判断指令?例如JB),以及空操作指令?NOP)等相关*/

#include \内部寄存器定义头文件*/ #include \内部寄存器错误标志头文件*/ #include \内部寄存器定义头文件*/

#include \用户自定义相关变量和数据结构头文件*/

#define GetRegPage(addr)(0x80|(addr>>3)) /*将addr右移3位再与80h取或*/

#definenocard0 / *能量场中没有卡*/ #definemifare11 /*场中有mifare1卡*/

#definemifarepro2 /*场中有mifarepro卡*/ #definemifarelight3 /*场中有mifarelight卡*/ #defineunknowncard4 /*场中有未知卡*/ #defineNO_TIMER21 /*?*/ #defineucharunsignedchar

bdataucharAA; //A,可位寻址单字节数据类型 sbithigh_bit=AA^7; //ACC.7 sbitlow_bit=AA^0; //ACC.0 //ucharsebuf;//RECBUF,SENBUF ucharidatadisp_buf[4]; void del_8us() {

Uchar i;

for(i=0;i<1;i++) {;} }

voiddel_50us()//延时子程序 {

Uchar i;

for(i=0;i<6;i++) {;} }

voiddel_50ms() {

Uchar i,j;

for(i=0;i<255;i++) for(j=0;j<255;j++)

{;} }

voidsend(ucharsebuf)//发送子程序 {

57.uchari; 58.AA=sebuf; 59.CLK=0; 60.CS=0;

61.del_50us();

62.for(i=0;i<8;i++) 63.{

64.del_8us(); 65.DIO=high_bit; 66.CLK=1;

67.del_8us();

68.AA=AA<<1;//循环移位 69.CLK=0; 70.}

71.DIO=0; 72.}

void reset_light()//复位子程序 {

KEY=1; DIO=1;

del_8us(); send(0xa4); CS=1;

del_8us(); }

void reset_7289() {

reset_light();//上电初检 send(0xbf);

CS=1;//测试所有的led灯 del_50ms();

reset_light();//恢复熄灭状态 }

void display() {

Uchar i;

for(i=0;i<4;i++)

{send(0xa1);CS=1;del_8us();//逻辑左移指令 send(0xc8);

send((disp_buf[i]>>4)&0x0f);CS=1;del_8us();

send(0xa1);CS=1;del_8us();//逻辑左移指令 send(0xc8);

send(disp_buf[i]&0x0f);CS=1;del_8us(); } }

///////////////////////////////////////////////////////////////////////

/*往一个寄存器写一个数据*/

///////////////////////////////////////////////////////////////////////

Void WriteRawIO(unsignedcharAddress,unsignedcharvalue) {

XBYTE[Address]=value;/*调用XBYTE函数?*/ }

///////////////////////////////////////////////////////////////////////

/*从一个寄存器读出一个数据*/

///////////////////////////////////////////////////////////////////////

Unsigned char ReadRawIO(unsigned char Address) {

returnXBYTE[Address];/*调用XBYTE函数*/ }

///////////////////////////////////////////////////////////////////////

/*用页选方式访问寄存器?写入?*/

///////////////////////////////////////////////////////////////////////

void WriteIO(unsigned char Address,unsigned char value) {

WriteRawIO(0x00,GetRegPage(Address));/*调用writerawio()函数?页选?80h-87h?*/

WriteRawIO(Address,value);/*调用writerawio()函数?选择一个寄存器?0-7h?*/ }

///////////////////////////////////////////////////////////////////////

/*用页选方式访问寄存器?读出?*/

///////////////////////////////////////////////////////////////////////

Unsigned char ReadIO(unsigned char Address) {

WriteRawIO(0x00,GetRegPage(Address));/*调用writerawio()函数?页选*/ returnReadRawIO(Address);/*调用readrawio()函数*/

}

///////////////////////////////////////////////////////////////////////

/*设置定时时间*/

///////////////////////////////////////////////////////////////////////

void M500PcdSetTmo(unsigned char tmoLength) {

switch(tmoLength) {case1:

WriteIO(RegTimerClock,0x07);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,0x6a);/*调用WRITEIO()函数,从单片机写计时器的初始值(6AH)*/ break; case2:

WriteIO(RegTimerClock,0x07);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,0xa0);/*调用WRITEIO()函数,从单片机写计时器的初始值(A0H)*/ break; case3:

WriteIO(RegTimerClock,0x09);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/512--2^9*/

WriteIO(RegTimerReload,0xa0);/*调用WRITEIO()函数,从单片机写计时器的初始值(A0H)*/ break; case4:

WriteIO(RegTimerClock,0x09);/*调用WRITEIO()函数,从单片机写计时器得分频比

(09H)=13.56MHZ/512--2^9*/

WriteIO(RegTimerReload,0xff);/*调用WRITEIO()函数,从单片机写计时器的初始值(FF)*/ break; case5:

WriteIO(RegTimerClock,0x0b);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,0xff);/*调用WRITEIO()函数,从单片机写计时器的初始值(FFH)*/ break;

case6:

WriteIO(RegTimerClock,0x0d);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,0xff);/*调用WRITEIO()函数,从单片机写计时器的初始值(FFH)*/ break; case7:

WriteIO(RegTimerClock,0x0f);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,0xff);/*调用WRITEIO()函数,从单片机写计时器的初始值(FFH)*/ break;

default:/*其它情况*/

WriteIO(RegTimerClock,0x07);/*调用WRITEIO()函数,从单片机写计时器得分频比

(07H)=13.56MHZ/128--2^7*/

WriteIO(RegTimerReload,tmoLength);/*调用WRITEIO()函数,从单片机写计时器的初始值(TMOLENTH)*/ break; } }

///////////////////////////////////////////////////////////////////////

//Request Command define dinISO14443(Mifare) /*命令判别程序*/

///////////////////////////////////////////////////////////////////////

Char M500PcdCmd(unsigned char cmd, volatileunsignedchardata*rcv, MfCmdInfoidata*info) {

Char idatastatus=MI_OK;

Char idatatmpStatus;/*中间状态寄存器*/

Unsigned char idatalastBits;/*中间状态寄存器*/ unsigned int idatatimecnt=0; unsigned char idatairqEn=0x00; unsigned char idatawaitFor=0x00; unsigned char idatatimerCtl=0x00;

WriteIO(RegInterruptEn,0x7F);/*?06H?SETEN,0,TIMER,TX,RX,IDLE,HI,LO=0111,1111:禁中断使 能*/

WriteIO(RegInterruptRq,0x7F);/*(07H)SETIRQ,0,TIMER,TX,RX,IDLE,HI,LO=

0111,1111:禁中断请 求*/

WriteIO(RegCommand,PCD_IDLE);/*(01H)命令代号均写入此处相当于单片机的指令寄存器PC:进入待命 态*/

FlushFIFO();/*清缓冲区标志?这样FIFO区就可供单片机或RC500状态机使用*/

MpIsrInfo=info;/*?*/

MpIsrOut=rcv;/*接收数据缓冲区*/

info->irqSource=0x00;/*->:存储结构或联合单元?右结合?*/ switch(cmd)

{/*根据输入的命令分支*/

casePCD_IDLE:/*是IDLE命令?00H?*/ irqEn=0x00; waitFor=0x00; break;

casePCD_WRITEE2:/*是写EEROM命令?01H?*/ irqEn=0x11; waitFor=0x10; break;

casePCD_READE2:/*是读EEROM命令?03H?*/ irqEn=0x07; .waitFor=0x04; break;

case CD_LOADCONFIG:/*是载入配置命令?07H?*/

case PCD_LOADKEYE2:/*是从EEROM载入密钥命令?0BH?*/ case CD_AUTHENT1:/*是执行认证1命令?0CH?*/ irqEn=0x05; waitFor=0x04; break;

casePCD_CALCCRC:/*是激活CRC命令?12H?*/ irqEn=0x11; waitFor=0x10; break;

casePCD_AUTHENT2:/*是执行认证2命令?14H?*/ irqEn=0x04; waitFor=0x04; break;

casePCD_RECEIVE:/*是激活接收器命令?16H?*/

info->nBitsReceived=-(ReadIO(RegBitFraming)>>4); irqEn=0x06; waitFor=0x04; break;

Case PCD_LOADKEY:/*是从FIFO中载入密钥命令?19H?*/

irqEn=0x05; waitFor=0x04; break;

casePCD_TRANSMIT:/*是将FIFO数据发送到卡片命令?1AH?*/ irqEn=0x05; waitFor=0x04; break;

case PCD_TRANSCEIVE:/*是先发送然后立即接收命令?1EH?*/ info->nBitsReceived=-(ReadIO(RegBitFraming)>>4); irqEn=0x3D; waitFor=0x04; break; default:

status=MI_UNKNOWN_COMMAND; /*是未知命令*/ }

if(status==MI_OK) /*命令是否被正确执行*/ { /*是的*/

irqEn|=0x20;/*开启定时器*/ waitFor|=0x20;

timecnt=1000;/*?*/

WriteIO(RegInterruptEn,irqEn|0x80);/*开相应的中断使能*/ WriteIO(RegCommand,cmd);/*写入相应的入口命令*/

while(!(MpIsrInfo->irqSource&waitFor||!(timecnt--)));/*错误发生情况1?*/

WriteIO(RegInterruptEn,0x7F);/*定时器计完?禁中断系统*/ WriteIO(RegInterruptRq,0x7F);

SetBitMask(RegControl,0x04);/*这一位设置作用是立即结束中断计时*/ WriteIO(RegCommand,PCD_IDLE);/*进入IDLE态*/

if(!(MpIsrInfo->irqSource&waitFor))/*错误发生情况2*/ {

status=MI_ACCESSTIMEOUT;/*在规定的时间内没有完成任务*/ }

else/*错误发生情况3*/ {

status=MpIsrInfo->status; }

if(status==MI_OK)/*命令执行成功*/ {

if(tmpStatus=(ReadIO(RegErrorFlag)&0x17))/*取出错误状态寄存器内容*/ {

if(tmpStatus&0x01)/*取出比特碰撞位?是否为1?1?有碰撞?*/ {

info->collPos=ReadIO(RegCollPos);/*得到碰撞的具体位置*/ status=MI_COLLERR;/*有碰撞*/

} else {

info->collPos=0;/*无碰撞*/ if(tmpStatus&0x02) {

status=MI_PARITYERR;/*1?奇偶校验错*/ } }

if(tmpStatus&0x04)/*取出帧检测位?是否为1?1?帧头错SOF?*/ {

status=MI_FRAMINGERR;/*1?帧头错SOF*/ }

if(tmpStatus&0x10)/*取出FIFO状态位?是否为1*/ {

FlushFIFO();/*清缓冲区*/

status=MI_OVFLERR;/*1?FIFO满*/ }

if(tmpStatus&0x08)/*取出crc校验位?是否为1*/ {

status=MI_CRCERR;/*1?CRC校验错*/ }

if(status==MI_OK)

status=MI_NY_IMPLEMENTED;//该命令不存在 }

if(cmd==PCD_TRANSCEIVE)/*如果是发接指令1*/ {

lastBits=ReadIO(RegSecondaryStatus)&0x07;/*取出最后三位*/ if(lastBits)/*最后三位为1-7?不全有效*/

info->nBitsReceived+=(info->nBytesReceived-1)*8+lastBits; else/*最后三位为0?全有效*/

info->nBitsReceived+=info->nBytesReceived*8; } } else {

info->collPos=0x00;/*无碰撞*/ } }

MpIsrInfo=0; MpIsrOut=0; return status; }

////////////////////////////////////////////////////////////////////

///

//置RC500寄存器bit

///////////////////////////////////////////////////////////////////////

charSetBitMask(unsignedcharreg,unsignedcharmask) {/*相应的寄存器?REG)?相应的屏蔽位?MASK?*/ Char idatatmp=0x00; tmp=ReadIO(reg);

WriteIO(reg,tmp|mask);/*写入*/ return0x00; }

///////////////////////////////////////////////////////////////////////

//清RC500寄存器bit

///////////////////////////////////////////////////////////////////////

char ClearBitMask(unsignedcharreg,unsignedcharmask) {/*相应的寄存器?REG)?相应的屏蔽位?MASK?*/ charidatatmp=0x00; tmp=ReadIO(reg);

WriteIO(reg,tmp&~mask);/*写入*/ Return 0x00; }

///////////////////////////////////////////////////////////////////////

/*清缓冲区标志?这样RC500的FIFO取就可供单片机或RC500状态机使用*/ ///////////////////////////////////////////////////////////////////////

voidFlushFIFO(void) {

SetBitMask(RegControl,0x01);/*控制寄存器地址?09H------置1?FIFOFLUSH=1)*/ }

///////////////////////////////////////////////////////////////////////

//ValueformatoperationsforMifareStandardcardICs

/*改变MIFARE1卡内部EEROM的内容?单调增加?单调减少?数据检验操作?*/

///////////////////////////////////////////////////////////////////////

charM500PiccValue(unsignedchardd_mode, unsignedcharaddr, unsignedchar*value,

unsignedchartrans_addr)

{/*VALUE:连续写入的四字节指针?TRANS_ADDR:指向的改变后的数据要存入的地址*/

Char status=MI_OK;/*SATUS:置初值*/

/*DD_MODE:三种命令模式?ADDR:指向的要改变数据单元的地址*/ M500PcdSetTmo(1);/*初始化计时器--方式1*/ ResetInfo(MInfo);/*Minfo=INFO*/

SerBuffer[0]=dd_mode;/*93h,95h,97h三种命令模式*/

SerBuffer[1]=addr;/*ADDR:指向的要改变数据单元的地址*/ MInfo.nBytesToSend=2;/*要发送的字节数*/ status=M500PcdCmd(PCD_TRANSCEIVE, SerBuffer, &MInfo);

/*执行先送后接指令后返回STATUS*/

if(status!=MI_NOTAGERR)/*MI_NOTAGERR=没有卡在此场里*/ {/*有卡在此场里*/

if(MInfo.nBitsReceived!=4)/*收到的数据不是4比特*/ {

status=MI_BITCOUNTERR;/*置收到错误的比特数目标志位*/ }

else/*收到的数据是4比特*/ {

SerBuffer[0]&=0x0f;/*取出低四位*/ switch(SerBuffer[0]) {

case0x00:

status=MI_NOTAUTHERR;/*0000=置收到错误的比特数目标志位*/ break;

case0x0a:/*1010=置命令正确执行位*/ status=MI_OK; break;

case0x01:/*0001=置数据结构错误位*/ status=MI_VALERR; break; default:

status=MI_CODEERR;/*收到NACK,发送的数据出错?CRC,PARITY?*/ break; } } }

if(status==MI_OK)

{/*TRANSCEIVE命令执行成功*/

M500PcdSetTmo(3);/*初始化计时器--方式3*/ ResetInfo(MInfo);/*Minfo=INFO*/

memcpy(SerBuffer,value,4);/*将缓冲区里放入要改变的数据*/

MInfo.nBytesToSend=4;/*要发送的字节数4*/

status=M500PcdCmd(PCD_TRANSCEIVE,/*执行先送后接指令后返回STATUS*/ SerBuffer, &MInfo);

if(status==MI_OK)/*上条TRANSCEIVE命令执行成功*/ {

if(MInfo.nBitsReceived!=4)/*收到的数据不是4比特*/ {

status=MI_BITCOUNTERR;/*MI_NOTAGERR=没有卡在此场里*/ }

else/*收到的数据是4比特*/ {

SerBuffer[0]&=0x0f;/*取出低四位*/ switch(SerBuffer[0]) {

case0x00:/*0000=置收到错误的比特数目标志位*/ status=MI_NOTAUTHERR; break;

case0x01:/*0001=置数据结构错误位*/ status=MI_VALERR; break;

default:/*收到NACK,发送的数据出错?CRC,PARITY?*/ 435.status=MI_CODEERR; 436.break; 437.} 438.} 439.}

440.else/*上条TRANSCEIVE命令执行不成功*/ 441.{

442.if(status==MI_NOTAGERR)/*MI_NOTAGERR=没有卡在此场里*/ 443.status=MI_OK;/*恢复初始值*/ 444.} 445.}

446.if(status==MI_OK)/**/ 447.{

448.ResetInfo(MInfo);/*Minfo=INFO*/

449.SerBuffer[0]=PICC_TRANSFER;/*这才是真正的改变卡内存的指令?下载?*/

450.SerBuffer[1]=trans_addr; 451.MInfo.nBytesToSend=2;

452.status=M500PcdCmd(PCD_TRANSCEIVE,/*执行传送指令?下载到卡的EEROM*/

453.SerBuffer,

454.&MInfo);/*TRANSCEIVE指令的出口参数?一部分状态信息*/

455.if(status!=MI_NOTAGERR) 456.{/*有卡在此场里*/

457.if(MInfo.nBitsReceived!=4) 458.{

459.status=MI_BITCOUNTERR;/*收到的数据不是4比特*/ 460.}

461.else/*收到的数据是4比特*/ 462.{

463.SerBuffer[0]&=0x0f;/*取出低四位*/ 464.switch(SerBuffer[0]) 465.{

466.case0x00:/*0000=置收到错误的比特数目标志位*/ 467.status=MI_NOTAUTHERR; 468.break; 469.case0x0a:

470.status=MI_OK;/*1010=置命令正确执行位*/ 471.break;

472.case0x01:/*0001=置数据结构错误位*/ 473.status=MI_VALERR; 474.break;

475.default:/*收到NACK,发送的数据出错?CRC,PARITY?*/ 476.status=MI_CODEERR; 477.break; 478.} 479.} 480.} 481.}

482.returnstatus;/*这个SWITCH作为整个函数的反馈值*/ 483.} 484.

485.///////////////////////////////////////////////////////////////////////

486.//SetcardinHALT-state 487./*终止卡的操作*/

488.///////////////////////////////////////////////////////////////////////

489.charM500PiccHalt(void) 490.{

491.charidatastatus=MI_CODEERR;/*将STATUS初值定为数据错*/ 492.

493.//*************CmdSequence********************************** 494.ResetInfo(MInfo);/*Minfo=INFO*/

495.SerBuffer[0]=PICC_HALT;/*执行IDLE指令?关闭卡*/ 496.SerBuffer[1]=0x00;/*同上*/

497.MInfo.nBytesToSend=2;/*同上*/

498.status=M500PcdCmd(PCD_TRANSCEIVE,/*调用命令执行程序*/ 499.SerBuffer, 500.&MInfo); 501.if(status) 502.{

503.//timeouterror==>noNAKreceived==>OK

504.if(status==MI_NOTAGERR||status==MI_ACCESSTIMEOUT) 505.{/*无卡响应?命令执行成功*/ 506.status=MI_OK; 507.} 508.}

509.//resetcommandregister-noresponsefromtagit

510.WriteIO(RegCommand,PCD_IDLE);/*有卡响应?命令执行不成功*/ 511.returnstatus;/*返回状态值*/ 512.} 513.

514.///////////////////////////////////////////////////////////////////////

515.//ResettheMFRC500

516./*重启RC500,开始新一轮寻卡*/

517.///////////////////////////////////////////////////////////////////////

518.charM500PcdReset(void) 519.{

520.charidatastatus=MI_OK;/*状态初值*/

521.unsignedintidatatimecnt=0;/*局部计数器置初值*/ 522.

523.RC500RST=0;/*重启时序*/ 524.delay_1ms(25); 525.RC500RST=1;

526.delay_50us(200); 527.RC500RST=0;

528.delay_50us(50); 529.timecnt=1000;

530.while(ReadIO(RegCommand)&0x3F)&&timecnt--);/*循环查询?*/ 531.if(!timecnt) 532.{

533.status=MI_RESETERR;/*timecnt=0,则置status为重起失败标志*/ 534.}

535.if(status==MI_OK)/*如果在timecnt没变成0时status就被置命令执行成功*/ 536.{

537.//WriteIO(RegPage,0x80);

538.if(ReadIO(RegCommand)!=0x00)/*如果此时regcommand不为0*/ 539.{

540.status=MI_INTERFACEERR;/*则置status为接口出错?实质上是rc500没有响应单片机或是上位机?*/ 541.} 542.}

543.returnstatus;/*返回状态值*/ 544.} 545.

546.///////////////////////////////////////////////////////////////////////

547.//ConfigurestheMFRC500

548./*新一轮认卡后的寄存器配置过程*/

549.///////////////////////////////////////////////////////////////////////

550.charM500PcdConfig(void) 551.{

552.charidatastatus; 553.

554.if((status=M500PcdReset())==MI_OK)/*如果返回的状态值是重启成功*/ 555.{

556.WriteIO(RegClockQControl,0x00);/*q通道时钟控制寄存器置0?自动校准时钟偏差*/

557.WriteIO(RegClockQControl,0x40);/*q通道时钟控制寄存器置40?不校准时钟偏差?*/

558.delay_50us(2);/*延时100us*/

559.ClearBitMask(RegClockQControl,0x40);/*q通道时钟控制寄存器又置0?自动校准时钟偏差?1BH?*/

560.WriteIO(RegBitPhase,0xAD);/*选择发送与接收之间的时钟相位差?默认值?oxad-----important ?1FH?*/

561.WriteIO(RegRxThreshold,0xFF);/*选择RX脚输入信号的门限电压值0XFF?1CH?*/

562.WriteIO(RegRxControl2,0x01);/*接收控制--使用内部解码器?用Q时钟?接收器时常处于激活态 ?1EH?*/

563.WriteIO(RegFIFOLevel,0x1A);/*FIFO饱和度水平=1A?29H?*/

564.WriteIO(RegTimerControl,0x02);/*发送一完成自动开始计数?2BH?*/ 565.WriteIO(RegIRqPinConfig,0x03);/*IRQ脚配置?输出电平与IRQ标志相反?工作于标准CMOS输出模式 ?2DH?*/

566.M500PcdRfReset(1);/*调用射频重启函数*/ 567.}

568.returnstatus;/*返回状态值*/

569.} 570.

571./////////////////////////////////////////////////////////////// 572.//KeyloadingintotheMFRC500'sEEPROM 573./*将主密钥送入RC500的EEROM*/

574./////////////////////////////////////////////////////////////// 575.charM500PcdLoadKeyE2(unsignedcharkey_type, 576.unsignedcharsector,/*存放密钥的EEROM块地址*/ 577.unsignedchar*uncoded_keys) 578.{

579.signedcharstatus=MI_OK;

580.unsignedinte2addr=0x80+sector*0x18;/*EEROM地址为两个字节*/ 581.unsignedcharcoded_keys[12]; 582.

583.if(key_type==PICC_AUTHENT1B)/*如果是B类卡*/ 584.{

585.e2addr+=12;/*取12字节以后的作为密钥地址*/ 586.}

587.if((status=M500HostCodeKey(uncoded_keys,coded_keys))==MI_OK)/*如果密钥编码成功*/ 588.{

589.status=PcdWriteE2(e2addr,12,coded_keys);/*将主密钥?12字节?送入RC500的EEROM*/ 590.}

591.returnstatus;/*返回状态值*/ 592.} 593.

594.///////////////////////////////////////////////////////////////////////

595.//WritetheMFRC500'sEEPROM 596./*写RC500'sEEPROM*/

597.///////////////////////////////////////////////////////////////////////

598.charPcdWriteE2(unsignedintstartaddr,/*EEROM地址为两个字节*/ 599.unsignedcharlength,/*长度*/

600.unsignedchar*_data)/*密钥在单片机里的初始地址*/ 601.{

602.charstatus=MI_OK; 603.ResetInfo(MInfo);

604.SerBuffer[0]=startaddr&0xFF;/*存放密钥的EEROM块地址*/

605.SerBuffer[1]=(startaddr>>8)&0xFF;/*STARTADDR为整型变量?16BIT*/ 606.memcpy(SerBuffer+2,_data,length);/*将密钥拷贝到发送缓冲区*/ 607.

608.MInfo.nBytesToSend=length+2;/*发送14字节*/

609.

610.status=M500PcdCmd(PCD_WRITEE2,/*执行写RC500'sEEPROM命令*/ 611.SerBuffer, 612.&MInfo);

613.returnstatus;/*返回状态值*/ 614.} 615.

616.///////////////////////////////////////////////////////////////////////

617.//SelectCommanddefinedinISO14443(MIFARE) 618./*配置MFOUT/MFIN两脚输出内容*/

619.///////////////////////////////////////////////////////////////////////

620.charM500PcdMfOutSelect(unsignedchartype)/*TYPE为MFOUT输出的信号是什么类型*/ 621.{

622.WriteIO(RegMfOutSelect,type&0x7);/*MFOUTSELECT寄存器?26H?=TYPE--低三位有效*/ 623.returnMI_OK; 624.} 625.

626.///////////////////////////////////////////////////////////////////////

627.//RequestCommanddefinedinISO14443(MIFARE)

628.//Request,Anticoll,Select,returnCardType(2bytes)+CardSerialNo(4bytes)

629.//寻卡?防冲突?选择卡返回卡类型?2bytes?+卡系列号(4bytes)

630.///////////////////////////////////////////////////////////////////////

631.charM500PiccCommonRequest(unsignedcharreq_code,unsignedchar*atq) 632.{/*ATQ=ANSWERTOREQUEST:响应信息?两个字节*/ 633.charidatastatus=MI_OK; 634.

635.M500PcdSetTmo(3);/*计数器工作于模式3*/

636.WriteIO(RegChannelRedundancy,0x03);/*通道冗余寄存器置3--奇校验?每个字节后附加一个校验位?无CRC校验*/

637.ClearBitMask(RegControl,0x08);/*清加密算法位?09H?*/

638.WriteIO(RegBitFraming,0x07);/*最后三位为111?表示最后一字节须传送的位数为1?0FH?*/

639.SetBitMask(RegTxControl,0x03);/*TX脚发送被数据调制好的能量载波信号?11H?*/ 640.

641.ResetInfo(MInfo);/*信息接口*/

642.SerBuffer[0]=req_code;/*REQ_CODE=26H:REQUESTALL,REQ_CODE=52H:REQ

UESTIDLE,*/

643.MInfo.nBytesToSend=1;

644./*上面是REQUEST指令相关信息*/

645.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo);/*执行TRANSCEIVE指令?寻卡--REQUEST?*/ 646.

647.if(status)/*返回标志为1*/ 648.{

649.*atq=0;/*则响应值置0*/ 650.}

651.else/*返回标志为0--成功了一半*/ 652.{

653.if(MInfo.nBitsReceived!=16)/*如果收到的比特数不是16?则命令执行失败*/ 654.{

655.*atq=0;/*则响应值置0*/

656.status=MI_BITCOUNTERR;/*置状态寄存器为比特计数器错*/ 657.} 658.else 659.{

660.status=MI_OK;/*是16?命令执行成功*/

661.memcpy(atq,SerBuffer,2);/*从单片机数据缓冲区中读取响应信号?ATQ?*/ 662.} 663.}

664.returnstatus;/*返回状态值*/ 665.} 666.

667.///////////////////////////////////////////////////////////////////

668.//CascadedAnti-CollisionCommanddefinedinISO14443(MIFARE) 669./*防冲突读卡的系列号MLastSelectedSnr四位的序列号*/

670.///////////////////////////////////////////////////////////////////

671.charM500PiccCascAnticoll(unsignedcharbcnt,unsignedchar*snr) 672.{/*BCNT=0--32,比特计数器?SNR=序列号存储缓冲区4个字节?*/ 673.charidatastatus=MI_OK; 674.charidatasnr_in[4]; 675.charidatanbytes=0; 676.charidatanbits=0; 677.charidatacomplete=0; 678.charidatai=0;

679.charidatabyteOffset=0; 680.unsignedchardummyShift1;

681.unsignedchardummyShift2; 682.

683.M500PcdSetTmo(106);/*初始化计时器--方式106*/ 684.memcpy(snr_in,snr,4);/*序列号复制*/ 685.

686.WriteIO(RegDecoderControl,0x28);/*任何在比特碰撞出现之后接收到的信号位进被屏蔽为0?大大简化ISO14443A标 准*/

687.ClearBitMask(RegControl,0x08);/*清加密算法位?09H?*/ 688.complete=0;

689.while(!complete&&(status==MI_OK))/*如果这两个条件都成立则在此循环*/ 690.{

691.ResetInfo(MInfo);

692.WriteIO(RegChannelRedundancy,0x03);/*通道冗余寄存器置3--奇校验?每个字节后附加一个校验位?无CRC校 验*/

693.nbits=bcnt%8;/*NBIT=BCNT除以8的余数*/ 694.if(nbits)/*如果不为0*/ 695.{

696.WriteIO(RegBitFraming,nbits<4|nbits);/*如果不为0*/ 697.nbytes=bcnt/8+1;/*NBYTES为收到的序列号字节数?要加一*/ 698.if(nbits==7) 699.{

700.MInfo.cmd=PICC_ANTICOLL1;

701.WriteIO(RegBitFraming,nbits);/**/ 702.} 703.}

704.else/*余数为0*/ 705.{

706.nbytes=bcnt/8;/*NBYTES为收到的序列号字节数*/ 707.}

708.SerBuffer[0]=0x93;/*标准选卡命令*/ 709.SerBuffer[1]=0x20+((bcnt/8)<4)+nbits; 710.

711.for(i=0;inbytes;i++) 712.{

713.SerBuffer[i+2]=snr_in[i];/*序列号输入接口*/ 714.}

715.MInfo.nBytesToSend=2+nbytes;/*输入字节个数*/ 716.

717.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 718.if(nbits==7)

719.{/*反碰撞处理过程?*/

720.dummyShift1=0x00;

721.for(i=0;iMInfo.nBytesReceived;i++) 722.{

723.dummyShift2=SerBuffer[i];

724.SerBuffer[i]=(dummyShift1>>(i+1))|(SerBuffer[i]<(7-i)); 725.dummyShift1=dummyShift2; 726.}

727.MInfo.nBitsReceived-=MInfo.nBytesReceived;

728.if(MInfo.collPos)MInfo.collPos+=7-(MInfo.collPos+6)/9; 729.}

730.if(status==MI_OK||status==MI_COLLERR) 731.{

732.if(MInfo.nBitsReceived!=(40-bcnt)) 733.{

734.status=MI_BITCOUNTERR; 735.} 736.else 737.{

738.byteOffset=0; 739.if(nbits!=0) 740.{

741.snr_in[nbytes-1]=snr_in[nbytes-1]|SerBuffer[0]; 742.byteOffset=1; 743.} 744.

745.for(i=0;i(4-nbytes);i++) 746.{

747.snr_in[nbytes+i]=SerBuffer[i+byteOffset]; 748.} 749.

750.if(status!=MI_COLLERR) 751.{

752.dummyShift2=snr_in[0]^snr_in[1]^snr_in[2]^snr_in[3]; 753.dummyShift1=SerBuffer[MInfo.nBytesReceived-1]; 754.if(dummyShift2!=dummyShift1) 755.{

756.status=MI_SERNRERR; 757.} 758.else 759.{

760.complete=1; 761.} 762.} 763.else

764.{

765.bcnt=bcnt+MInfo.collPos-nbits; 766.status=MI_OK; 767.} 768.} 769.} 770.}

771.if(status==MI_OK)/*如果状态标志成功*/ 772.{

773.memcpy(snr,snr_in,4);/*保存序列号*/ 774.} 775.else 776.{

777.memcpy(snr,\不成功?则返回0000*/ 778.}

779.ClearBitMask(RegDecoderControl,0x20);/*清掉反碰撞位*/ 780.

781.returnstatus;/*返回状态值*/ 782.} 783.

784.//////////////////////////////////////////////////////////////////

785.//CascadedSelectcommanddefinedinISO14443(MIFARE) 786./*选择卡?确定序列号是否大于4字节*/

787.//////////////////////////////////////////////////////////////////

788.charM500PiccCascSelect(unsignedchar*snr,unsignedchar*sak) 789.{/*snr为序列号首址?sak为一字节选卡回应值*/ 790.charidatastatus=MI_OK; 791.

792.M500PcdSetTmo(106);/*计时器初始化*/ 793.

794.WriteIO(RegChannelRedundancy,0x0F);/*通道冗余寄存器置f--16bitcrc校验?确定数据帧最后两个字节为crc字节? 奇校验?每个字节后附加一个校验位*/

795.ClearBitMask(RegControl,0x08);/*清加密算法位?09H?*/

796./////////////////////////////////////////////////////////////////////////////////////////////////////////////

797./*送rc500FIFO的相关信息?与命令函数m500pcdcmd()配合*/ 798.ResetInfo(MInfo);/*给rc500的相关信息?与指令相配合*/

799.SerBuffer[0]=0x93;/*给rc500的相关信息?写入指令?选卡?数据*/ 800.SerBuffer[1]=0x70;/*给rc500的相关信息?写入数据*/

801.memcpy(SerBuffer+2,snr,4);/*将原指针snr对应的序列号拷贝到发送缓冲区serbuffer中去*/

802.SerBuffer[6]=SerBuffer[2]^SerBuffer[3]^SerBuffer[4]^SerBuffer[5];/*序号中四字节按位异或得到crc校 验字节*/

803.MInfo.nBytesToSend=7;/*给rc500的相关信息?与指令相配合?须发送的字节数*/

804.//////////////////////////////////////////////////////////////////////////////////////////////////////////////

805.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo);/*执行命令函数m500pcdcmd()?返回STATUS*/ 806.

807.*sak=0;/*sak选卡回应值先置0*/

808.if(status==MI_OK)/*返回值为执行成功标志MI_OK*/ 809.{

810.if(MInfo.nBitsReceived!=8)/*如果接收到的不是一个字节*/ 811.{

812.status=MI_BITCOUNTERR;/*则置标志位为MI_BITCOUNTERR*/ 813.}

814.else/*如果接收到的是一个字节*/ 815.{

816.*sak=SerBuffer[0];/*则将该值存于SAK中*/ 817.} 818.}

819.returnstatus;/*返回状态值*/ 820.} 821.

822.///////////////////////////////////////////////////////////////////////

823.//KeyloadingintotheMFRC500'sEEPROM

824.//将RC500的EEROM中的密钥载入密钥缓冲区,校验卡密码(E2)

825.///////////////////////////////////////////////////////////////////////

826.charM500PiccAuthE2(unsignedcharauth_mode,unsignedchar*snr, 827.unsignedcharkeynr,unsignedcharblock)

828./*入口参数?AUTH_MODE:A/B卡型号?SNR:卡序列号?KEYNR:密钥所在扇区数?BLOCK:密钥所在数据块*/ 829.{

830.charidatastatus=MI_OK;

831.unsignedinte2addr=0x80+keynr*0x18;/*得出密钥在EEROM中的位置*/ 832.//unsignedchar*e2addrbuf=(unsignedchar*)&e2addr; 833.unsignedchar*e2addrbuf; 834.

835.e2addrbuf=(unsignedchar*)&e2addr;

836.if(auth_mode==PICC_AUTHENT1B)/*如果是B类卡*/ 837.{

838.e2addr+=12;/*密钥地址加12*/ 839.}

840.FlushFIFO();

841.ResetInfo(MInfo); 842.

843.memcpy(SerBuffer,e2addrbuf,2);/*从E2ADDRBUF中取出存密钥的EEROM地址?两个字节?*/

844.SerBuffer[2]=SerBuffer[0]; 845.SerBuffer[0]=SerBuffer[1]; 846.SerBuffer[1]=SerBuffer[2]; 847.MInfo.nBytesToSend=2;

848.if((status=M500PcdCmd(PCD_LOADKEYE2,SerBuffer,&MInfo))==MI_OK) 849.{/*下载密钥成功*/

850.status=M500PiccAuthState(auth_mode,snr,block); 851.}/*三轮认证*/

852.returnstatus;/*返回状态值*/ 853.} 854.

855.///////////////////////////////////////////////////////////////////////

856.//Authenticationkeycoding 857./*将密钥换成标准密钥形式*/

858.///////////////////////////////////////////////////////////////////////

859.charM500HostCodeKey(unsignedchar*uncoded,unsignedchar*coded) 860.{

861.charidatastatus=MI_OK; 862.unsignedcharidatacnt=0; 863.unsignedcharidataln=0; 864.unsignedcharidatahn=0;

865.for(cnt=0;cnt6;cnt++)/*密钥由6字节转成12字节*/ 866.{

867.ln=uncoded[cnt]&0x0F;/*密钥一字节的低四位*/ 868.hn=uncoded[cnt]>>4;/*密钥一字节的高四位*/ 869.coded[cnt*2+1]=(~ln<4)|ln; 870.coded[cnt*2]=(~hn<4)|hn; 871.}

872.returnMI_OK; 873.} 874.

875.///////////////////////////////////////////////////////////////////

876.//AuthenticationwithdirectkeyloadingfromtheuC

877./*直接校验从单片机载入的密码?针对卡中的某一块数据来说?16块?每

块64字节?*/

878.//////////////////////////////////////////////////////////////////

879.charM500PiccAuthKey(unsignedcharauth_mode, 880.unsignedchar*snr, 881.unsignedchar*keys, 882.unsignedcharblock) 883.{

884.charidatastatus=MI_OK; 885.//PcdSetTmo(2); 886.FlushFIFO();

887.ResetInfo(MInfo);

888.memcpy(SerBuffer,keys,12); 889.MInfo.nBytesToSend=12;

890.if((status=M500PcdCmd(PCD_LOADKEY,SerBuffer,&MInfo))==MI_OK) 891.{/*直接从单片机载入密码到FIFO,然后再载入密钥缓冲区*/ 892.status=M500PiccAuthState(auth_mode,snr,block); 893.}/*三轮认证*/ 894.returnstatus; 895.}/*返回状态值*/ 896.

897.///////////////////////////////////////////////////////////////////////

898./*三轮认证函数*/

899.///////////////////////////////////////////////////////////////////////

900.charM500PiccAuthState(unsignedcharauth_mode,unsignedchar*snr,unsignedcharblock)

901.{/*入口参数?AUTH_MODE:A/B卡型号?SNR:卡序列号?BLOCK:要访问所在数据块*/

902.charidatastatus=MI_OK; 903.unsignedcharidatai=0; 904.

905.status=ReadIO(RegErrorFlag);/*读RC500中的错误标志寄存器*/ 906.if(status!=MI_OK)/*载入密钥不成功*/ 907.{

908.if(status&0x40) 909.{

910.status=MI_KEYERR;/*密钥出错标志*/ 911.} 912.else 913.{

914.status=MI_AUTHERR;/*认证出错标志*/ 915.}

916.}

917.else/*载入密钥成功*/ 918.{/*三轮认证开始*/ 919.

920.SerBuffer[0]=auth_mode; 921.SerBuffer[1]=block;

922.memcpy(SerBuffer+2,snr,4); 923.ResetInfo(MInfo);

924.MInfo.nBytesToSend=6;

925./*上面为认证命令1的入口参数?卡型?要访问的数据块?序列号?相关流动信息?要发送的字节数*/

926.if((status=M500PcdCmd(PCD_AUTHENT1,SerBuffer,&MInfo))==MI_OK) 927.{

928.if(ReadIO(RegSecondaryStatus)&0x07) 929.{

930.status=MI_BITCOUNTERR;/*认证不成功?置比特计数标志*/ 931.} 932.else 933.{

934.ResetInfo(MInfo);

935.MInfo.nBytesToSend=0;

936./*上面为认证命令2的入口参数?相关流动信息?要发送的字节数*/ 937.if((status=M500PcdCmd(PCD_AUTHENT2, 938.SerBuffer,

939.&MInfo))==MI_OK) 940.{

941.if(ReadIO(RegControl)&0x08) 942.{

943.status=MI_OK;/*认证成功?RC500会自动置CRYTON=1*/ 944.} 945.else 946.{

947.status=MI_AUTHERR;/*认证不成功?置认证错标志*/ 948.} 949.} 950.} 951.} 952.}

953.returnstatus;/*返回状态值*/ 954.} 955.

956.//////////////////////////////////////////////////////////////// 957.//Readthemifarecard

958./*读卡?一次读出16字节?一整块BLOCK?*/

959.//////////////////////////////////////////////////////////////// 960.charM500PiccRead(unsignedcharaddr,unsignedchar*_data)

961.{/*addr=卡的EEROM数据块地址?_data=读出数据的存放区首址*/ 962.charidatastatus=MI_OK; 963.charidatatmp=0; 964.

965.FlushFIFO();/*清缓冲区*/ 966.

967.M500PcdSetTmo(3);

968.WriteIO(RegChannelRedundancy,0x0F);/*16比特CRC检测?奇校验*/ 969.ResetInfo(MInfo);

970.SerBuffer[0]=PICC_READ; 971.SerBuffer[1]=addr; 972.MInfo.nBytesToSend=2;

973./*上面为读卡命令的入口参数?读指令?块地址?发送字节数*/ 974.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo);/*读卡*/ 975.

976.if(status!=MI_OK)/*读卡命令执行不成功*/ 977.{

978.if(status!=MI_NOTAGERR) 979.{

980.if(MInfo.nBitsReceived==4) 981.{

982.SerBuffer[0]&=0x0f;

983.if((SerBuffer[0]&0x0a)==0) 984.{

985.status=MI_NOTAUTHERR;/*认证不成功?或说无权访问*/ 986.} 987.else 988.{

989.status=MI_CODEERR;/*编码错误*/ 990.} 991.} 992.}

993.memcpy(_data,\执行不成功则返回00*/ 994.}

995.else/*读卡命令执行成功*///ResponseProcessing 996.{

997.if(MInfo.nBytesReceived!=16)/*如果返回的字节个数不是16*/ 998.{

999.status=MI_BYTECOUNTERR;/*则置字节计数错*/

1000.memcpy(_data,\返回00*/ 1001.}

1002.else/*如果返回的字节个数是16*/

1003.{

1004.memcpy(_data,SerBuffer,16);/*则将读出的数据送_DATA存储*/ 1005.} 1006.}

1007.M500PcdSetTmo(1);/*延时?方式0?*/ 1008.returnstatus;/*返回状态值*/ 1009.} 1010.

1011.////////////////////////////////////////////////////////////////

1012.//Writethemifarecard

1013./*写卡,下载密码到15区?1-15?的任意区的第四块?密钥块?*/

1014.////////////////////////////////////////////////////////////////

1015.charM500PiccWrite(unsignedcharaddr,unsignedchar*_data) 1016.{/*addr=卡的EEROM数据块地址?_data=写入数据的存放区首址*/ 1017.charidatastatus=MI_OK; 1018.

1019.ResetInfo(MInfo);

1020.SerBuffer[0]=PICC_WRITE; 1021.SerBuffer[1]=addr; 1022.MInfo.nBytesToSend=2;

1023./*上面为写卡命令的入口参数?写指令?块地址?发送字节数*/ 1024.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 1025.

1026.if(status!=MI_NOTAGERR)/*如果不是出现无卡情况*/ 1027.{

1028.if(MInfo.nBitsReceived!=4)/*如果返回比特数不是4*/ 1029.{

1030.status=MI_BITCOUNTERR;/*则置比特计数错标志*/ 1031.}

1032.else/*如果返回比特数是4*/ 1033.{

1034.SerBuffer[0]&=0x0f;

1035.if((SerBuffer[0]&0x0a)==0) 1036.{

1037.status=MI_NOTAUTHERR;/*没有通过授权?有些块是禁止读写的?*/ 1038.} 1039.else 1040.{

1041.if(SerBuffer[0]==0x0a)/*如果返回数据第一个字节最后四位是A*/ 1042.{

1043.status=MI_OK;/*则写入命令执行成功*/ 1044.}

1045.else 1046.{

1047.status=MI_CODEERR;/*否则是数据校验出错*/ 1048.} 1049.} 1050.} 1051.} 1052.

1053.if(status==MI_OK)/*如果写入命令执行成功*/ 1054.{

1055.M500PcdSetTmo(3); 1056.

1057.ResetInfo(MInfo);

1058.memcpy(SerBuffer,_data,16); 1059.MInfo.nBytesToSend=16;

1060./*上面为写卡命令的入口参数?要写入的数据16字节*/

1061.status=M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo);/*开始写入*/ 1062./*要写卡?必须先送命令?再送数据*/

1063.if(status&0x80)/*如果返回状态最高位为1*/ 1064.{

1065.status=MI_NOTAGERR;/*则是无卡在此场*/ 1066.}

1067.else/*如果返回状态最高位为0*/ 1068.{

1069.if(MInfo.nBitsReceived!=4)/*如果返回比特数不是4*/ 1070.{

1071.status=MI_BITCOUNTERR;/*则置比特计数错标志*/ 1072.}

1073.else/*如果返回比特数是4*/ 1074.{

1075.SerBuffer[0]&=0x0f;

1076.if((SerBuffer[0]&0x0a)==0)/*如果返回数据第一个字节最后四位是0*/ 1077.{

1078.status=MI_WRITEERR;/*写卡失败标志*/ 1079.}

1080.else/*如果返回数据第一个字节最后四位不是0*/ 1081.{

1082.if(SerBuffer[0]==0x0a)/*如果返回数据第一个字节最后四位是A?为什么?*/ 1083.{

1084.status=MI_OK;/*则写卡成功*/ 1085.} 1086.else 1087.{

1088.status=MI_CODEERR;/*否则是数据校验出错*/ 1089.} 1090.} 1091.} 1092.}

1093.M500PcdSetTmo(1);/*延时?方式1?*/ 1094.}

1095.returnstatus;/*返回状态值*/ 1096.} 1097.

1098.///////////////////////////////////////////////////////////////////////

1099.//ResetRfCard

1100./*重新配置RF读卡器*/

1101.///////////////////////////////////////////////////////////////////////

1102.charM500PcdRfReset(unsignedcharms) 1103.{

1104.charidatastatus=MI_OK; 1105.

1106.if(ms)/*如果有重启信号1*/ 1107.{

1108.ClearBitMask(RegTxControl,0x03);/*全部清零?不再有输出*/ 1109.delay_1ms(2);

1110.SetBitMask(RegTxControl,0x03);/*让TX1/TX2脚都能输出*/ 1111.}

1112.else/*如果没有重启信号0*/ 1113.{

1114.ClearBitMask(RegTxControl,0x03);/*关闭输出*/ 1115.}

1116.returnstatus;/*返回状态值*/ 1117.} 1118.

1119.#pragmanoaregs 1120.

1121./*延时子程序集*/ 1122.

1123.///////////////////////////////////////////////////////////////////////

1124.//Delay50us

1125.///////////////////////////////////////////////////////////////////////

1126.voiddelay_50us(unsignedchar_50us) 1127.{

1128.while(_50us--) 1129.{

1130._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1131._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1132._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1133._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1134._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1135._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1136._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

1137._nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 1138.} 1139.} 1140.

1141.///////////////////////////////////////////////////////////////////////

1142.//Delay1ms

1143.///////////////////////////////////////////////////////////////////////

1144.voiddelay_1ms(unsignedchar_1ms) 1145.{

1146.#ifndefNO_TIMER2 1147.RCAP2LH=RCAP2_1ms; 1148.T2LH=RCAP2_1ms; 1149.

1150.TR2=TRUE;

1151.while(_1ms--) 1152.{

1153.while(!TF2); 1154.TF2=FALSE; 1155.}

1156.TR2=FALSE; 1157.#else

1158.while(_1ms--) 1159.{

1160.delay_50us(20); 1161.}

1162.#endif 1163.} 1164.

1165.///////////////////////////////////////////////////////////////////////

1166.//Delay10ms

1167.///////////////////////////////////////////////////////////////////////

1168.voiddelay_10ms(unsignedint_10ms) 1169.{

1170.#ifndefNO_TIMER2 1171.RCAP2LH=RCAP2_10ms; 1172.T2LH=RCAP2_10ms; 1173.

1174.TR2=TRUE;

1175.while(_10ms--) 1176.{

1177.while(!TF2); 1178.TF2=FALSE; 1179.}

1180.TR2=FALSE; 1181.#else

1182.while(_10ms--) 1183.{

1184.delay_50us(19); 1185.if(CmdValid) 1186.return;

1187.delay_50us(20); 1188.if(CmdValid) 1189.return;

1190.delay_50us(20); 1191.if(CmdValid) 1192.return;

1193.delay_50us(20); 1194.if(CmdValid) 1195.return;

1196.delay_50us(20); 1197.if(CmdValid) 1198.return;

1199.delay_50us(20); 1200.if(CmdValid) 1201.return;

1202.delay_50us(20); 1203.if(CmdValid)

1204.return;

1205.delay_50us(20); 1206.if(CmdValid) 1207.return;

1208.delay_50us(20); 1209.if(CmdValid) 1210.return;

1211.delay_50us(19); 1212.if(CmdValid) 1213.return; 1214.}

1215.#endif 1216.} 1217.

1218.///////////////////////////////////////////////////////////////////////

1219./*RC500中断处理总程序*/

1220.///////////////////////////////////////////////////////////////////////

1221.voidRC500ISR(void)interrupt0using1 1222.{

1223.staticunsignedcharidatairqBits; 1224.staticunsignedcharidatairqMask; 1225.staticunsignedcharidatanbytes; 1226.staticunsignedcharidatacnt; 1227.

1228.IE0=0;/*用的是INT0脚*/ 1229.WriteRawIO(0,0x80);

1230.if(MpIsrInfo&&MpIsrOut) 1231.{

1232.while(ReadRawIO(RegPrimaryStatus)&0x08)/*第四位表示是否有中断请求?03H?*/ 1233.{

1234.irqMask=ReadRawIO(RegInterruptEn);/*IRQMASK=中断使能寄存器内容?06H?*/

1235.irqBits=ReadRawIO(RegInterruptRq)&irqMask;/*IRQBITS=中断使能+中断请求寄存器内容?07H?*/

1236.MpIsrInfo->irqSource|=irqBits;

1237.if(irqBits&0x01)/*如果缓冲器FIFO未满成立*/ 1238.{

1239.nbytes=64-ReadRawIO(RegFIFOLength);

1240.if((MpIsrInfo->nBytesToSend-MpIsrInfo->nBytesSent)=nbytes) 1241.{

1242.nbytes=MpIsrInfo->nBytesToSend-MpIsrInfo->nBytesSent;

1243.WriteRawIO(RegInterruptEn,0x01); 1244.}

1245.for(cnt=0;cntnbytes;cnt++) 1246.{

1247.WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]); 1248.MpIsrInfo->nBytesSent++; 1249.}

1250.WriteRawIO(RegInterruptRq,0x01); 1251.}

1252.if(irqBits&0x10)/*如果有发送中断请求*/ 1253.{

1254.WriteRawIO(RegInterruptRq,0x10);/*则置发送中断请求*/

1255.WriteRawIO(RegInterruptEn,0x82);/*缓冲区FIFO满中断使能*/ 1256.if(MpIsrInfo->cmd==PICC_ANTICOLL1) 1257.{

1258.WriteIO(RegChannelRedundancy,0x02); 1259.WriteRawIO(0,0x80); 1260.} 1261.}

1262.if(irqBits&0x0E)/*如果有接收中断请求?*/ 1263.{

1264.nbytes=ReadRawIO(RegFIFOLength); 1265.for(cnt=0;cntnbytes;cnt++) 1266.{

1267.MpIsrOut[MpIsrInfo->nBytesReceived]=ReadRawIO(RegFIFOData); 1268.MpIsrInfo->nBytesReceived++; 1269.}

1270.WriteRawIO(RegInterruptRq,0x0A&irqBits); 1271.}

1272.if(irqBits&0x04)/*如果有IDLE中断请求*/ 1273.{

1274.WriteRawIO(RegInterruptEn,0x20);/*则置计时器中断使能和请求*/ 1275.WriteRawIO(RegInterruptRq,0x20); 1276.irqBits&=~0x20;

1277.MpIsrInfo->irqSource&=~0x20;

1278.WriteRawIO(RegInterruptRq,0x04); 1279.}

1280.if(irqBits&0x20)/*如果有计时器中断请求*/ 1281.{

1282.WriteRawIO(RegInterruptRq,0x20);

1283.MpIsrInfo->status=MI_NOTAGERR;/*则表明无卡在此场中*/ 1284.} 1285.} 1286.}

1287.} 1288.

1289.///////////////////////////////////////////////////////////////////////

1290./*RS232异步串行通信接收和发送中断子程序*/

1291.///////////////////////////////////////////////////////////////////////

1292.voidisr_UART(void)interrupt4using1 1293.{

1294.unsignedcharlen,i; 1295.unsignedintj=0; 1296.

1297.if(RI) 1298.{

1299.len=SBUF;/*LEN为数据个数*/ 1300.RI=0;

1301.for(i=0;i

1303.while(!RI) 1304.{ 1305.j++;

1306.if(j>1000) 1307.{

1308.break; 1309.} 1310.}

1311.if(j<1000) 1312.{

1313.RevBuffer[i]=SBUF;/*接收来自上位机PC的数据*/ 1314.RI=0; 1315.j=0; 1316.} 1317.else 1318.{

1319.break; 1320.} 1321.}

1322.if(i==len) 1323.{

1324.REN=0;

1325.CmdValid=1; 1326.} 1327.}

1328.elseif(!RI&&TI)

1329.{

1330.TI=0;

1331.len=RevBuffer[0];/*LEN为数据个数*/ 1332.for(i=0;i

1334.SBUF=RevBuffer[i];/*发送单片机里的已知数据*/ 1335.while(!TI); 1336.TI=0; 1337.}

1338.REN=1; 1339.} 1340.} 1341.

1342.///////////////////////////////////////////////////////////////////////

1343./*MFRC500软硬件配置总程序*/

1344.///////////////////////////////////////////////////////////////////////

1345.charMfConfig(void) 1346.{

1347.charstatus=MI_OK; 1348.

1349.M500PcdConfig();/*配置RC500读写器的引脚?重启时序*/ 1350.M500PcdMfOutSelect(2);/*?*/ 1351.returnstatus; 1352.} 1353.

1354.///////////////////////////////////////////////////////////////////////

1355./*系统初始化---单片机和RC500芯片*/

1356.///////////////////////////////////////////////////////////////////////

1357.voidinit(void) 1358.{

1359.RC500RST=0;

1360.ET2=0;//禁止定时器2中断

1361.T2CON=0x04;//启动定时器2(tr2=1) 1362.PCON=0x80;

1363.SCON=0x70;//8位uart,波特率可变

1364.TMOD=0x21;//TMOD=0x21;两个定时器均为自动重载方式 1365.

1366.TH1=BAUD_9600; 1367.TL1=TH1;

1368.TR1=TRUE;//串行口波特率发生器---定时器1

1369.

1370.TH0=0x60;//定时器0初始化 1371.TL0=0x60; 1372.TR0=0; 1373.

1374.ET0=0;//定时器0中断禁止---用作一般定时器 1375.ET1=0;//定时器1中断禁止---用作波特率发生器 1376.EA=1;//总中断允许

1377.EX0=1;//外部中断0允许----rc500的irq 1378.IT0=1;//外部中断0触发类型--下降沿触发 1379.TR2=0;//关闭定时器2(tr2=1) 1380.ES=TRUE;//串行口中断允许 1381.CmdValid=0; 1382.

1383.SPEAKER=1;

1384.delay_10ms(30); 1385.SPEAKER=0;

1386.delay_10ms(30); 1387.SPEAKER=1; 1388.

1389.reset_7289();

1390.MfConfig();/*调用RC500软硬件配置总程序*/ 1391.} 1392.

1393.///////////////////////////////////////////////////////////////////////

1394.//IC卡处理函数

1395.///////////////////////////////////////////////////////////////////////

1396.voidcmd_execution(void) 1397.{

1398.unsignedcharcmd; 1399.unsignedcharstatus; 1400.

1401.cmd=RevBuffer[0];/*来自上位机的命令存于REVBUFFER[0]*/ 1402.switch(cmd) 1403.{

1404.case1:/*终止卡的操作*/ 1405.status=M500PiccHalt(); 1406.

1407.RevBuffer[0]=1;

1408.RevBuffer[1]=status;/*返回给上位机的内容*/ 1409.break;

1410.case2://Request,Anticoll,Select,returnCardType(2bytes)+CardSeri

alNo(4bytes)

1411.//寻卡?防冲突?选择卡返回卡类型?2bytes?+卡序列号(4bytes) 1412.status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]); 1413.if(status!=0)/*寻卡指令?应答信息*/ 1414.{/*寻卡不成功*/

1415.status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]);/*再次寻卡*/

1416.if(status!=0)

1417.{/*寻卡还是不成功*/ 1418.

1419.RevBuffer[0]=1;

1420.RevBuffer[1]=status;/*做出应答信息给上位机*/ 1421.break; 1422.} 1423.} 1424.

1425.if(RevBuffer[2]==2)//返回信息 1426.cardtype=mifarepro;//MifarePro卡 1427.elseif(RevBuffer[2]==4)

1428.{cardtype=mifare1;//MifareOne卡 1429. 1430.}

1431.elseif(RevBuffer[2]==16)

1432.cardtype=mifarelight;//MifareLight卡 1433.else

1434.cardtype=unknowncard; 1435.

1436.RevBuffer[0]=3;

1437.RevBuffer[1]=status;/*做出应答信息给上位机*/ 1438.

1439.break; 1440.

1441.case3://防冲突读卡的系列号MLastSelectedSnr 1442.{status=M500PiccCascAnticoll(0,&RevBuffer[2]); 1443.status=0;

1444.if(status!=0) 1445.{/*反冲突失败*/ 1446.RevBuffer[0]=1;

1447.RevBuffer[1]=status;/*做出失败的应答信息给上位机*/ 1448.

1449.break; 1450.}

1451./*反冲突成功*/

1452.memcpy(MLastSelectedSnr,&RevBuffer[2],4);/*存储序列号*/

1453.RevBuffer[0]=5;

1454.RevBuffer[1]=status;/*做出成功的应答信息给上位机*/ 1455. 1456.}

1457.break; 1458.

1459.case4://选择卡SelectCard

1460.status=M500PiccCascSelect(MLastSelectedSnr,&RevBuffer[2]); 1461.

1462.if(status!=MI_OK) 1463.{

1464.RevBuffer[0]=1;

1465.RevBuffer[1]=status;/*做出失败的应答信息给上位机*/ 1466.break; 1467.}

1468.RevBuffer[0]=3;

1469.RevBuffer[1]=status;/*做出成功的应答信息给上位机*/ 1470.

1471.break;

1472.case5://KeyloadingintotheMFRC500'sEEPROM 1473.//校验卡密码(E2)

1474.status=M500PiccAuthE2(RevBuffer[1],MLastSelectedSnr,RevBuffer[2],RevBuffer[3]);

1475.RevBuffer[0]=1;/*入口参数?AUTH_MODE:A/B卡型号?SNR:卡序列号?KEYNR:密钥所在EE扇区数?BLOCK:密钥所 在卡数据块*/

1476.RevBuffer[1]=status; 1477.break;

1478.case6://KeyloadingintotheMFRC500'sEEPROM 1479.//下载密码(E2)

1480.status=M500PcdLoadKeyE2(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);

1481.RevBuffer[0]=1;

1482.RevBuffer[1]=status; 1483.break;

1484.case7://AuthenticationwithdirectkeyloadingfromtheuC 1485.//直接校验密码

1486.memcpy(&RevBuffer[9],&RevBuffer[3],6);

1487.M500HostCodeKey(&RevBuffer[9],&RevBuffer[3]);

1488.status=M500PiccAuthKey(RevBuffer[1],MLastSelectedSnr,&RevBuffer[3],RevBuffer[2]);

1489.RevBuffer[0]=1;/*入口参数?AUTH_MODE:A/B卡型号?SNR:卡序列号?KEYNR:密钥所在RAM地址?BLOCK:密钥所在 卡数据块*/

1490.RevBuffer[1]=status; 1491.break;

1492.case8://Readthemifarecard 1493.//读卡

1494.status=M500PiccRead(RevBuffer[1],&RevBuffer[2]); 1495.if(status==0) 1496.{

1497.if(cardtype==mifare1||cardtype==mifarepro)

1498.RevBuffer[0]=17;/*卡类型决定一次能读出的数据个数*/ 1499.elseif(cardtype==1)

1500.RevBuffer[0]=9;/*一次读出9个*/ 1501.else

1502.RevBuffer[0]=16;/*一次读出16个?MIFARE1?*/ 1503.} 1504.else 1505.{

1506.RevBuffer[0]=1; 1507.}

1508.RevBuffer[1]=status; 1509.break;

1510.case9://Writethemifarecard 1511.//写卡下载密码

1512.status=M500PiccWrite(RevBuffer[1],&RevBuffer[2]); 1513.RevBuffer[0]=1;

1514.RevBuffer[1]=status; 1515.break;

1516.case10://写卡改变卡内EEROM中数据块中的内容

1517.status=M500PiccValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3],RevBuffer[7]);

1518.RevBuffer[0]=1;/*入口参数?三种命令?自增?自减?改变??卡块地址?要写入的值?卡块地址*/ 1519.RevBuffer[1]=status; 1520.break;

1521.case12://参数设置

1522.RevBuffer[0]=1;//contact 1523.RevBuffer[1]=0; 1524.break; 1525.} 1526.} 1527.

1528.///////////////////////////////////////////////////////////////////////

1529.//主函数

1530.///////////////////////////////////////////////////////////////

////////

1531.voidmain(void) 1532.{

1533.init(); 1534.while(1) 1535.{

1536.if(CmdValid) 1537.{

1538.CmdValid=FALSE;

1539.cmd_execution();//进入IC卡处理程序 1540.CALL_isr_UART(); 1541.} 1542.} 1543.}

本文来源:https://www.bwwdw.com/article/qu9o.html

Top