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

📄 mifare.c

📁 采用单片机89C52对飞利浦13.56Mhz的射频芯片MFRC500进行密码的配置与扇区的读写。可以由电脑通过串口发送命令来对MFRC500进行寄存器的配置读写。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg52.h>
#include <string.h>
#include "main.h"
#include "mfrc500.h"
#include "mifare.h"
#define FSD 64              //RC500 FIFO BUFFER SIZE

                              
/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//          pTagType[OUT]:卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro(X)
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
   char status;   
   unsigned int  unLen;
   unsigned char idata ucComBuf[FSD];

   WriteRawRC(RegChannelRedundancy,0x03);
   ClearBitMask(RegControl,0x08);
   WriteRawRC(RegBitFraming,0x07);
   SetBitMask(RegTxControl,0x03);
   PcdSetTmo(4);
   ucComBuf[0] = req_code;

   status = PcdComISO14443(PCD_TRANSCEIVE,ucComBuf,1,ucComBuf,&unLen);
   
   if ((status == MI_OK) && (unLen == 0x10))
   {    
       *pTagType     = ucComBuf[0];
       *(pTagType+1) = ucComBuf[1];
   }
   else
   {   status = MI_ERR;   }
   
   return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////  
char PcdAnticoll(unsigned char *pSnr)
{
    char status ;
    unsigned char i;
    unsigned char ucBits;
    unsigned char ucBytes;
	unsigned char snr_check = 0;
    unsigned char ucCollPosition = 0;
    unsigned char ucLength=0;
    unsigned char ucTemp;
    unsigned int  unLen;
    unsigned char ucSNR[5] = {0, 0, 0, 0 ,0};
    unsigned char idata ucComBuf[FSD];

    WriteRawRC(RegDecoderControl,0x28);
    ClearBitMask(RegControl,0x08);
    WriteRawRC(RegChannelRedundancy,0x03);
    PcdSetTmo(4);
    
    do
    {
        ucBits = (ucCollPosition) % 8;
        if (ucBits != 0)
        {
             ucBytes = ucCollPosition / 8 + 1;
             WriteRawRC(RegBitFraming, (ucBits << 4) + ucBits);
        }
        else
        {
             ucBytes = ucCollPosition / 8;
        }
	
        ucComBuf[0] = PICC_ANTICOLL1;
        ucComBuf[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F);

        for (i=0; i<ucBytes; i++)
	    {
	        ucComBuf[i + 2] = ucSNR[i];
	    }
	    ucLength = ucBytes + 2;
	
	    status = PcdComISO14443(PCD_TRANSCEIVE,ucComBuf,ucLength,ucComBuf,&unLen);
	
	    ucTemp = ucSNR[(ucCollPosition / 8)];
	    if (status == MI_COLLERR)
	    {
	        for (i=0; i < 5 - (ucCollPosition / 8); i++)
	        {
		         ucSNR[i + (ucCollPosition / 8)] = ucComBuf[i+1];
	        }
	        ucSNR[(ucCollPosition / 8)] |= ucTemp;
	        ucCollPosition = ucComBuf[0];
        }
        else if (status == MI_OK)
        {
            for (i=0; i < (unLen / 8); i++)
            {
                 ucSNR[4 - i] = ucComBuf[unLen/8 - i - 1];
            }
            ucSNR[(ucCollPosition / 8)] |= ucTemp;
        }
    } while (status == MI_COLLERR);
			
			
    if (status == MI_OK)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucSNR[i];
             snr_check ^= ucSNR[i];
         }
         if (snr_check != ucSNR[i])
         {   status = MI_ERR;    }
    }
    
    ClearBitMask(RegDecoderControl,0x20);
    return status;
}

////////////////////////////////////////////////////////////////////
//功    能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdSelect(unsigned char *pSnr)
{
    char status ;
    unsigned char i, snr_check = 0;
    unsigned int  unLen;
    unsigned char idata ucComBuf[FSD];

    WriteRawRC(RegChannelRedundancy,0x0F);
    ClearBitMask(RegControl,0x08);
    PcdSetTmo(4);
    
    ucComBuf[0] = PICC_ANTICOLL1;
    ucComBuf[1] = 0x70;
    for (i=0; i<4; i++)
    {
    	snr_check ^= *(pSnr+i);
    	ucComBuf[i+2] = *(pSnr+i);
    }
    ucComBuf[6] = snr_check;

    status = PcdComISO14443(PCD_TRANSCEIVE,ucComBuf,7,ucComBuf,&unLen);
    
    if ((status == MI_OK) && (unLen == 0x08))
    {   status = MI_OK;  }
    else
    {   status = MI_ERR;    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:将Mifare_One卡密钥转换为RC500接收格式
//参数说明:uncoded[IN]:6字节未转换的密钥
//          coded[OUT]:12字节转换后的密钥
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char ChangeCodeKey(unsigned char *uncoded,unsigned char *coded)
{
   unsigned char cnt=0;
   unsigned char ln=0;
   unsigned char 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;
}

/*
/////////////////////////////////////////////////////////////////////
//功    能:将存在RC500的EEPROM中的密钥匙调入RC500的FIFO
//参数说明:addr[IN]:EEPROM地址
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdLoadKeyE2(unsigned int addr)
{
    char status ;
    unsigned int  unLen;
    unsigned char idata ucComBuf[FSD];

    ucComBuf[0] = addr & 0xFF;
    ucComBuf[1] = (addr >> 8) & 0xFF;
    
    status = PcdComISO14443(PCD_LOADKEYE2,ucComBuf,2,ucComBuf,&unLen);
    
    return status;
}
*/

/////////////////////////////////////////////////////////////////////
//功    能:将已转换格式后的密钥送到RC500的FIFO中
//参数说明:pKey[IN]:密钥
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAuthKey(unsigned char *pKey)
{
    char status;
    unsigned int  unLen;
    unsigned char idata ucComBuf[FSD];

    PcdSetTmo(4);
    memcpy(ucComBuf, pKey, 12);    

    status = PcdComISO14443(PCD_LOADKEY,ucComBuf,12,ucComBuf,&unLen);

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
//                 0x60 = 验证A密钥
//                 0x61 = 验证B密钥 
//          addr[IN]:块地址
//          pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////               
char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pSnr)
{
    char status;
    unsigned int  unLen;
    unsigned char idata ucComBuf[FSD];

    PcdSetTmo(4);
    ucComBuf[0] = auth_mode;
    ucComBuf[1] = addr;
    memcpy(&ucComBuf[2], pSnr, 4);    
      
    status = PcdComISO14443(PCD_AUTHENT1,ucComBuf,6,ucComBuf,&unLen);

    if ((status == MI_OK) && !(ReadRawRC(RegSecondaryStatus) & 0x07))
    {
          status = PcdComISO14443(PCD_AUTHENT2,ucComBuf,0,ucComBuf,&unLen);
          if ((status == MI_OK) && (ReadRawRC(RegControl) & 0x08))
          {   status = MI_OK;   }
          else
          {   status = MI_ERR;   }
    }
    else
    {   status = MI_ERR;   }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
//          pData[OUT]:读出的数据,16字节
//返    回: 成功返回MI_OK
///////////////////////////////////////////////////////////////////// 
char PcdRead(unsigned char addr,unsigned char *pData)
{
    char status;
    unsigned int  unLen;
    unsigned char idata ucComBuf[FSD]; 

    PcdSetTmo(5);
    WriteRawRC(RegChannelRedundancy,0x0F);
   
    ucComBuf[0] = PICC_READ;
    ucComBuf[1] = addr;

    status = PcdComISO14443(PCD_TRANSCEIVE,ucComBuf,2,ucComBuf,&unLen);
    
    if ((status == MI_OK) && (unLen == 0x80))
    {   memcpy(pData,  ucComBuf, 16);  }
    else

⌨️ 快捷键说明

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