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

📄 mfrc522.c

📁 MFRC522 单片机读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
**				MF3	IC D40	的类型号:0344H
****************************************************************************************/
char PiccRequest(unsigned char req_code, unsigned char idata *atq)
{
   char  status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[2];	

   /************* initialize *****************/
   RcModifyReg(JREG_STATUS2, 0, JBIT_CRYPTO1ON);  /* disable Crypto if activated before */
   RcSetReg(JREG_COLL, JBIT_VALUESAFTERCOLL);  //active values after coll
   RcModifyReg(JREG_TXMODE, 0, JBIT_CRCEN);  //disable TxCRC and RxCRC
   RcModifyReg(JREG_RXMODE, 0, JBIT_CRCEN);
   RcSetReg(JREG_BITFRAMING, REQUEST_BITS);

   /* set necessary parameters for transmission */
   ResetInfo();
   SerBuffer[0] = req_code;
   MInfo.nBytesToSend   = 1;

   /* Set timeout for REQA, ANTICOLL, SELECT*/
	SetTimeOut(4);

   status = M522PcdCmd(JCMD_TRANSCEIVE,
                      SerBuffer);
   if(status == STATUS_SUCCESS || status == STATUS_COLLISION_ERROR)
   {
       if(MInfo.nBytesReceived != ATQA_LENGTH || MInfo.nBitsReceived != 0x00)
       {
           status = STATUS_PROTOCOL_ERROR;
       }
       else
       {
           memcopy(atq,SerBuffer,2);
       }
   }
   else
   {   /* reset atqa parameter */
       atq[0] = 0x00;
       atq[1] = 0x00;
   }
   //RcSetReg(JREG_BITFRAMING, 0);
   return status;
}
/****************************************************************************************
** 函数原型:    char PiccCascAnticoll(unsigned char sel_code,unsigned char bitcount,
**                                    unsigned char idata *snr);
** 函数功能:    防碰撞
** 入口参数:    unsigned char sel_code      ; 防碰撞的等级
**              unsigned char bitcount      ; 已知UID的位数
**              unsigned char idata *snr    ; 已知的UID
** 出口参数:    unsigned char idata *snr    ; UID
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccCascAnticoll(unsigned char sel_code,
                   unsigned char bitcount,
                   unsigned char idata *snr)
{
    char status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[7];	
    unsigned char  i;
    unsigned char  complete = 0; /* signs end of anticollission loop */
    unsigned char  rbits    = 0; /* number of total received bits */
    unsigned char  nbits    = 0; /* */
    unsigned char  nbytes   = 0; /* */
    unsigned char  byteOffset;   /* stores offset for ID copy if uncomplete last byte was sent */

    /* initialise relvant bytes in internal buffer */
    for(i=2;i<7;i++)
        SerBuffer[i] = 0x00;

    /* disable TxCRC and RxCRC */
    RcModifyReg(JREG_TXMODE, 0, JBIT_CRCEN);
    RcModifyReg(JREG_RXMODE, 0, JBIT_CRCEN);

    /* activate deletion of bits after coll */
    RcSetReg(JREG_COLL, 0);

    /* init parameters for anticollision */
    while(!complete && (status == STATUS_SUCCESS))
    {
         /* if there is a communication problem on the RF interface, bcnt
            could be larger than 32 - folowing loops will be defective. */
        if(bitcount > SINGLE_UID_LENGTH)
        {
            status = STATUS_INVALID_PARAMETER;
            continue;
        }

        /* prepare data length */
        nbits = (unsigned char)(bitcount % BITS_PER_BYTE);
        nbytes = (unsigned char)(bitcount / BITS_PER_BYTE);
        if(nbits)
            nbytes++;

        /* prepare data buffer */
        SerBuffer[0] = sel_code;
        SerBuffer[1] = (unsigned char)(NVB_MIN_PARAMETER + ((bitcount / BITS_PER_BYTE) << UPPER_NIBBLE_SHIFT) + nbits);
        for(i=0;i<nbytes;i++)
            SerBuffer[2+i] = snr[i];   /* copy serial number to tranmit buffer */

        /* set TxLastBits and RxAlign to number of bits sent */
        RcSetReg(JREG_BITFRAMING, (unsigned char)((nbits << UPPER_NIBBLE_SHIFT) | nbits));

        /* prepare data for common transceive */
        ResetInfo();
        MInfo.nBytesToSend   = (unsigned char)(nbytes + 2);

        SetTimeOut(100);
        status = M522PcdCmd(JCMD_TRANSCEIVE, SerBuffer);

        if(status == STATUS_COLLISION_ERROR || status == STATUS_SUCCESS)
        {
            /* store number of received data bits and bytes internaly */
            rbits = (unsigned char)(MInfo.nBitsReceived + (MInfo.nBytesReceived << 3) - nbits);

            if((rbits + bitcount) > COMPLETE_UID_BITS)
            {
                status = STATUS_BITCOUNT_ERROR;
                continue;
            }

            /* increment number of bytes received if also some bits received */
            if(MInfo.nBitsReceived)
                MInfo.nBytesReceived++;

            /* reset offset for data copying */
            byteOffset = 0;
            /* if number of bits sent are not 0, write first received byte in last of sent */
            if(nbits)
            {   /* last byte transmitted and first byte received are the same */
                snr[nbytes - 1] |= SerBuffer[0];
                byteOffset++;
            }

            for(i=0;i<(4-nbytes);i++)
                snr[nbytes + i] = SerBuffer[i + byteOffset];

            if(status == STATUS_COLLISION_ERROR)
            {
                /* calculate new bitcount value */
                bitcount = (unsigned char)(bitcount + rbits);
                status = STATUS_SUCCESS;
            } else
            {
                if((snr[0] ^ snr[1] ^ snr[2] ^ snr[3]) != SerBuffer[i + byteOffset])
                {
                    status = STATUS_WRONG_UID_CHECKBYTE;
                    continue;
                }
                complete=1;
            }
        }
    }

    /* clear RxAlign and TxLastbits */
    RcSetReg(JREG_BITFRAMING, 0);

    /* activate values after coll */
    RcSetReg(JREG_COLL, JBIT_VALUESAFTERCOLL);
    return status;
}
/****************************************************************************************
** 函数原型:    char PiccCascSelect(unsigned char sel_code,unsigned char idata *snr,
**                                  unsigned char idata *sak);
** 函数功能:    防碰撞
** 入口参数:    unsigned char sel_code      ; 防碰撞的等级
**              unsigned char idata *snr    ; UID
** 出口参数:    unsigned char idata *sak    ; SAK
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccCascSelect(unsigned char sel_code, 
                    unsigned char idata *snr, 
                    unsigned char idata *sak)
{
    char status = STATUS_SUCCESS;
    /* define local variables */
    unsigned char i;
	unsigned char idata SerBuffer[7];	
    /* activate CRC */
    RcModifyReg(JREG_TXMODE, 1, JBIT_CRCEN);
    RcModifyReg(JREG_RXMODE, 1, JBIT_CRCEN);

    /* prepare data stream */
    SerBuffer[0] = sel_code;   /* command code */
    SerBuffer[1] = NVB_MAX_PARAMETER;       /* parameter */
    for(i=0;i<4;i++)
        SerBuffer[2+i] = snr[i];   /* serial numbner bytes 1 to 4 */
    SerBuffer[6] = (unsigned char)(snr[0] ^ snr[1] ^ snr[2] ^ snr[3]);   /* serial number check byte */

    /* prepare data for common transceive */
    ResetInfo();
    MInfo.nBytesToSend   = 0x07;
    SetTimeOut(20);
    status = M522PcdCmd(JCMD_TRANSCEIVE, SerBuffer);

    if(status == STATUS_SUCCESS)
    {
        if(MInfo.nBytesReceived == SAK_LENGTH && MInfo.nBitsReceived == 0)
            *sak = SerBuffer[0];
        else
            status = STATUS_BITCOUNT_ERROR;
    }
    return status;
}

/*************************************************
Function:       AnticollSelect
Description:
     Anticollision loop and selecte a card to operate
Parameter:
     bcnt       bit counter of known UID
     snr        buffer to store the card UID
Return:
     char      status of implement
**************************************************/
/*char AnticollSelect(unsigned char bcnt, unsigned char *snr)
{
    unsigned char i;
    char status=STATUS_SUCCESS;
    unsigned char length, casc_code, length_in,sak,tmpSnr[12];
    length_in = bcnt;
    //* do loop for max. cascade level 
    for(i=0;i<MAX_CASCADE_LEVELS;i++)
    {
        if(length_in)
        {
            if(length_in > SINGLE_UID_LENGTH)
            {
                length = SINGLE_UID_LENGTH;
                length_in -= SINGLE_UID_LENGTH;
            }
            else
            {
                length = length_in;
                length_in = 0;
            }
        }
        else
        {
            length = 0;
        }

        switch(i)
        {
            case 1:  casc_code = SELECT_CASCADE_LEVEL_2;
                     memcopy(snr, tmpSnr+1,3);
                     break;
            case 2:  casc_code = SELECT_CASCADE_LEVEL_3;
                     break;
            default: casc_code = SELECT_CASCADE_LEVEL_1;
                     break;
        }

        if(length != SINGLE_UID_LENGTH && status == STATUS_SUCCESS)
        // do anticollission with selected level 
        status = CascAnticoll(casc_code,
                              length,
                              tmpSnr + i * 4);


        if(status == STATUS_SUCCESS)
        {
            // select 1st cascade level uid 
            status = Select(casc_code, tmpSnr + i * 4, &sak);

            // check if further cascade level is used 
            if(status == STATUS_SUCCESS)
            {
                // increase number of received bits in parameter 
                bcnt = (unsigned char)(SINGLE_UID_LENGTH * (i + 1)); //the actually length of the UID, you can return it.

                // check if cascade bit is set 
                if(!(sak & CASCADE_BIT))
                {
                    break;
                }
            }
        }
        else
        {
            break;
        }
    }
    switch(i)
    {
        case 1:  memcopy(snr+3, tmpSnr+4,4);     //copy UID to snr buffer without CT(0x88)
                 break;
        case 2:  memcopy(snr+6, tmpSnr+4,4);
                 break;
        default: memcopy(snr, tmpSnr,4);
                 break;
    }
    return status;
}
*/
/****************************************************************************************
** 函数原型:    char PiccHalt(void)
** 函数功能:    将选择的卡挂起(ISO/IEC14443A-3)
** 入口参数:    -
** 出口参数:    -
** 返 回 值:    执行结果
** 描   述:    该函数是ISO/IEC14443A-3层协议
****************************************************************************************/
char PiccHalt(void)
{
    char  status = STATUS_SUCCESS;
	unsigned char idata SerBuffer[2];
	
    /* initialise data buffer */
    SerBuffer[0] = HALTA_CMD;
    SerBuffer[1] = HALTA_PARAM;

    ResetInfo();
    MInfo.nBytesToSend   = HALTA_CMD_LENGTH;
    SetTimeOut(10);
    status = M522PcdCmd(JCMD_TRANSCEIVE, SerBuffer);

    if(status == STATUS_IO_TIMEOUT)
        status = STATUS_SUCCESS;
    return status;
}

/****************************************************************************************
** 函数原型:    char PiccAuthKey(unsigned char auth_mode,unsigned char idata *snr,
**                               unsigned char idata *key,unsigned char addr)
** 函数功能:    验证Mifare卡选择的扇区
** 入口参数:    unsigned char auth_mode     ; 验证模式阿:A密钥/B密钥
**              unsigned char idata *snr    ; 4字节UID
**              unsigned char idata *key    ; 6字节密钥
**              unsigned char addr          ; 验证的扇区号
** 出口参数:    -
** 返 回 值:    执行结果
** 描   述:    
****************************************************************************************/
char PiccAuthKey(unsigned char auth_mode,unsigned char idata *snr,
                 unsigned char idata *key,unsigned char addr)
{
    char status;
    unsigned char RegVal;
	unsigned char idata SerBuffer[12];	

    ResetInfo();

    SerBuffer[0] = auth_mode;           //  key A or key B
    SerBuffer[1] = addr;                //  address to authentication
    memcopy(SerBuffer+2,key,6);         //  6bytes key
    memcopy(SerBuffer+8,snr,4);         //  4 bytes UID
    MInfo.nBytesToSend = 12;            //  length
    SetTimeOut(20);
    status = M522PcdCmd(JCMD_AUTHENT, SerBuffer);
    if(status == STATUS_SUCCESS)
    {
      	RegVal = RcGetReg(JREG_STATUS2);
        if((RegVal & 0x0f) != 0x08)
            status = STATUS_AUTHENT_ERROR;
    }
    return status;
}
/****************************************************************************************
** 函数原型:    char PiccRead(unsigned char addr, unsigned char idata *_data)
** 函数功能:    从指定的块号读出一块数据
** 入口参数:    unsigned char addr          ; 块号
** 出口参数:    unsigned char idata *_data  ; 读出的数据(16字节)

⌨️ 快捷键说明

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