www.pudn.com > RC500.rar > main.c


/**************************************************************************** 
* File :  main.c                                                            * 
* COPYRIGHT BY HUOYAN LTD.COMPANY                                           * 
* Version:      V5.2                                       			        * 
* Created:      18.11.2002                                                  * 
* Last Change:  8.Jan.2005                                                  * 
* Author:       NIL                                                         * 
* Compiler:     KEIL C51 V7.10                                              * 
* Description:  AT89S52-Firmware for MFRC500 Demo Serial Reader             * 
*                                                                           * 
****************************************************************************/ 
#define __SRC 
#include "main.h" 
#undef  __SRC 
 
#include  
#include  
#include  
#include "intrins.h" 
#include "at89c5131.h" 
#include "Mfreg500.h" 
#include "M500a.h" 
 
 
#define uchar	unsigned char 
#define uint unsigned int 
//#define DataPort P0				// 数据端口 
 
 
//pin define  mcu控制管脚定义 
      
sbit RC500RST   =   P1_1;		//由高变低时复位RC500 
sbit RC500CS=P2_7; 
sbit CARD_LED=P3_5; 
sbit SPEAKER    =   P1^3; 		   
 
bit bcard; 
 
/////////////////////////////////////////////////////////////////////// 
// 主函数 
/////////////////////////////////////////////////////////////////////// 
void main(void) 
{ 	//设置变量 
    uchar baud; 
   
 
    InitSystem();       //初始化系统	   
	// bcard=0; 
     
   	delay_10ms(5);					 
    while (1) 
    { 	 
	 
        // KeyPress();	处理按键 
   		delay_10ms(5);    
		//检查串口命令标志	 
 	    if (bCmd)    
	    {	 
		      
		    bCmd = FALSE;     //清零命令标志以便接收下一个命令 
			if(RevBuffer[0]==0x10)	    //测试蜂鸣器 
		    { 
		    	RevBuffer[2]=RevBuffer[1];    //蜂鸣时间存到RevBuffer[2] 
	  	    	cmd_ok();               //发送测试结果01 00给上位机 
		    	TI=1;		                  //准备发给上位机数据 
		    	SPEAKER=1;              //开蜂鸣器和指示灯 
		        CARD_LED=ON; 
				delay_10ms(RevBuffer[2]);    //延时 
		    	SPEAKER=0; 
                CARD_LED=OFF;               
 			     
		    } 
	    	else if(RevBuffer[0]==0x11)   //串口参数设置,设置通讯波特率 
	    	{ 
    			switch(RevBuffer[1])      
    			{ 
    				case 0: 
	    				baud=BAUD_9600; 
	    				break; 
	    			case 1: 
	    				baud=BAUD_14400; 
		    			break; 
	    			case 2: 
	    				baud=BAUD_19200; 
	    				break; 
	    			case 3: 
	    				baud=BAUD_28800; 
	    				break; 
	    			case 4: 
	    				baud=BAUD_38400; 
	    				break; 
	    			case 5: 
	    				baud=BAUD_57600; 
	    				break; 
	    			case 6: 
	    				baud=BAUD_115200; 
	    				break; 
	    			default: 
	    				baud=BAUD_19200; 
	    				break; 
	    		}				 
	    		cmd_ok();	        //发送测试结果01 00给上位机 
	    		TI=1;                     
	    		delay_10ms(5);			//延时设置波特率  
	    		TR1   = 0; 
	    		TH1   = baud; 
	    		TL1   = TH1; 
	    		delay_10ms(2); 
	    		TR1   = TRUE; 
	    	} 
	    	    	 
       		else 
    		{ 
     			uart_process();        // 进入串口处理程序	 
    			TI=1;                 //处理完准备发送结果给上位机  
    		} 
	 
					                 		  			 
	 			 
			 } 
		 
	 } 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 系统初始化 
/////////////////////////////////////////////////////////////////////// 
void InitSystem(void) 
{  
    RC500CS=0;	            	//选中RC500 
	RC500RST=0;	               //复位 
 
	ET2 = FALSE; 	              // T/C2关中断 
	T2CON = 0x04;		      //TR2=1,设为TIMER2,auto reload  
    PCON = 0x80;               
    SCON = 0x70;              // SMOD = 1;   
    TMOD = 0x21;              //TMOD = 0x22; 
 
	TH1   = BAUD_19200;       //默认波特率 
	TL1   = TH1; 
	TR1   = TRUE;             // 以T1作为波特率发生器 
     
	ET1=FALSE; 
	IT0 =TRUE;    			// Config ext0 as edge trigger for RC500 
    EX0 =TRUE; 			// Enable ext0 interrupt for RC500 
    EA = TRUE;			// Enable all interrupts 
	TR2=FALSE;                   //Close T2 
	IP=0x10;			// 设串口中断高优先级 
 	ES = TRUE;               //打开串口 
 
	bCmd=FALSE;         //初始化为0,没有收到命令 
					 
	beep(1);          //开机喇叭和指示灯测试 
    splash(1); 
 	MfConfig();			//配置RC500     
    
   
} 
 
/////////////////////////////////////////////////////////////////////// 
// 串口接收和发送中断 
//数据包格式:数据包长度L(1byte)+命令字C(1byte)+数据包D(L-1 bytes) 
//其中数据包长度是从命令字开始算起的。 
/////////////////////////////////////////////////////////////////////// 
void Uart_Int(void) interrupt 4 using 1 
{ 
    uchar len, i; 
  	uint j=0; 
  
  	if(RI)        //收到数据 
	{	 
		len=SBUF;  //第一个字节是数据包的长度 
		RI=0;	   //清零RI以便接收下一个 
		for(i=0;i1000) 
				{ 
				    break; 
				} 
			} 
			if(j<1000) 
			{ 
				RevBuffer[i]=SBUF;     
				RI=0; 
				j=0; 
			} 
			else 
			{ 
			    break; 
			} 
		} 
		if(i==len) 
		{ 
			REN=0;            // 清零接收位 
			bCmd=TRUE;       //接收完毕,收到命令有效,置位1 
		} 
	} 
	else if(!RI && TI)   //发送-RI=0,TI=1 
	{ 
		TI=0; 
		len=RevBuffer[0];    //发送的第一个字节是包的长度 
		for(i=0;iirqSource = 0x00; 
    switch(cmd) 
    { 
        case PCD_IDLE:                 
            irqEn = 0x00; 
            waitFor = 0x00; 
            break; 
        case PCD_WRITEE2:             
            irqEn = 0x11; 
            waitFor = 0x10; 
            break; 
        case PCD_READE2:      
            irqEn = 0x07; 
            waitFor = 0x04; 
            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:      
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); 
            irqEn = 0x06; 
            waitFor = 0x04; 
            break; 
        case PCD_LOADKEY:  
            irqEn = 0x05; 
            waitFor = 0x04; 
            break; 
        case PCD_TRANSMIT:  
            irqEn = 0x05; 
            waitFor = 0x04; 
            break; 
        case PCD_TRANSCEIVE:  
	        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--))); 
        WriteIO(RegInterruptEn,0x7F);          
        WriteIO(RegInterruptRq,0x7F);           
        SetBitMask(RegControl,0x04);           
        WriteIO(RegCommand,PCD_IDLE);          
        if (!(MpIsrInfo->irqSource & waitFor))    
        {                                
            status = MI_ACCESSTIMEOUT; 
        } 
        else 
        { 
            status = MpIsrInfo->status;            
        } 
        if (status == MI_OK)                     
        { 
            if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17)) 
            { 
                if (tmpStatus & 0x01) 
                { 
                    info->collPos = ReadIO(RegCollPos); 
                    status = MI_COLLERR; 
                } 
                else 
                { 
                    info->collPos = 0; 
                    if (tmpStatus & 0x02)   
                    { 
                        status = MI_PARITYERR; 
                    } 
                } 
                if (tmpStatus & 0x04)    
                { 
                    status = MI_FRAMINGERR; 
                } 
                if (tmpStatus & 0x10)    
                { 
                    FlushFIFO(); 
                    status = MI_OVFLERR; 
                } 
 	            if (tmpStatus & 0x08)  
	            { 
                    status = MI_CRCERR; 
	            }	 
                if (status == MI_OK) 
                    status = MI_NY_IMPLEMENTED; 
            } 
            if (cmd == PCD_TRANSCEIVE) 
            { 
                lastBits = ReadIO(RegSecondaryStatus) & 0x07; 
                if (lastBits) 
                    info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits; 
                else 
                    info->nBitsReceived += info->nBytesReceived * 8; 
            } 
        } 
        else 
        { 
            info->collPos = 0x00; 
        } 
    } 
    MpIsrInfo = 0;          
    MpIsrOut  = 0; 
    return status; 
}    
 
/////////////////////////////////////////////////////////////////////// 
// 置一个bit 
/////////////////////////////////////////////////////////////////////// 
char SetBitMask(uchar reg,uchar mask)   
{ 
    char idata tmp = 0x00; 
 
    tmp = ReadIO(reg); 
    WriteIO(reg,tmp | mask);  // set bit mask 
    return 0x00; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 清一个bit 
/////////////////////////////////////////////////////////////////////// 
char ClearBitMask(uchar reg,uchar mask)   
{ 
    char idata tmp = 0x00; 
 
    tmp = ReadIO(reg); 
    WriteIO(reg,tmp & ~mask);  // clear bit mask 
    return 0x00; 
} 
 
/////////////////////////////////////////////////////////////////////// 
//清除FIFO 
/////////////////////////////////////////////////////////////////////// 
void FlushFIFO(void) 
{   
    SetBitMask(RegControl,0x01); 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Value format operations for Mifare Standard card ICs 
// 块值操作:加.减 
/////////////////////////////////////////////////////////////////////// 
char M500PiccValue(uchar dd_mode,  
                   uchar addr,  
                   uchar *value, 
                   uchar trans_addr) 
{ 
    char status = MI_OK; 
 
    M500PcdSetTmo(1);  
    ResetInfo(MInfo);    
    SerBuffer[0] = dd_mode;       
    SerBuffer[1] = addr; 
    MInfo.nBytesToSend = 2; 
    status = M500PcdCmd(PCD_TRANSCEIVE, 
                       SerBuffer, 
                       &MInfo); 
 
    if (status != MI_NOTAGERR)    
    { 
        if (MInfo.nBitsReceived != 4)   
        { 
            status = MI_BITCOUNTERR; 
        } 
        else                     
        { 
            SerBuffer[0] &= 0x0f;  
            switch(SerBuffer[0]) 
            { 
                case 0x00:  
                    status = MI_NOTAUTHERR; 
                    break; 
                case 0x0a: 
                    status = MI_OK; 
                    break; 
                case 0x01: 
                    status = MI_VALERR; 
                    break; 
                default: 
                    status = MI_CODEERR; 
                    break; 
            } 
        } 
    } 
 
    if ( status == MI_OK) 
    { 
        M500PcdSetTmo(3);     
        ResetInfo(MInfo);    
        memcpy(SerBuffer,value,4); 
        MInfo.nBytesToSend   = 4; 
        status = M500PcdCmd(PCD_TRANSCEIVE, 
                            SerBuffer, 
                            &MInfo); 
         
        if (status == MI_OK)     
        { 
            if (MInfo.nBitsReceived != 4)    
            { 
                status = MI_BITCOUNTERR; 
            } 
            else                     
            { 
                SerBuffer[0] &= 0x0f;  
                switch(SerBuffer[0]) 
                { 
                    case 0x00:  
                        status = MI_NOTAUTHERR; 
                        break; 
                    case 0x01: 
                        status = MI_VALERR; 
                        break; 
                    default: 
                        status = MI_CODEERR; 
                        break; 
                } 
            } 
        }         
        else 
        { 
            if (status == MI_NOTAGERR ) 
                status = MI_OK;   
        } 
    } 
    if (status == MI_OK) 
    { 
        ResetInfo(MInfo);    
        SerBuffer[0] = PICC_TRANSFER;       
        SerBuffer[1] = trans_addr; 
        MInfo.nBytesToSend   = 2; 
        status = M500PcdCmd(PCD_TRANSCEIVE, 
                            SerBuffer, 
                            &MInfo); 
        if (status != MI_NOTAGERR)   
        { 
            if (MInfo.nBitsReceived != 4) 
            { 
                status = MI_BITCOUNTERR; 
            } 
            else                    
            { 
                SerBuffer[0] &= 0x0f;  
                switch(SerBuffer[0]) 
                { 
                    case 0x00:  
                        status = MI_NOTAUTHERR; 
                        break; 
                    case 0x0a: 
                        status = MI_OK; 
                        break; 
                    case 0x01: 
                        status = MI_VALERR; 
                        break; 
                    default: 
                        status = MI_CODEERR; 
                        break; 
                } 
            } 
        }         
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
//HALT the card 
// 终止卡的操作 
/////////////////////////////////////////////////////////////////////// 
char M500PiccHalt(void) 
{ 
    char idata status = MI_CODEERR; 
 
    // ************* Cmd Sequence **********************************  
    ResetInfo(MInfo);    
    SerBuffer[0] = PICC_HALT ;      // Halt command code 
    SerBuffer[1] = 0x00;            // dummy address 
    MInfo.nBytesToSend = 2; 
    status = M500PcdCmd(PCD_TRANSCEIVE, 
                       SerBuffer, 
                       &MInfo);    
    if (status) 
    { 
        // timeout error ==> no NAK received ==> OK 
        if (status == MI_NOTAGERR || status == MI_ACCESSTIMEOUT) 
        { 
            status = MI_OK; 
        } 
    } 
    //reset command register - no response from tag 
    WriteIO(RegCommand,PCD_IDLE); 
    return status;  
} 
 
/////////////////////////////////////////////////////////////////////// 
// Reset the MF RC500  
/////////////////////////////////////////////////////////////////////// 
char M500PcdReset(void) 
{ 
    char idata status = MI_OK; 
    unsigned int idata timecnt=0; 
     
    RC500RST = 0;   
    delay_1ms(25);  
    RC500RST = 1;   
    delay_50us(200);  
    RC500RST = 0;   
    delay_50us(50); 
    timecnt=1000; 
    while ((ReadIO(RegCommand) & 0x3F) && timecnt--); 
    if(!timecnt) 
    { 
        status = MI_RESETERR; 
    } 
    if (status == MI_OK) 
    { 
        //WriteIO(RegPage,0x80); 
        if (ReadIO(RegCommand) != 0x00) 
        {                            
            status = MI_INTERFACEERR; 
        } 
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Configures the MF RC500  配置RC500内部寄存器函数 
/////////////////////////////////////////////////////////////////////// 
char M500PcdConfig(void) 
{ 
    char idata status; 
 
    if ((status = M500PcdReset()) == MI_OK) 
    { 
        WriteIO(RegClockQControl,0x00); 
        WriteIO(RegClockQControl,0x40); 
        delay_50us(2);   
        ClearBitMask(RegClockQControl,0x40); 
        WriteIO(RegBitPhase,0xAD);       
        WriteIO(RegRxThreshold,0xFF);    
        WriteIO(RegRxControl2,0x01); 
        WriteIO(RegFIFOLevel,0x1A); 
        WriteIO(RegTimerControl,0x02); 
        WriteIO(RegIRqPinConfig,0x03);  
        M500PcdRfReset(1);                
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////// 
// Key loading into the MF RC500's EEPROM 
///////////////////////////////////////////////////////////////		             
char M500PcdLoadKeyE2(uchar key_type, 
                       uchar sector, 
                       uchar *uncoded_keys) 
{ 
    signed char status = MI_OK; 
    unsigned int e2addr = 0x80 + sector * 0x18; 
    uchar coded_keys[12]; 
 
    if (key_type == PICC_AUTHENT1B) 
    { 
        e2addr += 12;           // key B offset 
    } 
    if ((status = M500HostCodeKey(uncoded_keys,coded_keys)) == MI_OK) 
    { 
        status = PcdWriteE2(e2addr,12,coded_keys); 
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Write the MF RC500's EEPROM 
// 向RC500 EEPROM写数据 
/////////////////////////////////////////////////////////////////////// 
char PcdWriteE2(unsigned int startaddr, 
                uchar length, 
                uchar* _data) 
{ 
    char status = MI_OK; 
    ResetInfo(MInfo); 
    SerBuffer[0] = startaddr & 0xFF; 
    SerBuffer[1] = (startaddr >> 8) & 0xFF; 
    memcpy(SerBuffer + 2,_data,length); 
 
    MInfo.nBytesToSend   = length + 2; 
          
    status = M500PcdCmd(PCD_WRITEE2, 
                       SerBuffer, 
                       &MInfo);  
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Select Command defined in ISO14443(MIFARE) 
/////////////////////////////////////////////////////////////////////// 
char M500PcdMfOutSelect(uchar type) 
{ 
    WriteIO(RegMfOutSelect,type&0x7); 
    return MI_OK; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Request Command defined in ISO14443(MIFARE) 
// Request 
// 寻卡 
/////////////////////////////////////////////////////////////////////// 
char M500PiccCommonRequest(uchar req_code,uchar *atq) 
{ 
    char idata status = MI_OK; 
	 
    M500PcdSetTmo(3); 
    WriteIO(RegChannelRedundancy,0x03); 
    ClearBitMask(RegControl,0x08); 
    WriteIO(RegBitFraming,0x07);      
    SetBitMask(RegTxControl,0x03);      
    ResetInfo(MInfo); 
    SerBuffer[0] = req_code; 
    MInfo.nBytesToSend = 1;    
     
    status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
    if (status)      
    { 
        *atq = 0; 
    }  
    else  
    { 
        if (MInfo.nBitsReceived != 16)  
        { 
            *atq = 0; 
            status = MI_BITCOUNTERR; 
        }  
        else  
        { 
            status = MI_OK; 
            memcpy(atq,SerBuffer,2); 
        } 
    } 
    return status;  
} 
 
/////////////////////////////////////////////////////////////////// 
// Cascaded Anti-Collision Command defined in ISO14443(MIFARE) 
// 防冲突 读卡的系列号 CardSnr 
/////////////////////////////////////////////////////////////////// 
char M500PiccCascAnticoll (uchar bcnt,uchar *snr)        
{ 
    char idata status = MI_OK; 
    char idata snr_in[4];     
    char idata nbytes = 0; 
    char idata nbits = 0; 
    char idata complete = 0; 
    char idata i        = 0; 
    char idata byteOffset = 0; 
    uchar dummyShift1; 
    uchar dummyShift2; 
     
    M500PcdSetTmo(106); 
    memcpy(snr_in,snr,4);    
    
    WriteIO(RegDecoderControl,0x28);  
    ClearBitMask(RegControl,0x08);    
    complete = 0; 
    while (!complete && (status == MI_OK) ) 
    { 
        ResetInfo(MInfo);            
        WriteIO(RegChannelRedundancy,0x03); 
        nbits = bcnt % 8; 
        if(nbits) 
        { 
            WriteIO(RegBitFraming,nbits << 4 | nbits); 
            nbytes = bcnt / 8 + 1;    
            if (nbits == 7) 
            { 
                MInfo.cmd = PICC_ANTICOLL1; 
                WriteIO(RegBitFraming,nbits);  
            } 
        }   
        else 
        { 
            nbytes = bcnt / 8; 
        } 
        SerBuffer[0] = 0x93; 
        SerBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; 
                
        for (i = 0; i < nbytes; i++)   
        { 
            SerBuffer[i + 2] = snr_in[i]; 
        } 
        MInfo.nBytesToSend   = 2 + nbytes;    
  
        status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
        if (nbits == 7) 
        { 
            dummyShift1 = 0x00; 
            for (i = 0; i < MInfo.nBytesReceived; i++) 
            { 
                dummyShift2 = SerBuffer[i]; 
                SerBuffer[i] = (dummyShift1 >> (i+1)) | (SerBuffer[i] << (7-i)); 
                dummyShift1 = dummyShift2; 
            } 
            MInfo.nBitsReceived -= MInfo.nBytesReceived;        
            if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9; 
        } 
        if ( status == MI_OK || status == MI_COLLERR)     
        { 
            if ( MInfo.nBitsReceived != (40 - bcnt) ) 
            { 
                status = MI_BITCOUNTERR;  
            }  
            else  
            { 
                byteOffset = 0; 
                if( nbits != 0 )  
                { 
                    snr_in[nbytes - 1] = snr_in[nbytes - 1] | SerBuffer[0]; 
                    byteOffset = 1; 
                } 
 
                for ( i =0; i < (4 - nbytes); i++)      
                { 
                    snr_in[nbytes + i] = SerBuffer[i + byteOffset]; 
                } 
   
                if (status != MI_COLLERR )  
                { 
                    dummyShift2 = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3]; 
                    dummyShift1 = SerBuffer[MInfo.nBytesReceived - 1]; 
                    if (dummyShift2 != dummyShift1) 
                    { 
                        status = MI_SERNRERR; 
                    }  
                    else    
                    { 
                        complete = 1; 
                    } 
                } 
                else                  
                { 
                    bcnt = bcnt + MInfo.collPos - nbits; 
                    status = MI_OK; 
                } 
            } 
        } 
    } 
    if (status == MI_OK) 
    { 
        memcpy(snr,snr_in,4); 
    } 
    else 
    { 
        memcpy(snr,"0000",4); 
    } 
    ClearBitMask(RegDecoderControl,0x20);  
    
    return status;   
} 
 
////////////////////////////////////////////////////////////////// 
// Cascaded Select command defined in ISO14443(MIFARE) 
// 选择卡 Select Card 
////////////////////////////////////////////////////////////////// 
char M500PiccCascSelect(uchar *snr,uchar *sak) 
{ 
    char idata status = MI_OK;  
  
    M500PcdSetTmo(106); 
	 
    WriteIO(RegChannelRedundancy,0x0F);  
    ClearBitMask(RegControl,0x08);     
    ResetInfo(MInfo);    
    SerBuffer[0] = 0x93; 
    SerBuffer[1] = 0x70;         
    
    memcpy(SerBuffer + 2,snr,4); 
    SerBuffer[6] = SerBuffer[2] ^ SerBuffer[3] ^ SerBuffer[4] ^ SerBuffer[5]; 
    MInfo.nBytesToSend   = 7; 
    status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
 
    *sak = 0;    
    if (status == MI_OK)   
    { 
        if (MInfo.nBitsReceived != 8)    
        { 
            status = MI_BITCOUNTERR; 
        } 
        else 
        { 
	        *sak = SerBuffer[0]; 
        }	 
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Key loading into the MF RC500's EEPROM 
// 校验卡密码(E2) 
/////////////////////////////////////////////////////////////////////// 
char M500PiccAuthE2( uchar auth_mode,uchar *snr,       
                     uchar keynr,uchar block)      
                                               
{ 
    char idata status = MI_OK; 
    unsigned int e2addr = 0x80 + keynr * 0x18; 
    uchar *e2addrbuf; 
     
    e2addrbuf = (uchar *)&e2addr; 
    if (auth_mode == PICC_AUTHENT1B) 
    { 
        e2addr += 12;  
    } 
    FlushFIFO();     
    ResetInfo(MInfo); 
 
    memcpy(SerBuffer,e2addrbuf,2);  
    SerBuffer[2] = SerBuffer[0];       
    SerBuffer[0] = SerBuffer[1];  
    SerBuffer[1] = SerBuffer[2]; 
    MInfo.nBytesToSend   = 2; 
    if ((status=M500PcdCmd(PCD_LOADKEYE2,SerBuffer,&MInfo)) == MI_OK) 
    {   
        status = M500PiccAuthState(auth_mode,snr,block);   
    } 
    return status; 
}                         
 
/////////////////////////////////////////////////////////////////////// 
// Authentication key coding 
/////////////////////////////////////////////////////////////////////// 
char M500HostCodeKey(  uchar *uncoded, uchar *coded)    
{ 
    char idata status = MI_OK; 
    uchar idata cnt = 0; 
    uchar idata ln  = 0;      
    uchar idata hn  = 0;       
    for (cnt = 0; cnt < 6; cnt++) 
    { 
        ln = uncoded[cnt] & 0x0F; 
        hn = uncoded[cnt] >> 4; 
        coded[cnt * 2 + 1] = (~ln << 4) | ln; 
        coded[cnt * 2 ] = (~hn << 4) | hn; 
    } 
    return MI_OK; 
} 
 
/////////////////////////////////////////////////////////////////////// 
//校验状态 
/////////////////////////////////////////////////////////////////////// 
char M500PiccAuthState( uchar auth_mode,uchar *snr,uchar block) 
{ 
    char idata status = MI_OK; 
    uchar idata i = 0; 
    
    status = ReadIO(RegErrorFlag);                                      
    if (status != MI_OK) 
    { 
        if (status & 0x40)            
        { 
            status = MI_KEYERR; 
        } 
        else 
        { 
            status = MI_AUTHERR;     
        } 
    } 
    else 
    { 
        SerBuffer[0] = auth_mode;     
 
        SerBuffer[1] = block;   
        memcpy(SerBuffer + 2,snr,4);  
        ResetInfo(MInfo); 
        MInfo.nBytesToSend = 6; 
        if ((status = M500PcdCmd(PCD_AUTHENT1,SerBuffer,&MInfo)) == MI_OK) 
        { 
            if (ReadIO(RegSecondaryStatus) & 0x07)  
            { 
                status = MI_BITCOUNTERR; 
            } 
            else 
            { 
                ResetInfo(MInfo); 
                MInfo.nBytesToSend = 0; 
                if ((status = M500PcdCmd(PCD_AUTHENT2, 
                                     SerBuffer, 
                                     &MInfo)) == MI_OK)  
                { 
                    if ( ReadIO(RegControl) & 0x08 )  
                    { 
                        status = MI_OK; 
                    } 
                    else 
                    { 
                        status = MI_AUTHERR; 
                    } 
                } 
            } 
        } 
    } 
    return status; 
} 
 
//////////////////////////////////////////////////////////////// 
// Read the mifare card 
// 读卡 
//////////////////////////////////////////////////////////////// 
char M500PiccRead(uchar addr,uchar *_data) 
{ 
    char idata status = MI_OK; 
    char idata tmp    = 0; 
 
    FlushFIFO();     
 
    M500PcdSetTmo(3);   
    WriteIO(RegChannelRedundancy,0x0F); 
    ResetInfo(MInfo);    
    SerBuffer[0] = PICC_READ;    
    SerBuffer[1] = addr; 
    MInfo.nBytesToSend   = 2;    
    status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
 
    if (status != MI_OK) 
    { 
        if (status != MI_NOTAGERR )  
        { 
            if (MInfo.nBitsReceived == 4)   
            { 
                SerBuffer[0] &= 0x0f;   
                if ((SerBuffer[0] & 0x0a) == 0) 
                { 
                    status = MI_NOTAUTHERR; 
                } 
                else 
                { 
                    status = MI_CODEERR; 
                } 
            } 
        } 
        memcpy(_data,"0000000000000000",16);  
    } 
    else                // Response Processing 
    { 
        if (MInfo.nBytesReceived != 16) 
        { 
            status = MI_BYTECOUNTERR; 
            memcpy(_data,"0000000000000000",16); 
        } 
        else 
        { 
            memcpy(_data,SerBuffer,16); 
        } 
    } 
    M500PcdSetTmo(1);              
    return status;  
} 
 
//////////////////////////////////////////////////////////////// 
// Write the mifare card 
// 写卡  下载密码 
//////////////////////////////////////////////////////////////// 
char M500PiccWrite( uchar addr,uchar *_data) 
{ 
    char idata status = MI_OK; 
     
    ResetInfo(MInfo);    
    SerBuffer[0] = PICC_WRITE;  
    SerBuffer[1] = addr;             
    MInfo.nBytesToSend   = 2; 
    status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
 
    if (status != MI_NOTAGERR)    
    { 
        if (MInfo.nBitsReceived != 4)   
        { 
            status = MI_BITCOUNTERR; 
        } 
        else                      
        { 
            SerBuffer[0] &= 0x0f;  
            if ((SerBuffer[0] & 0x0a) == 0) 
            { 
                status = MI_NOTAUTHERR;                    
            } 
            else 
            { 
                if (SerBuffer[0] == 0x0a) 
                { 
                    status = MI_OK; 
                } 
                else  
                { 
                    status = MI_CODEERR; 
                } 
            } 
        } 
    } 
 
    if ( status == MI_OK) 
    { 
        M500PcdSetTmo(3);     
 
        ResetInfo(MInfo);    
        memcpy(SerBuffer,_data,16); 
        MInfo.nBytesToSend   = 16; 
        status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
         
        if (status & 0x80)    
        { 
            status = MI_NOTAGERR; 
        } 
        else 
        { 
            if (MInfo.nBitsReceived != 4)  
            { 
                status = MI_BITCOUNTERR; 
            } 
            else                   
            { 
                SerBuffer[0] &= 0x0f;  
                if ((SerBuffer[0] & 0x0a) == 0) 
                { 
                    status = MI_WRITEERR; 
                } 
                else 
                { 
                    if (SerBuffer[0] == 0x0a) 
                    { 
                        status = MI_OK; 
                    } 
                    else  
                    { 
                        status = MI_CODEERR; 
                    } 
                }      
            } 
        }         
        M500PcdSetTmo(1);   
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Reset Rf Card 
/////////////////////////////////////////////////////////////////////// 
char M500PcdRfReset(uchar ms) 
{ 
    char idata status = MI_OK; 
	 
    if(ms) 
    { 
        ClearBitMask(RegTxControl,0x03);  
        delay_1ms(2);                 
        SetBitMask(RegTxControl,0x03);  
    } 
    else 
    { 
        ClearBitMask(RegTxControl,0x03);   
    } 
    return status; 
} 
 
#pragma noaregs 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 50us 
/////////////////////////////////////////////////////////////////////// 
void delay_50us(uchar _50us) 
{ 
  RCAP2LH = RCAP2_50us; 
  T2LH    = RCAP2_50us; 
  ET2 = 0; 	// Disable timer2 interrupt 
  T2CON = 0x04;	// 16-bit auto-reload, clear TF2, start timer 
   
  while (_50us--) 
  { 
	while (!TF2); 
	TF2 = FALSE; 
  } 
 
  TR2 = FALSE; 
 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 1ms 
/////////////////////////////////////////////////////////////////////// 
void delay_1ms(uchar _1ms) 
{ 
  RCAP2LH = RCAP2_1ms; 
  T2LH    = RCAP2_1ms; 
  ET2 = 0; 	// Disable timer2 interrupt 
  T2CON = 0x04;	// 16-bit auto-reload, clear TF2, start timer 
   
  while (_1ms--) 
  { 
	while (!TF2); 
	TF2 = FALSE; 
  } 
  TR2 = FALSE; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 10ms 
/////////////////////////////////////////////////////////////////////// 
void delay_10ms(uint _10ms) 
{ 
  RCAP2LH = RCAP2_10ms; 
  T2LH    = RCAP2_10ms; 
  ET2 = 0; 	// Disable timer2 interrupt 
  T2CON = 0x04;	// 16-bit auto-reload, clear TF2, start timer 
   
  while (_10ms--) 
  { 
	while (!TF2) 
	{ 
	  if (bCmd) 
	  { 
		TR2 = FALSE; 
		TF2 = FALSE; 
		return; 
	  } 
	} 
	TF2 = FALSE; 
  } 
  TR2 = FALSE; 
 
} 
 
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
void RC500ISR (void) interrupt 0 using 1     
{ 
    static uchar idata irqBits; 
    static uchar idata irqMask;             
    static uchar idata nbytes; 
    static uchar idata cnt; 
	 
    IE0 = 0; 	 
    WriteRawIO(0,0x80); 
    if (MpIsrInfo && MpIsrOut) 
    { 
        while( ReadRawIO(RegPrimaryStatus) & 0x08)  
        { 
            irqMask = ReadRawIO(RegInterruptEn); 
            irqBits = ReadRawIO(RegInterruptRq) & irqMask; 
            MpIsrInfo->irqSource |= irqBits;  
            if (irqBits & 0x01)    
            {   
                nbytes = 64 - ReadRawIO(RegFIFOLength); 
                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes) 
                { 
                    nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent; 
                    WriteRawIO(RegInterruptEn,0x01); 
                }    
                for ( cnt = 0;cnt < nbytes;cnt++) 
                { 
                    WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]); 
                    MpIsrInfo->nBytesSent++; 
                } 
                WriteRawIO(RegInterruptRq,0x01);   
            }       
            if (irqBits & 0x10)     
            { 
                WriteRawIO(RegInterruptRq,0x10);     
                WriteRawIO(RegInterruptEn,0x82);    
                if (MpIsrInfo->cmd == PICC_ANTICOLL1) 	 
	            {                                         
                    WriteIO(RegChannelRedundancy,0x02); 
                    WriteRawIO(0,0x80); 
	            }	 
            } 
            if (irqBits & 0x0E)  
            { 
                nbytes = ReadRawIO(RegFIFOLength); 
                for ( cnt = 0; cnt < nbytes; cnt++)                
                { 
                    MpIsrOut[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData); 
                    MpIsrInfo->nBytesReceived++; 
                } 
                WriteRawIO(RegInterruptRq,0x0A & irqBits);  
            }    
            if (irqBits & 0x04)  
            { 
                WriteRawIO(RegInterruptEn,0x20);  
                WriteRawIO(RegInterruptRq,0x20);  
                irqBits &= ~0x20;  
                MpIsrInfo->irqSource &= ~0x20; 
                WriteRawIO(RegInterruptRq,0x04); 
            } 
            if (irqBits & 0x20)      
            { 
                WriteRawIO(RegInterruptRq,0x20);  
                MpIsrInfo->status = MI_NOTAGERR;  
            } 
        } 
    } 
} 
 
 
 
/////////////////////////////////////////////////////////////////////// 
// MF RC500 Config 
/////////////////////////////////////////////////////////////////////// 
char MfConfig(void) 
{ 
	char status=MI_OK; 
	 
	M500PcdConfig(); 
	M500PcdMfOutSelect(2); 
	return status; 
} 
///////////////////////////////////////////////////////////////////////// 
//Beep(n);n为鸣叫的声音次数 
///////////////////////////////////////////////////////////////////////// 
void beep(uchar n) 
{ 
	uchar i; 
	for(i=0;i