⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.c

📁 应用案例
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
#include <Mfreg500.h>
#include <M500A.h>
#include <string.h>

extern void delay_50us(unsigned char time);
// reset struct
#define ResetInfo(info)                  \
            info.nBytesToSend   = 0;     \
			info.nBytesSent		= 0;     \
            info.nBytesReceived = 0;     \
            info.nBitsReceived  = 0;     \
			info.irqSource		= 0;	 \
            info.collPos        = 0;	 


// struct definition for a communication channel
typedef struct 
         {
            unsigned char  nBytesToSend;  // how many bytes to send
			unsigned char  nBytesSent;    // how many bytes sent
            unsigned char  nBytesReceived;// how many bytes received
            unsigned int   nBitsReceived; // how many bits received
			unsigned char  irqSource;     //
            unsigned char  collPos;       // at which position occured a collision

         } MfCmdInfo;


static   unsigned char idata MFIFOLength = DEF_FIFO_LENGTH; // actual FIFO length

         // send buffer 
static   volatile unsigned char MSndBuffer[SND_BUF_LEN];
         // receive buffer 
static   volatile unsigned char MRcvBuffer[RCV_BUF_LEN];
         // info struct  
static   volatile MfCmdInfo     MInfo;      

extern  void WriteIO(unsigned char add,unsigned char value);
extern  unsigned char ReadIO(unsigned char add);


char SetBitMask(unsigned char reg,unsigned char mask) // 
{
   char idata tmp = 0x0;

   tmp = ReadIO(reg) | mask;
   WriteIO(reg,tmp); 
   return 0x0;
}

char ClearBitMask(unsigned char reg,unsigned char mask) 
{
   char idata tmp = 0x0;

   tmp = ReadIO(reg) & ~mask;
   WriteIO(reg,tmp);  // clear bit mask
   return 0x0;
}


void FlushFIFO(void)
{  
   SetBitMask(RegControl,0x01);
}


void RC500Config(void)
{

	 while ((ReadIO(RegCommand) & 0x3F) == 0x3F);	  // 接口初始化检查
            
	 WriteIO(RegPage,0x80); 
	 while ((ReadIO(RegCommand) & 0x3F) == 0x3F);

     WriteIO(RegPage,0x00); 						 // 线性地址模式
     WriteIO(RegClockQControl,0x00);
     WriteIO(RegClockQControl,0x40);
     delay_50us(2); 
     ClearBitMask(RegClockQControl,0x40); 
     WriteIO(RegBitPhase,0xaa);                      
	 WriteIO(RegRxThreshold,0xDF);   			
     WriteIO(RegRxControl2,0x01);		
	 WriteIO(RegRxWait,0x05);		 		
     WriteIO(RegFIFOLevel,0x05);
     WriteIO(RegTimerControl,0x00); 
	 WriteIO(RegTimerClock,0x10);   
	 WriteIO(RegTimerReload,0x32);  
	 WriteIO(RegInterruptEn,0x7F); 
  	 ClearBitMask(RegTxControl,0x03);  
     delay_50us(20);                    
     SetBitMask(RegTxControl,0x03);    

}


char  RC500Cmd(unsigned char cmd,
               volatile unsigned char* send, 
               volatile unsigned char* rcv,
               volatile MfCmdInfo *info)
{     
   char    idata       status 	 = MI_OK;

   unsigned char 	   irqBits;
   unsigned char 	   lastBits;
   unsigned char 	   irqMask;            
   unsigned char 	   nbytes;
   unsigned char 	   cnt;
   unsigned char   	   tmpStatus ;

   unsigned char 	   irqEn     = 0x00;
   unsigned char       waitFor   = 0x00;
   unsigned char       TimeOut   = 0x00;


   WriteIO(RegInterruptEn,0x7F); 
   WriteIO(RegInterruptRq,0x7F); 
   WriteIO(RegCommand,PCD_IDLE); 

   FlushFIFO();           

   switch(cmd)
   {
      case PCD_IDLE:                   // nothing else required
         irqEn = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:                // LoAlert and TxIRq
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:                 // HiAlert, LoAlert and IdleIRq
         irqEn = 0x07;
         waitFor = 0x04;
         break;
      case PCD_LOADCONFIG:             // IdleIRq
      case PCD_LOADKEYE2:              // IdleIRq
      case PCD_AUTHENT1:               // IdleIRq
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_CALCCRC:                // LoAlert and TxIRq
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_AUTHENT2:               // IdleIRq
         irqEn = 0x04;
         waitFor = 0x04;
         break;
      case PCD_RECEIVE:                // HiAlert and IdleIRq
         info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
         irqEn = 0x06;
         waitFor = 0x04;
         break;
      case PCD_LOADKEY:                // IdleIRq
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSMIT:               // LoAlert and IdleIRq
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSCEIVE:             // TxIrq, RxIrq, IdleIRq and LoAlert
    	 info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
         irqEn = 0x3D;
         waitFor = 0x04;
         break;
      default:
         status = MI_UNKNOWN_COMMAND;
   }        
   if (status == MI_OK)
   {
      irqEn |= 0x20;
      waitFor |= 0x20;                            
      WriteIO(RegInterruptEn,irqEn | 0x80);  		
	  SetBitMask(RegControl,0x02);           
	  	
      WriteIO(RegCommand,cmd);               
      while (!(info->irqSource & waitFor || TimeOut)) 
      {                                             
         while( ReadIO(RegPrimaryStatus) & 0x08)   
          {			
             irqMask = ReadIO(RegInterruptEn); 
             irqBits = ReadIO(RegInterruptRq) & irqMask;
             info->irqSource |= irqBits; 
             if (irqBits & 0x01)    
              {
                 nbytes = MFIFOLength - ReadIO(RegFIFOLength);
                 if ((info->nBytesToSend - info->nBytesSent) <= nbytes)
                  {
                    nbytes = info->nBytesToSend - info->nBytesSent;
                    WriteIO(RegInterruptEn,0x01);
                  }
                 for ( cnt = 0;cnt < nbytes;cnt++)
                  {
                    WriteIO(RegFIFOData,send[info->nBytesSent]);
                    info->nBytesSent++;
                  }
                  WriteIO(RegInterruptRq,0x01); 
              } 
             if (irqBits & 0x10)     
              {
                 WriteIO(RegInterruptRq,0x10);    
                 WriteIO(RegInterruptEn,0x82);   
                 if (cmd == PICC_ANTICOLL1)     
                  {                       
                     WriteIO(RegChannelRedundancy,0x02);   
                  }    
              }
             if (irqBits & 0x0E) 
              {
                nbytes = ReadIO(RegFIFOLength);
                for ( cnt = 0; cnt < nbytes; cnt++)               
                  {
                    rcv[info->nBytesReceived] = ReadIO(RegFIFOData);
                    info->nBytesReceived++;
                  }
                WriteIO(RegInterruptRq,0x0A & irqBits);  
              }   			   
             if (irqBits & 0x04)     				
              {
			  	WriteIO(RegInterruptEn,0x20);     	
				WriteIO(RegInterruptRq,0x20); 		
                irqBits &= ~0x20;
			    info->irqSource &= ~0x20; 	   
                WriteIO(RegInterruptRq,0x04); 
              }
      		 if (irqBits & 0x20)        
         	  {
          		WriteIO(RegInterruptRq,0x20); 
          		status = MI_NOTAGERR;     
          		TimeOut = 1;						 
          		break;                    
         	  }
		  }
      }
      WriteIO(RegInterruptEn,0x7F);       
      WriteIO(RegInterruptRq,0x7F);        
      SetBitMask(RegControl,0x04);          

      WriteIO(RegCommand,PCD_IDLE);        

      if (!(info->irqSource & waitFor))   
      {                                
         status = MI_ACCESSTIMEOUT;
      }
      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;
      }
   }
   return status;
}     
          

char PcdReadE2(unsigned int startaddr,
               unsigned char length,
               unsigned char* _data)
{
   char status = MI_OK;
     ResetInfo(MInfo);   
     MSndBuffer[0] = startaddr & 0xFF;
     MSndBuffer[1] = (startaddr >> 8) & 0xFF;
     MSndBuffer[2] = length;
     MInfo.nBytesToSend   = 3;
     status = RC500Cmd(PCD_READE2,
                         MSndBuffer,
                         MRcvBuffer,
                         &MInfo);
    if (status == MI_OK)
    {
       memcpy(_data,MRcvBuffer,length);
    }
    else   
    {
       _data[0] = 0;
    }
    return status ;
} 


char CardRequest(unsigned char req_code, 
                   unsigned char *atq)    
{
   char idata status = MI_OK;

   WriteIO(RegChannelRedundancy,0x03); 
   ClearBitMask(RegControl,0x08);     
   WriteIO(RegBitFraming,0x07);       
   SetBitMask(RegTxControl,0x03);   
   
   ResetInfo(MInfo);   
   MSndBuffer[0] = req_code;
   MInfo.nBytesToSend   = 1;   
   status = RC500Cmd(PCD_TRANSCEIVE,
                      MSndBuffer,
                      MRcvBuffer,
                      &MInfo);
  
   if (status)     
   {
      *atq = 0;
   } 
   else 
   {
      if (MInfo.nBitsReceived != 16) 
      {
         *atq = 0;
         status = MI_BITCOUNTERR;
      } 
      else 
      {
         status = MI_OK;
         memcpy(atq,MRcvBuffer,2);
      }
   }
   return status; 
}


char ReadCardNum (unsigned char bcnt,
                  unsigned char *snr)    
{
   char idata    status = MI_OK;
   char idata    snr_in[4];    
   char 		 nbytes = 0;
   char 		 nbits = 0;
   char 		 complete = 0;
   char 		 i       = 0;		 
   char 		 byteOffset = 0;
   unsigned char  snr_crc;
   unsigned char  snr_check;
   unsigned char dummyShift1;     
   unsigned char dummyShift2;        

   memcpy(snr_in,snr,4);   
   
   WriteIO(RegDecoderControl,0x28);  
   ClearBitMask(RegControl,0x08);    
      
   complete = 0;
   bcnt = 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)
         {       
            WriteIO(RegBitFraming,nbits); 
         }
      } 
      else
      {
         nbytes = bcnt / 8; 
      }

      MSndBuffer[0] = 0x93;
      MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; 
               
      for (i = 0; i < nbytes; i++)  
      {
         MSndBuffer[i + 2] = snr_in[i];
      }
      MInfo.nBytesToSend   = 2 + nbytes;   
 
      status = RC500Cmd(PCD_TRANSCEIVE,
                         MSndBuffer,
                         MRcvBuffer,
                         &MInfo);
      if (nbits == 7)
      {
         dummyShift1 = 0x00;
         for (i = 0; i < MInfo.nBytesReceived; i++)
         {
            dummyShift2 = MRcvBuffer[i];
            MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[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] | MRcvBuffer[0];
                byteOffset = 1;
            }

            for ( i =0; i < (4 - nbytes); i++)     
            {
               snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
            }
  
            if (status != MI_COLLERR ) 
            {
               snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
               snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
               if (snr_crc != snr_check)
               {
                  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;  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -