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

📄 mfrc522.c

📁 MFRC522 单片机读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccRead(unsigned char addr, unsigned char idata *_data)
{
   char status = STATUS_SUCCESS;
   char tmp    = 0;
	unsigned char idata SerBuffer[16];	

   ResetInfo();
   SerBuffer[0] = MIFARE_READ;
   SerBuffer[1] = addr;
   MInfo.nBytesToSend   = 2;
   SetTimeOut(100);
   status = M522PcdCmd(JCMD_TRANSCEIVE,
                       SerBuffer);

   if (status != STATUS_SUCCESS)
   {
      if (status != STATUS_IO_TIMEOUT )     // no timeout occured
      {
         if (MInfo.nBitsReceived == 4)
         {
             SerBuffer[0] &= 0x0f;
             if ((SerBuffer[0] & 0x0a) == 0)
             {
                status = STATUS_AUTHENT_ERROR;
             }
             else
             {
                status = STATUS_INVALID_FORMAT;
             }
          }
      }
   }
   else   // Response Processing
   {
      if (MInfo.nBytesReceived != 16)
      {
         status = STATUS_ACCESS_DENIED;
      }
      else
      {
         memcopy(_data,SerBuffer,16);
      }
   }
   return status;
}

char MFCheckAck(char Status, unsigned char Rsponse)
{
	if(Status == STATUS_ACK_SUPPOSED)
	{
		if (MInfo.nBitsReceived != 4)
       	{
          	Status = STATUS_BITCOUNT_ERROR;
       	}
       	else
       	{
          	Rsponse &= 0x0f;
           	switch(Rsponse)
           	{
              	case 0x00:
                 	Status = STATUS_AUTHENT_ERROR;
                 	break;
              	case 0x0a:
                 	Status = STATUS_SUCCESS;
                 	break;
              	case 0x01:
                 	Status = STATUS_INVALID_FORMAT;
                 	break;
              	default:
                 	Status = STATUS_OTHER_ERROR;
                 	break;
           	}
       	}
	}
	return Status;
}

/****************************************************************************************
** 函数原型:    char PiccWrite(unsigned char addr, unsigned char idata *_data)
** 函数功能:    向指定的扇区写入16字节数据
** 入口参数:    unsigned char addr          ; 块号
**              unsigned char idata *_data  ; 写入的数据(16字节)
** 出口参数:    
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccWrite( unsigned char addr, unsigned char idata *_data)
{
    char status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[16];	

    ResetInfo();
    SerBuffer[0] = MIFARE_WRITE;
    SerBuffer[1] = addr;
    MInfo.nBytesToSend   = 2;
    SetTimeOut(200);
    status = M522PcdCmd(JCMD_TRANSCEIVE,
                        SerBuffer);

    status = MFCheckAck(status, SerBuffer[0]);

    if ( status == STATUS_SUCCESS)
    {

       SetTimeOut(50);

       ResetInfo();
       memcopy(SerBuffer,_data,16);
       MInfo.nBytesToSend   = 16;
       status = M522PcdCmd(JCMD_TRANSCEIVE,
                           SerBuffer);

       status = MFCheckAck(status, SerBuffer[0]);
    }
  	return status;
}

/****************************************************************************************
** 函数原型:    char PiccULWrite( unsigned char addr,unsigned char idata *_data)
** 函数功能:    向指定的块写入4字节数据(MF IC U1)
** 入口参数:    unsigned char addr          ; 块号
**              unsigned char idata *_data  ; 写入的数据(4字节)
** 出口参数:    
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccULWrite( unsigned char addr,unsigned char idata *_data)
{
	char status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[6];	

    ResetInfo();
    SerBuffer[0] = PICC_ULWRITE;
    SerBuffer[1] = addr;
	memcopy(&SerBuffer[2],_data,4);
    MInfo.nBytesToSend   = 6;
    
    SetTimeOut(200);
    status = M522PcdCmd(JCMD_TRANSCEIVE,SerBuffer);

	status = MFCheckAck(status, SerBuffer[0]);
	return status;
}
/****************************************************************************************
** 函数原型:    char PiccValue(unsigned char OperMode,unsigned char addr,
**                             unsigned char idata *value,unsigned char trans_addr)
** 函数功能:    值块操作函数(增、减或者传输)
** 入口参数:    unsigned char OperMode      ; 操作模式(增、减)
**              unsigned char addr          ; 块号
**              unsigned char idata *value  ; 操作值块的值
**              unsigned char trans_addr    ; 保存操作结果的块号
** 出口参数:    -
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccValue( unsigned char OperMode,unsigned char addr,
                unsigned char idata *value,unsigned char trans_addr)
{
   char status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[4];	

   ResetInfo();
   SerBuffer[0] = OperMode;
   SerBuffer[1] = addr;
   MInfo.nBytesToSend   = 2;
   SetTimeOut(200);
   status = M522PcdCmd(JCMD_TRANSCEIVE,
                       SerBuffer);

   status = MFCheckAck(status, SerBuffer[0]);

     if ( status == STATUS_SUCCESS)
     {
        SetTimeOut(100);
        ResetInfo();
        memcopy(SerBuffer,value,4);
        MInfo.nBytesToSend   = 4;
        status = M522PcdCmd(JCMD_TRANSCEIVE,
                            SerBuffer);

        if (status == STATUS_IO_TIMEOUT)
        {
            status = STATUS_SUCCESS;
        }
        else
        {
            status = STATUS_OTHER_ERROR;
        }
     }
     if ( status == STATUS_SUCCESS)
     {
        ResetInfo();
        SerBuffer[0] = MIFARE_TRANSFER;
        SerBuffer[1] = trans_addr;
        MInfo.nBytesToSend   = 2;
        status = M522PcdCmd(JCMD_TRANSCEIVE,
                            SerBuffer);

        status = MFCheckAck(status, SerBuffer[0]);
     }
   return status;
}

/****************************************************************************************
** 函数原型:    char PiccActivate(unsigned char br,unsigned char req_code,
**                                unsigned char idata *atq, unsigned char idata *sak, 
**                                unsigned char idata *uid, unsigned char idata *uid_len)
** 函数功能:    卡片激活
** 入口参数:    unsigned char req_code      ; 请求模式
** 出口参数:    unsigned char idata *atq    ; ATQ 2字节
                unsigned char idata *sak    ; SAK 
                unsigned char idata *uid    ; UID 
                unsigned char idata *uid_len    ; UID_Len
** 返 回 值:    执行结果
** 描   述:    组合函数
****************************************************************************************/
#if PICC_ACTIVATE_EN
char PiccActivate(unsigned char br,unsigned char req_code,
                          unsigned char idata *atq, 
                          unsigned char idata *sak, 
                          unsigned char idata *uid, 
                          unsigned char idata *uid_len)
{
//  unsigned char cascade_level;
  unsigned char sel_code;
  unsigned char uid_index;
  char status;
 // unsigned char cmdASEL;
  bit SecReqFlag = FALSE;	//第二次请求标志

  *uid_len = 0;
  br = br;

  while(1)
  {
	if ((status=PiccRequest(req_code,atq))==STATUS_SUCCESS)
	{
	     if((atq[0] & 0x1F) == 0x00) // check lower 5 bits, for tag-type
	                                 // all tags within this 5 bits have to
	                                 // provide a bitwise anticollision
	     {
	        status = STATUS_NOBITWISEANTICOLL;
	     }
	     break;
	}
    else
	{
		if(SecReqFlag)
			break;
		else
		{
			SecReqFlag = TRUE;
			continue;
		}
	}
  }
  
  
      //Get UID in 1 - 3 levels (standard, [double], [triple] )
      //-------
 //     if(!br)
  //    {
   //      sel_code = PICC_ANTICOLL1;
//	  }
  //    else
//	  {
  //       status = MI_BAUDRATE_NOT_SUPPORTED;
  //    }
  
  if (status == STATUS_SUCCESS)
  {
   //   cascade_level = 0;
      uid_index     = 0;
      sel_code = SELECT_CASCADE_LEVEL_1;
      do
      {
        //Select code depends on cascade level
   //     sel_code   = cmdASEL + (cascade_level << 1);
  //      cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
        //ANTICOLLISION
        status = PiccCascAnticoll( sel_code, 0, &uid[uid_index]);
        //SELECT
        if (status == STATUS_SUCCESS)
        {
           status = PiccCascSelect(sel_code, &uid[uid_index], sak);
           if (status == STATUS_SUCCESS)
           {
             // cascade_level++;
			  sel_code += 2;
              //we differ cascaded and uncascaded UIDs
              if (*sak & 0x04) // if cascaded, bit 2 is set in answer to select
              {
                 //this UID is cascaded, remove the cascaded tag that is
                 //0x88 as first of the 4 byte received
                 //memmove(&uid[uid_index], &uid[uid_index + 1], 3);
				 uid[uid_index] = uid[uid_index + 1];
				 uid[uid_index + 1] = uid[uid_index + 2];
				 uid[uid_index + 2] = uid[uid_index + 3];
                 uid_index += 3;
                 *uid_len += 3;
              }
              else
              {
                 //this UID is not cascaded -> the length is 4 bytes
               //  uid_index += 4;
                 *uid_len += 4;
              }
           }
        }
    	
      }
      while((status == STATUS_SUCCESS)        // error status
            && (*sak & 0x04)         // no further cascade level
            && (sel_code < 0x99)); // highest cascade level is reached
   }
   if (status == STATUS_SUCCESS)
   {
      //Exit function, if cascade level is triple and sak indicates another
      //cascase level.
      if ((sel_code == 0x99) && (*sak & 0x04))
      {
         *uid_len = 0;
         status = STATUS_SERNR_ERROR;
      }
   }
   return (status);
}
#endif
//=======================================================================================
// 其他实用的操作函数
//=======================================================================================
/****************************************************************************************
** 函数原型:    char PcdRfReset(unsigned char ms)
** 函数功能:    RF场复位
** 入口参数:    unsigned char ms            ; RF场关闭的时间
** 出口参数:    -
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
#if PCD_RFRESET_EN
char PcdRfReset(unsigned char ms)
    {
    // Tx2RF-En, Tx1RF-En disablen
    RcModifyReg(JREG_TXCONTROL,0,TxConMask); 
    if(ms)
    {  
        while(ms--)
        {
//        	delay_50us(20);
        }
     // Tx2RF-En, Tx1RF-En enable
        RcModifyReg(JREG_TXCONTROL,1,TxConMask); 
    }  
    return MI_OK;
}
#endif



⌨️ 快捷键说明

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