RC522读卡芯片怎么用?

RC522读卡芯片怎么用?,第1张

什么意思?#include

#define RST 1 <世慧腔<8 // P0.7控制RC522复位,低电平复位/*

*********************************************************************************************************

** 函数名称 :RC522_RST()

** 函数功能 :复位RC522

** 调试说明 :需将跳线JP5和RST连接。

*********************************************************************************************************

*/int RC522_RST (void)

{//PINSEL0 = 0x00000000 // 设置管脚连接GPIO

IO0DIR = RST // 设置RST控制口为输出

IO0SET = RST // P0.7置高

DelayNS(10) // 延时搜衫

IO0CLR = RST // P0.7置低

DelayNS(3)

IO0SET = RST

return 0

}/*

********************************************************************************************************

** 函数名称:ReadRawRC()

** 函数功能:读MF522寄存器

** 参数说明:Address[IN]:寄存器地址

** 返 回 值:读出的值

********************************************************************************************************

*/unsigned char ReadRawRC(unsigned char Address)

{

unsigned char ucAddr

unsigned char ucResult = 0

ucAddr = ((Address<<1)&0x7E)|0x80

ucResult = MSPI_SendData (ucAddr)

return ucResult

}

/*

*******************************************************************************************************

** 函数名称:WriteRawRC()

** 函碧余数功能:写MF522寄存器

** 参数说明:Address[IN]:寄存器地址

** value[IN]:写入的值

** 返 回 值:无

*******************************************************************************************************

*/void WriteRawRC(unsigned char Address,unsigned char value)

{

unsigned char ucAddr

ucAddr = ((Address<<1)&0x7E)

MSPI_SendData(ucAddr)

MSPI_SendData(value)

return 0}/*

*******************************************************************************************************

** 函数名称:SetBitMask()

** 函数功能:置MF522寄存器位

** 参数说明:reg[IN]:寄存器地址

** mask[IN]:置位值

** 返 回 值:无

*******************************************************************************************************

*/void SetBitMask(unsigned char reg,unsigned char mask)

{

char tmp = 0x0

tmp = ReadRawRC(reg)

WriteRawRC(reg,tmp | mask)

return 0

}/*

*******************************************************************************************************

** 函数名称:ClearBitMask()

** 函数功能:清MF522寄存器位

** 参数说明:reg[IN]:寄存器地址

** mask[IN]:清位值

** 返 回 值:无

*******************************************************************************************************

*/void ClearBitMask(unsigned char reg,unsigned char mask)

{

char tmp = 0x0

tmp ReadRawRC(reg)

WriteRawRC(reg,tmp &~mask)

return 0

}/*

*******************************************************************************************************

** 函数名称:PcdAntennaOn()

** 函数功能:开启天线

** 函数说明:每次开启或关闭天线发射之间至少有1ms的间隔

** 返 回 值:无

*******************************************************************************************************

*/void PcdAntennaOn()

{

unsigned char i

i = ReadRawRC(TxControlReg)

if (!(i &0x03))

{

SetBitMask(TxControlReg,0x03)

}return 0

}/*

*******************************************************************************************************

** 函数名称:PcdAntennaOff()

** 函数功能:关闭天线

** 函数说明:每次开启或关闭天线发射之间至少有1ms的间隔

** 返 回 值:无

*******************************************************************************************************

*/void PcdAntennaOff()

{

ClearBitMask(TxControlReg,0x03)

}/*

*******************************************************************************************************

** 函数名称:PcdComMF522()

** 函数功能:通过RC522和ISO14443卡通讯

** 函数说明:Command[IN]:RC522命令字

** pIndata[IN]:通过RC522发送到卡片的数据

** InLenByte[IN]:发送数据的字节长度

** pOutData[OUT]:接收到的卡片返回数据

** *pOutLenBit[OUT]:返回数据的位长度

** 返 回 值:成功返回 MI_OK

*******************************************************************************************************

*/char PcdComMF522(unsigned char Command,

unsigned char *pInData,

unsigned char InLenByte,

unsigned char *pOutData,

unsigned int *pOutLenBit)

{

char status = MI_ERR

unsigned char irqEn = 0x00

unsigned char waitFor = 0x00

unsigned char lastBits

unsigned char n

unsigned int i

switch (Command)

{

case PCD_AUTHENT:

irqEn = 0x12

waitFor = 0x10

break

case PCD_TRANSCEIVE:

irqEn = 0x77

waitFor = 0x30

break

default:

break

}

WriteRawRC(ComIEnReg,irqEn|0x80)

ClearBitMask(ComIrqReg,0x80)

WriteRawRC(CommandReg,PCD_IDLE)

SetBitMask(FIFOLevelReg,0x80)

for (i=0i<InLenBytei++)

{ WriteRawRC(FIFODataReg, pInData[i]) }

WriteRawRC(CommandReg, Command)

if (Command == PCD_TRANSCEIVE)

{SetBitMask(BitFramingReg,0x80) }

i = 600//根据时钟频率调整, *** 作M1卡最大等待时间25ms

do

{

n = ReadRawRC(ComIrqReg)

i--

}

while ((i!=0) &&!(n&0x01) &&!(n&waitFor))

ClearBitMask(BitFramingReg,0x80)

if (i!=0)

{

if(!(ReadRawRC(ErrorReg)&0x1B))

{

status = MI_OK

if (n &irqEn &0x01)

{ status = MI_NOTAGERR }

if (Command == PCD_TRANSCEIVE)

{

n = ReadRawRC(FIFOLevelReg)

lastBits = ReadRawRC(ControlReg) &0x07

if (lastBits)

{ *pOutLenBit = (n-1)*8 + lastBits }

else

{ *pOutLenBit = n*8 }

if (n == 0)

{ n = 1 }

if (n >MAXRLEN)

{ n = MAXRLEN }

for (i=0i<ni++)

{ pOutData[i] = ReadRawRC(FIFODataReg) }

}

}

else

{ status = MI_ERR }

}

SetBitMask(ControlReg,0x80) // stop timer now

WriteRawRC(CommandReg,PCD_IDLE)

return status

}2007-8-11 22:33:00 jianjian1981

等级:初中二年级

文章:51

积分:1461

门派:无门无派

注册:2006年4月19日第 2 楼 --------------------------------------------------------------------------------

/*

*******************************************************************************************************

** 函数名称:PcdRequest()

** 函数功能:寻卡

** 函数说明: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 ucComMF522Buf[MAXRLEN] ClearBitMask(Status2Reg,0x08)

WriteRawRC(BitFramingReg,0x07)

SetBitMask(TxControlReg,0x03)

ucComMF522Buf[0] = req_code status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen)

if ((status == MI_OK) &&(unLen == 0x10))

{

*pTagType = ucComMF522Buf[0]

*(pTagType+1) = ucComMF522Buf[1]

}

else

{ status = MI_ERR }

return status

}/*

*******************************************************************************************************

** 函数名称:PcdAnticoll()

** 函数功能:防冲撞

** 函数说明:pSnr[OUT]:卡片序列号,4字节

** 返 回 值:成功返回MI_OK

*******************************************************************************************************

*/char PcdAnticoll(unsigned char *pSnr)

{

char status

unsigned char i,snr_check=0

unsigned int unLen

unsigned char ucComMF522Buf[MAXRLEN]

ClearBitMask(Status2Reg,0x08)

WriteRawRC(BitFramingReg,0x00)

ClearBitMask(CollReg,0x80)

ucComMF522Buf[0] = PICC_ANTICOLL1

ucComMF522Buf[1] = 0x20 status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen) if (status == MI_OK)

{

for (i=0i<4i++)

{

*(pSnr+i) = ucComMF522Buf[i]

snr_check ^= ucComMF522Buf[i]

}

if (snr_check != ucComMF522Buf[i])

{ status = MI_ERR }

}

SetBitMask(CollReg,0x80)

return status

}/*

*******************************************************************************************************

** 函数名称:PcdSelect()

** 函数功能:选定卡片

** 函数说明:pSnr[IN]:卡片序列号,4字节

** 返 回 值:成功返回MI_OK

*******************************************************************************************************

*/char PcdSelect(unsigned char *pSnr)

{

char status

unsigned char i

unsigned int unLen

unsigned char ucComMF522Buf[MAXRLEN]

ucComMF522Buf[0] = PICC_ANTICOLL1

ucComMF522Buf[1] = 0x70

ucComMF522Buf[6] = 0

for (i=0i<4i++)

{

ucComMF522Buf[i+2] = *(pSnr+i)

ucComMF522Buf[6] ^= *(pSnr+i)

}

CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7])

ClearBitMask(Status2Reg,0x08) status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen)

if ((status == MI_OK) &&(unLen == 0x18))

{ status = MI_OK }

else

{ status = MI_ERR }return status

}

S50的数据块包括控制块的读写都是以16字节为单位;

控制块中的KEYA是永远也读不出来的(即读出的内容要么全0要么全1),3字节的存取条件各bit间有严格的互补关系轿如正,不能写错;

如果你把控制块本身的闭悔存取条件设成了C1C2C3=111,整个控制块的内橡哗容就无法读出,会出现读出全0或全1的情况。

/////////////////////////////////////////////////////////////////////

//功    能:通过RC522和ISO14443卡通讯

//参数说明:Command[IN]:RC522命令字

//          pInData[IN]:通过RC522发送到卡片的数据

//          InLenByte[IN]:发送数据的字节长度

//          pOutData[OUT]:接收到的卡片返回数据

//          *pOutLenBit[OUT]:返回数据的位长度

/////////////////////////////////////////////////////////////////////

char PcdComMF522(unsigned char Command,unsigned char *pInData,unsigned char InLenByte,

                    unsigned char *pOutData, unsigned int *pOutLenBit)

{

    char  status = MI_ERR

    unsigned char  irqEn   = 0x00

    unsigned char  waitFor = 0x00

    unsigned char  lastBits

    unsigned char  n

    unsigned int   i

    switch (Command)

    {

        case PCD_AUTHENT:

            irqEn   = 0x12

            waitFor = 0x10

            break

        case PCD_TRANSCEIVE:     //发送并接收数据?

            irqEn   = 0x77

            waitFor = 0x30

            break

        default:

            break

    }

   

    WriteRawRC(ComIEnReg,irqEn|0x80)   //容许除定时器中断请求以为得所有中断请求

    ClearBitMask(ComIrqReg,0x80)      //屏蔽位清除

    WriteRawRC(CommandReg,PCD_IDLE)   //取消当前命令?

    SetBitMask(FIFOLevelReg,0x80)    //清除FIFO中的读写指针

    

    for (i=0 i<InLenByte i++)

    {   WriteRawRC(FIFODataReg, pInData[i])    } //写寻卡命令?

    WriteRawRC(CommandReg, Command)//发送并接收数据

    

    if (Command == PCD_TRANSCEIVE)

    {    SetBitMask(BitFramingReg,0x80)  }    //相当于启动发送STARTSENG

    

    //i = 600//根据时钟频率调整, *** 作M1卡最大等待时间25ms

    i = 2000

  配段  do 

    {

        n = ReadRawRC(ComIrqReg)

        i--

    }

    while ((i!=0) && !(n&0x01) && !(n&waitFor))

    ClearBitMask(BitFramingReg,0x80)    //相当于清除发送STARTSENG

    if (i!=0)   //定时时间到,i,没有递减到0?

    {    

        if(!(ReadRawRC(ErrorReg)&0x1B))

        {

            status = MI_OK

            if (n & irqEn & 0x01)

            {   status = MI_NOTAGERR   }

            if (Command == PCD_TRANSCEIVE)

            {

                   n = ReadRawRC(FIFOLevelReg)

                  lastBits = ReadRawRC(ControlReg) & 0x07

                if (lastBits)

                {   *pOutLenBit = (n-1)*8 + lastBits   }

                else

                {   *pOutLenBit = n*8   }

                if (n == 0)

                {   n = 1    }

            配卖春    if (n > MAXRLEN)

                {   n = MAXRLEN   }

                for (i=0 i<n i++)

                {   pOutData[i] = ReadRawRC(FIFODataReg)    }

            }

        }

        else

        {   status = MI_ERR   }

        

    }

   

    SetBitMask(ControlReg,0x80)           // stop timer now

    WriteRawRC(CommandReg,PCD_IDLE) 

  培耐  return status

}

/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////

//用MF522计算CRC16函数

/////////////////////////////////////////////////////////////////////

void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)

{

    unsigned char i,n

    ClearBitMask(DivIrqReg,0x04)      

    WriteRawRC(CommandReg,PCD_IDLE)      //取消当前命令

    SetBitMask(FIFOLevelReg,0x80)    //FlushBuffer?清除ErrReg?的标志位

    for (i=0 i<len i++)

    {   WriteRawRC(FIFODataReg, *(pIndata+i))   }

    WriteRawRC(CommandReg, PCD_CALCCRC)

    i = 0xFF

    do 

    {

        n = ReadRawRC(DivIrqReg)

        i--

    }

    while ((i!=0) && !(n&0x04))      //当CRCIRq 所有数据被处理完毕该位置位

    pOutData[0] = ReadRawRC(CRCResultRegL)    //显示计算出来的CRC值

    pOutData[1] = ReadRawRC(CRCResultRegM)

}

/////////////////////////////////////////////////////////////////////

//功    能:复位RC522

//返    回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdReset(void)

{

//    SPI_PORT_REG|=(1<<RC522RST)

//    SPI_PORT|=(1<<RC522RST)

//    SET_RC522_RST

    Delaynms(2)

//    SPI_PORT&=~(1<<RC522RST)

    CLR_RC522_RST  

    Delaynms(2)

//    SPI_PORT|=(1<<RC522RST)

    SET_RC522_RST

    Delaynms(2)

    WriteRawRC(CommandReg,PCD_RESETPHASE)//   #define PCD_RESETPHASE 0x0F //复位

    Delaynms(2)

    

    WriteRawRC(ModeReg,0x3D)            //和Mifare卡通讯,CRC初始值0x6363

    WriteRawRC(TReloadRegL,30)          //定时器的低8位数据 

    WriteRawRC(TReloadRegH,0)           //定时器的高8位数据

    WriteRawRC(TModeReg,0x8D)           //定时器模式寄存器,定时器减值计数

    WriteRawRC(TPrescalerReg,0x3E)     //ftimer 2000  //实际值是OXD3E 这部分主要是设置定时器寄存器,

    

    WriteRawRC(TxAutoReg,0x40)//必须要   //必须要 ,设置逻辑1,强制100%ASK调制

   

    return MI_OK

}

/******************************************************************************/

void InitRc522(void)

{

  PcdReset()

  PcdAntennaOff()  

  PcdAntennaOn()

  M500PcdConfigISOType( 'A' )

}

//////////////////////////////////////////////////////////////////////

//设置RC632的工作方式 

//////////////////////////////////////////////////////////////////////

char M500PcdConfigISOType(unsigned char type)

{

   if (type == 'A')                     //ISO14443_A

   { 

       ClearBitMask(Status2Reg,0x08)      //状态2寄存器

       WriteRawRC(ModeReg,0x3D)//3F      //和Mifare卡通讯,CRC初始值0x6363

       WriteRawRC(RxSelReg,0x86)//84   

       //选择内部接收器设置,内部模拟部分调制信号,发送数据后,延迟6个位时钟,接收 

       WriteRawRC(RFCfgReg,0x7F)   //4F    配置接收器 48dB最大增益

       WriteRawRC(TReloadRegL,30)//tmoLength)// TReloadVal = 'h6a =tmoLength(dec) 

       WriteRawRC(TReloadRegH,0)

       WriteRawRC(TModeReg,0x8D)

       WriteRawRC(TPrescalerReg,0x3E)     //ftimer 2000

       Delaynms(100)

       PcdAntennaOn()

   }

   else{ return -1 }

   

   return MI_OK

}

/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////

//关闭天线

/////////////////////////////////////////////////////////////////////

void PcdAntennaOff(void)

{

    ClearBitMask(TxControlReg, 0x03)   //tx12RFEN==00?,禁止发射管脚

}

/////////////////////////////////////////////////////////////////////

//开启天线  

//每次启动或关闭天险发射之间应至少有1ms的间隔

/////////////////////////////////////////////////////////////////////

void PcdAntennaOn(void)

{

    unsigned char i

    i = ReadRawRC(TxControlReg)

    if (!(i & 0x03))

    {

        SetBitMask(TxControlReg, 0x03)   //tx12RFEN==11?,打开发射管脚

    }

}

/////////////////////////////////////////////////////////////////////

//功    能:清RC522寄存器位

//参数说明:reg[IN]:寄存器地址

//          mask[IN]:清位值

/////////////////////////////////////////////////////////////////////

void ClearBitMask(unsigned char reg,unsigned char mask)  

{

    char  tmp = 0x0

    tmp = ReadRawRC(reg)

    WriteRawRC(reg, tmp & ~mask)  // clear bit mask

/////////////////////////////////////////////////////////////////////

//功    能:置RC522寄存器位

//参数说明:reg[IN]:寄存器地址

//          mask[IN]:置位值

/////////////////////////////////////////////////////////////////////

void SetBitMask(unsigned char reg,unsigned char mask)  

{

    char tmp = 0x0

    tmp = ReadRawRC(reg)

    WriteRawRC(reg,tmp | mask)  // set bit mask

}

/////////////////////////////////////////////////////////////////////

//功    能:读RC522寄存器

//参数说明:Address[IN]:寄存器地址

//返    回:读出的值

/////////////////////////////////////////////////////////////////////

unsigned char ReadRawRC(unsigned char Address)

{

    unsigned char  ucAddr

    unsigned char  ucResult=0

    CLR_SPI_CS

    ucAddr = ((Address<<1)&0x7E)|0x80 //读数据  

     //变化成有效的地址形式,最低位为0,最高位为1时候是,从MFRC522读出数据,参考39页

    SPI_MasterTransmit(ucAddr)    

    SPI_MasterTransmit(ucResult)

    ucResult=SPDR

    SET_SPI_CS

    return ucResult

}

/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////

//功    能:写RC522寄存器

//参数说明:Address[IN]:寄存器地址

//          value[IN]:写入的值

/////////////////////////////////////////////////////////////////////

void WriteRawRC(unsigned  char  Address, unsigned char  value)

//void WriteRawRC(Address,value)

{  

    unsigned  char  ucAddr

      CLR_SPI_CS   //启动SPI

      

    ucAddr = ((Address<<1)&0x7E)  //写数据  

    //变化成有效的地址形式,最低为为0,最高位为1时候是,写入MFRC522数据

    SPI_MasterTransmit(ucAddr)

    SPI_MasterTransmit(value)

      

      SET_SPI_CS   //停止SPI

     

}

/******************************************************************************/

void Delaynms(unsigned int di) //延时

{

    unsigned int i,j

     for(i=0i<dii++)

    

           for(j=0j<10j++)

            

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8275553.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存