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

📄 mfrc522.c

📁 MFRC522 单片机读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************Copyright (c)*************************************
**                              广州周立功单片机发展有限公司
**                                    研    究    所
**                                       产品一部 
**
**                                http://www.zlgmcu.com
**
**--------------文件信息----------------------------------------------------------------
** 文 件 名:    MFRC522.C
** 文件描述:    MF RC522底层程序
** 版    本:    V1.0 
** 创 建 人:    朱旻
** 创建日期:    xxxx.xx.xx
** 最后修改日期:
**=======================================================================================
**-----------------修改记录--------------------------------------------------------------
** 修改内容:    1、 修改文件结构
** 当前版本:    
** 修 改 人:    曾本森
** 修改日期:    2007.09.22
** 注    意: 
****************************************************************************************/
#define MIFARE_GLOBALS
#include "LPC900SPI.h"
#include "RC522Reg.h"
#include "OpCtrl.h"
#include "Mifare.h"
#include "main.h"
//=======================================================================================

typedef struct
         {
            unsigned char  cmd;                 //!< command code
            char           status;              //!< communication status
            unsigned char  nBytesSent;          //!< how many bytes already sent
            unsigned char  nBytesToSend;        //!< how many bytes to send
            unsigned char  nBytesReceived;      //!< how many bytes received
            unsigned short nBitsReceived;       //!< how many bits received
            unsigned char  collPos;             //collision position
         } MfCmdInfo;

volatile MfCmdInfo idata MInfo;
char  M522PcdCmd(unsigned char cmd,unsigned char idata *ExchangeBuf);

static void ResetInfo(void)
{
	unsigned char i;
	unsigned char idata *BfrPtr = (unsigned char idata *)(&MInfo);
	
	for(i=0 ; i<sizeof(MfCmdInfo); i++)
		BfrPtr[i] = 0;
}
/****************************************************************************************
** 函数原型:    void PcdClose(void);
** 函数功能:    读卡芯片硬件掉电/复位
** 入口参数:    -
** 出口参数:    -
** 返 回 值:    -
** 描   述:    复位脚 NRESTPD = 0
****************************************************************************************/
void PcdClose(void)
{
	NRSTPD = 0;
}
/****************************************************************************************
** 函数原型:    void SetTimeOut(unsigned int _100us)
** 函数功能:    设置芯片超时时间
** 入口参数:    unsigned int _100us         ; 设置的超时值×100us
** 出口参数:    -
** 返 回 值:    -
** 描   述:    
****************************************************************************************/
void SetTimeOut(unsigned int _100us)
{
    RcSetReg(JREG_TRELOADLO, ((unsigned char)(_100us&0xff)));
    RcSetReg(JREG_TRELOADHI, ((unsigned char)((_100us>>8)&0xff)));
}
/****************************************************************************************
** 函数原型:    char PcdConfig()
** 函数功能:    读写卡芯片配置
** 入口参数:    -
** 出口参数:    -
** 返 回 值:    操作结果
** 描   述:    
****************************************************************************************/
//char PN511InitAsPcd()
char PcdConfig()
{
    unsigned char RegVal;
	unsigned char i;
	ClosePCD();
    SPI_Init();
	OpenPCD();	                        // 低电平脉冲宽度大于100ns即可
	for(i=3;i>0;i--)
		for(RegVal=200;RegVal>0;RegVal--);	// 根据晶振起振情况调整此延时时间

    RcSetReg(JREG_CONTROL, 0x10); 	    /*Initator*/
	RcSetReg(JREG_MODE, 0x3f); 		    /*ModeDetOff*/
	RcSetReg(JREG_GSNOFF, 0x00); 
	RcSetReg(JREG_TXBITPHASE, 0x80); 
	RcSetReg(JREG_AUTOTEST, 0x40);

	RcSetReg(JREG_TXAUTO, 0x40);        /*force to 100% ASK*/
	RegVal = RcGetReg(JREG_TXAUTO);
	if(RegVal != 0x40)
		return STATUS_INIT_ERROR;
     /* Set the timer to auto mode, 5ms using operation control commands before HF is switched on to
     * guarantee Iso14443-3 compliance of Polling procedure
	 */
    SetTimeOut(10);

    /* Activate the field  */
    RcModifyReg(JREG_TXCONTROL, 1, JBIT_TX2RFEN | JBIT_TX1RFEN);

    /* start timer manually to check the initial waiting time */
    RcModifyReg(JREG_CONTROL, 1, JBIT_TSTARTNOW);

    /*
	 * After switching on the timer wait until the timer interrupt occures, so that
     * the field is on and the 5ms delay have been passed.
	 */
    do {
        RegVal = RcGetReg(JREG_COMMIRQ);
    }
    while(!(RegVal & JBIT_TIMERI));

    /* Clear the status flag afterwards */
    RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
			
	/*
    NOTE: The supported hardware range is bigger, since the prescaler here
          is always set to 100 us.
    */
    RcSetReg(JREG_TPRESCALER, 0xa6-1);
	RcSetReg(JREG_TMODE, 0x82);//82

    /* Activate receiver for communication
       The RcvOff bit and the PowerDown bit are cleared, the command is not changed. */
    RcSetReg(JREG_COMMAND, JCMD_IDLE);
    TxConMask = 0x03;
	return STATUS_SUCCESS;
}
/*************************************************
Function:       M522PcdCmd
Description:
     implement a command
Parameter:
     cmd            command code
     ExchangeBuf    saved the data will be send to card and the data responed from the card
     info           some information for the command
Return:
     char      status of implement
**************************************************/
char  M522PcdCmd(unsigned char cmd,
                 unsigned char idata *ExchangeBuf)
{
    char          status    = STATUS_SUCCESS;

    unsigned char  idata commIrqEn   = 0;
    unsigned char  idata divIrqEn    = 0;
    unsigned char  idata waitForComm = JBIT_ERRI | JBIT_TXI;
    unsigned char  idata waitForDiv  = 0;
    unsigned char  idata doReceive   = 0;
  //  unsigned char  idata i;
    unsigned char  idata getRegVal,setRegVal;

    unsigned char  nbytes, nbits;
    
    /*remove all Interrupt request flags that are used during function,
    keep all other like they are*/
    RcSetReg(JREG_COMMIRQ, 0x7f);	//waitForComm);
    RcSetReg(JREG_DIVIRQ, 0x7f);	//waitForDiv);
    RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);

    /*disable command or set to transceive*/
    getRegVal = RcGetReg(JREG_COMMAND);
    if(cmd == JCMD_TRANSCEIVE)
    {
        /*re-init the transceive command*/
        setRegVal = (getRegVal & ~JMASK_COMMAND) | JCMD_TRANSCEIVE;
        RcSetReg(JREG_COMMAND, setRegVal);//0c
    }
    else
    {
        /*clear current command*/
        setRegVal = (getRegVal & ~JMASK_COMMAND);
        RcSetReg(JREG_COMMAND, setRegVal);
    }
    
    switch(cmd)
    {
       case JCMD_IDLE:         /* values are 00, so return immediately after all bytes written to FIFO */
            waitForComm = 0;
            waitForDiv  = 0;
            break;
        case JCMD_CALCCRC:      /* values are 00, so return immediately after all bytes written to FIFO */
            waitForComm = 0;
            waitForDiv  = 0;
            break;
        case JCMD_TRANSMIT:
            commIrqEn = JBIT_TXI | JBIT_TIMERI;
            waitForComm = JBIT_TXI;
            break;
        case JCMD_RECEIVE:
            commIrqEn = JBIT_RXI | JBIT_TIMERI;		//| JBIT_ERRI;
            waitForComm = JBIT_RXI | JBIT_TIMERI; 	//| JBIT_ERRI;
            doReceive = 1;
            break;
        case JCMD_TRANSCEIVE:
            commIrqEn = JBIT_RXI | JBIT_TIMERI; 	//| JBIT_ERRI;
            waitForComm = JBIT_RXI | JBIT_TIMERI;	//| JBIT_ERRI;
            doReceive = 1;
            break;
        case JCMD_AUTHENT:
            commIrqEn = JBIT_IDLEI | JBIT_TIMERI;	//| JBIT_ERRI;
            waitForComm = JBIT_IDLEI | JBIT_TIMERI;	//| JBIT_ERRI;
            break;
        case JCMD_SOFTRESET:    /* values are 0x00 for IrqEn and for waitFor, nothing to do */
            waitForComm = 0;
            waitForDiv  = 0;
            break;
        default:
            status = STATUS_UNSUPPORTED_COMMAND;
    }
    if(status == STATUS_SUCCESS)
    {
        /* activate necessary communication Irq's */
        getRegVal = RcGetReg(JREG_COMMIEN);
        RcSetReg(JREG_COMMIEN, getRegVal | commIrqEn);

        /* activate necessary other Irq's */
        getRegVal = RcGetReg(JREG_DIVIEN);
        RcSetReg(JREG_DIVIEN, getRegVal | divIrqEn);

        /*write data to FIFO
        for(i=0; i<MpIsrInfo->nBytesToSend; i++)
        {
            RcSetReg(JREG_FIFODATA, ExchangeBuf[i]);
        }*/
		WriteFIFO(ExchangeBuf,MInfo.nBytesToSend);

        /*do seperate action if command to be executed is transceive*/
        if(cmd == JCMD_TRANSCEIVE)
        {
            /*TRx is always an endless loop, Initiator and Target must set STARTSEND.*/
            RcModifyReg(JREG_BITFRAMING, 1, JBIT_STARTSEND);
        }
        else
        {
            getRegVal = RcGetReg(JREG_COMMAND);
            RcSetReg(JREG_COMMAND, (getRegVal & ~JMASK_COMMAND) | cmd);
        }

        /*polling mode*/
        getRegVal = 0;
        setRegVal = 0;
        
		MIFARE_tmoutcnt = RC522_DELAY555MS;
        while(!(waitForComm ? (waitForComm & setRegVal) : 1) ||
              !(waitForDiv ? (waitForDiv & getRegVal) :1))
        {
            setRegVal = RcGetReg(JREG_COMMIRQ);
            getRegVal = RcGetReg(JREG_DIVIRQ);
            if(MIFARE_tmoutcnt == 0)
                break;
        }
		if(MIFARE_tmoutcnt == 0)
		{
			status = STATUS_ACCESS_TIMEOUT;
		}
		else
		{
	        /*store IRQ bits for clearance afterwards*/
	        waitForComm = (unsigned char)(waitForComm & setRegVal);
	        waitForDiv  = (unsigned char)(waitForDiv & getRegVal);
	
	        /*set status to Timer Interrupt occurence*/
	        if (setRegVal & JBIT_TIMERI)
	        {
	            status = STATUS_IO_TIMEOUT;
	        }
		}
    }

    /*disable all interrupt sources*/
    RcModifyReg(JREG_COMMIEN, 0, commIrqEn);

    RcModifyReg(JREG_DIVIEN, 0, divIrqEn);

    if(doReceive && (status == STATUS_SUCCESS))
    {
        /*read number of bytes received (used for error check and correct transaction*/
        MInfo.nBytesReceived = RcGetReg(JREG_FIFOLEVEL);
        nbytes = MInfo.nBytesReceived;
        getRegVal = RcGetReg(JREG_CONTROL);
        MInfo.nBitsReceived = (unsigned char)(getRegVal & 0x07);
        nbits = MInfo.nBitsReceived;

        getRegVal = RcGetReg(JREG_ERROR);
        /*set status information if error occured*/
        if(getRegVal)
        {
            if(getRegVal & JBIT_COLLERR)
                status = STATUS_COLLISION_ERROR;         /* Collision Error */
            else if(getRegVal & JBIT_PARITYERR)
                status = STATUS_PARITY_ERROR;            /* Parity Error */

            if(getRegVal & JBIT_PROTERR)
                status = STATUS_PROTOCOL_ERROR;          /* Protocoll Error */
            else if(getRegVal & JBIT_BUFFEROVFL)
                status = STATUS_BUFFER_OVERFLOW;         /* BufferOverflow Error */
            else if(getRegVal & JBIT_CRCERR)
            {   /* CRC Error */
                if(MInfo.nBytesReceived == 0x01 &&
                    (MInfo.nBitsReceived == 0x04 ||
                     MInfo.nBitsReceived == 0x00))
                {   /* CRC Error and only one byte received might be a Mifare (N)ACK */
                    ExchangeBuf[0] = RcGetReg(JREG_FIFODATA);
                    MInfo.nBytesReceived = 1;
                    status = STATUS_ACK_SUPPOSED;        /* (N)ACK supposed */
                }
                else
                    status = STATUS_CRC_ERROR;           /* CRC Error */
            }
            else if(getRegVal & JBIT_TEMPERR)
                status = STATUS_RC522_TEMP_ERROR;       /* Temperature Error */
            if(getRegVal & JBIT_WRERR)
                status = STATUS_FIFO_WRITE_ERROR;        /* Error Writing to FIFO */
            if(status == STATUS_SUCCESS)
                status = STATUS_ERROR_NY_IMPLEMENTED;    /* Error not yet implemented, shall never occur! */

            /* if an error occured, clear error register before IRQ register */
            RcSetReg(JREG_ERROR, 0);
        }

        /*read data from FIFO and set response parameter*/
        if(status != STATUS_ACK_SUPPOSED)
        {
           // for(i=0; i<MpIsrInfo->nBytesReceived; i++)
            //{
            //    ExchangeBuf[i] = RcGetReg(JREG_FIFODATA);
            //}
			ReadFIFO(ExchangeBuf,MInfo.nBytesReceived);
            /*in case of incomplete last byte reduce number of complete bytes by 1*/
            if(MInfo.nBitsReceived && MInfo.nBytesReceived)
                MInfo.nBytesReceived --;
        }
    }
    RcSetReg(JREG_COMMIRQ, waitForComm);
    RcSetReg(JREG_DIVIRQ, waitForDiv);
    RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
    RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
    RcSetReg(JREG_BITFRAMING, 0);
    return status;
}
/****************************************************************************************
** 函数原型:    char PiccRequest(unsigned char req_code, unsigned char idata *atq);
** 函数功能:    请求天线感应区内的卡
** 入口参数:    unsigned char req_code      ; 请求类型 REQALL、REQIDLE
** 出口参数:    unsigned char idata *atq    ; 请求回应
** 返 回 值:    -
** 描   述:    请求回应的代码
**	     		MF0 IC U1	的类型号:0044H
**	     		MF1 IC S50	的类型号:0004H
**				MF1 IC S70	的类型号:0002H

⌨️ 快捷键说明

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