加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

13.56M读卡器开发详解二(RC522驱动程序)

(2013-12-16 11:18:14)
标签:

13.56m开发详解

13.56读写器

rc522开发

rc522驱动程序

it

分类: 单片机

13.56M读卡器开发详解二

1. 硬件接口介绍

根据上一篇的介绍,小编使用了RC522SPI口通信方式和51单片机进行通信。硬件接口设计此处不再附图。只是将接口配置列写如下:

sbit  spi_cs=P1^6;

sbit  spi_ck=P1^5;

sbit  spi_mosi=P1^4;

sbit  spi_miso=P1^3;

sbit  spi_rst=P1^2;

 

#define SET_SPI_CS  spi_cs=1

#define CLR_SPI_CS  spi_cs=0

#define SET_SPI_CK  spi_ck=1

#define CLR_SPI_CK  spi_ck=0

#define SET_SPI_MOSI  spi_mosi=1

#define CLR_SPI_MOSI  spi_mosi=0

#define STU_SPI_MISO  spi_miso

#define SET_RC522RST  spi_rst=1

#define CLR_RC522RST  spi_rst=0

 

2. 51单片机模拟SPI通信函数

 

void delay_ns(unsigned int data ns)

{

  unsigned int xdata i;

  for(i=0;i

  {

    nop();

    nop();

    nop();

  }

}

 

unsigned char SPIReadByte(void)

{

  unsigned char idata SPICount;                   // Counter used to clock out the data

  

  unsigned char idata SPIData;                  

  SPIData 0;

  for (SPICount 0; SPICount 8; SPICount++)  // Prepare to clock in the data to be read

  {

    SPIData <<=1;                               // Rotate the data

    CLR_SPI_CK; nop();nop();                    // Raise the clock to clock the data out of the MAX7456

   if(STU_SPI_MISO)

   {

     SPIData|=0x01;

   }

    SET_SPI_CK;   nop();nop();                  // Drop the clock ready for the next bit

                                                              // and loop back

  return (SPIData);                             // Finally return the read data

 

void SPIWriteByte(unsigned char data SPIData)

{

  unsigned char idata SPICount;                 // Counter used to clock out the data

  for (SPICount 0; SPICount 8; SPICount++)

  {

    if (SPIData 0x80)

    {

      SET_SPI_MOSI;

    }

    else

    {

      CLR_SPI_MOSI;

    nop();nop();

    CLR_SPI_CK;nop();nop();

    SET_SPI_CK;nop();nop();

    SPIData <<= 1;

           

                         

3.RC522芯片的寄存器、命令字等定义

  3.1命令字等定义

   这些宏定义都是根据RC522数据手册编写的代码。

http://s4/bmiddle/001TjWaygy6F279bsxdd3&690    

  3.2. RC522寄存器地址定义

http://s2/bmiddle/001TjWaygy6F27ajCxze1&690 

http://s6/bmiddle/001TjWaygy6F27b2hsFf5&690 

http://s8/bmiddle/001TjWaygy6F27bPjXFf7&690 

4.  Rc522的14443协议代码驱动程序

  4.1寻卡程序

http://s9/bmiddle/001TjWaygy6F27dg5zq18&690 

 char PcdRequest(unsigned char data req_code,unsigned char *pTagType)

char idata status;  

unsigned int idata unLen;

unsigned char xdata 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;

}

 4.2防冲撞函数

http://s9/bmiddle/001TjWaygy6F27ewzXie8&690 

char PcdAnticoll(unsigned char *pSnr)

{

    char xdata status;

    unsigned char xdata i,snr_check=0;

    unsigned int xdata unLen;

    unsigned char xdata 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=0; i<4; i++)

           

             *(pSnr+i)  ucComMF522Buf[i];

             snr_check ^= ucComMF522Buf[i];

         }

         if (snr_check != ucComMF522Buf[i])

           status MI_ERR;    }

    }

    

    SetBitMask(CollReg,0x80);

    return status;

}

  4.3选定卡片

http://s13/bmiddle/001TjWaygy6F27fvWGg3c&690 

char PcdSelect(unsigned char *pSnr)

{

    char xdata status;

    unsigned char xdata i;

    unsigned int xdata unLen;

    unsigned char xdata ucComMF522Buf[MAXRLEN]; 

    

    ucComMF522Buf[0] PICC_ANTICOLL1;

    ucComMF522Buf[1] 0x70;

    ucComMF522Buf[6] 0;

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

    {

     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;

}

   4.4验证卡片密码

http://s12/bmiddle/001TjWaygy6F27gyCvh3b&690 

char PcdAuthState(unsigned char data auth_mode,unsigned char data addr,unsigned char *pKey,unsigned char *pSnr)

{

    char xdata status;

    unsigned int xdata unLen;

    unsigned char xdata i,ucComMF522Buf[MAXRLEN]; 

 

    ucComMF522Buf[0] auth_mode;

    ucComMF522Buf[1] addr;

    for (i=0; i<6; i++)

       ucComMF522Buf[i+2] *(pKey+i);   }

    for (i=0; i<6; i++)

       ucComMF522Buf[i+8] *(pSnr+i);   }

 //   memcpy(&ucComMF522Buf[2], pKey, 6); 

 //   memcpy(&ucComMF522Buf[8], pSnr, 4); 

    

    status PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);

    if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) 0x08)))

      status MI_ERR;   }

    

    return status;

}

4.5读取M1卡一块数据

http://s6/bmiddle/001TjWaygy6F27ho5aR25&690 

char PcdRead(unsigned char  data addr,unsigned char *pData)

{

    char idata status;

    unsigned int idata unLen;

    unsigned char idata i,ucComMF522Buf[MAXRLEN]; 

 

    ucComMF522Buf[0] PICC_READ;

    ucComMF522Buf[1] addr;

    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

   

    status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

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

 //     memcpy(pData, ucComMF522Buf, 16);   }

    {

        for (i=0; i<16; i++)

           *(pData+i) ucComMF522Buf[i];   }

    }

    else

      status MI_ERR;   }

    

    return status;

}

4.6写数据到M1卡一块

http://s1/bmiddle/001TjWaygy6F27irqik40&690 

char PcdWrite(unsigned char  data addr,unsigned char *pData)

{

    char idata status;

    unsigned int idata unLen;

    unsigned char idata  ucComMF522Buf[MAXRLEN]; 

    

    ucComMF522Buf[0] PICC_WRITE;

    ucComMF522Buf[1] addr;

    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

 

    status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

 

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] 0x0F) != 0x0A))

      status MI_ERR;   }

        

    if (status == MI_OK)

    {

        memcpy(ucComMF522Buf, pData, 16);

     //   for (i=0; i<16; i++)

      //     

     //    ucComMF522Buf[i] *(pData+i);   

     //   }

        CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

 

        status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);

        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] 0x0F) != 0x0A))

          status MI_ERR;   }

    return status;

}

4.7命令卡进入休眠状态

http://s4/bmiddle/001TjWaygy6F27jMwq7a3&690 

char PcdHalt(void)

{

    char idata status;

    unsigned int idata unLen;

    unsigned char idata ucComMF522Buf[MAXRLEN]; 

 

    ucComMF522Buf[0] PICC_HALT;

    ucComMF522Buf[1] 0;

    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

 

    status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

 

    return MI_OK;

}

4.8  RC522计算CRC16

http://s1/bmiddle/001TjWaygy6F27kvWko40&690 

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

{

    unsigned char idata i,n;

    ClearBitMask(DivIrqReg,0x04);

    WriteRawRC(CommandReg,PCD_IDLE);

    SetBitMask(FIFOLevelReg,0x80);

    for (i=0; i

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

    WriteRawRC(CommandReg, PCD_CALCCRC);

    0xFF;

    do 

    {

        ReadRawRC(DivIrqReg);

        i--;

    }

    while ((i!=0) && !(n&0x04));

    pOutData[0] ReadRawRC(CRCResultRegL);

    pOutData[1] ReadRawRC(CRCResultRegM);

}

4.9 复位RC522

http://s5/bmiddle/001TjWaygy6F27lneeM84&690 

char PcdReset(void)

{

//PORTD|=(1<<RC522RST);

SET_RC522RST;

    delay_ns(10);

//PORTD&=~(1<<RC522RST);

CLR_RC522RST;

    delay_ns(10);

//PORTD|=(1<<RC522RST);

SET_RC522RST;

    delay_ns(10);

    WriteRawRC(CommandReg,PCD_RESETPHASE);

    delay_ns(10);

    

    WriteRawRC(ModeReg,0x3D);         //ºÍMifare¿¨Í¨Ñ£¬CRC³õʼֵ0x6363

    WriteRawRC(TReloadRegL,30);           

    WriteRawRC(TReloadRegH,0);

    WriteRawRC(TModeReg,0x8D);

    WriteRawRC(TPrescalerReg,0x3E);

 

WriteRawRC(TxAutoReg,0x40);//±ØÐëÒª

   

    return MI_OK;

}

4.10 设置RC522工作方式

http://s14/bmiddle/001TjWaygy6F27mfgdL9d&690 

char M500PcdConfigISOType(unsigned char data type)

{

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

   

       ClearBitMask(Status2Reg,0x08);

       WriteRawRC(ModeReg,0x3D);//3F

       WriteRawRC(RxSelReg,0x86);//84

       WriteRawRC(RFCfgReg,0x7F);   //4F

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

   WriteRawRC(TReloadRegH,0);

       WriteRawRC(TModeReg,0x8D);

   WriteRawRC(TPrescalerReg,0x3E);

   delay_ns(1000);

       PcdAntennaOn();

   }

   else{ return -1; }

   

   return MI_OK;

}

4.11 RC522寄存器

http://s8/bmiddle/001TjWaygy6F27mWh3Ve7&690 

unsigned char ReadRawRC(unsigned char data Address)

{

    unsigned char xdata ucAddr;

    unsigned char xdata ucResult=0;

CLR_SPI_CS;

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

 

SPIWriteByte(ucAddr);

ucResult=SPIReadByte();

SET_SPI_CS;

   return ucResult;

}

4.12 RC522寄存器

http://s3/bmiddle/001TjWaygy6F27nOMDM62&690 

void WriteRawRC(unsigned char data Address, unsigned char data value)

 

    unsigned char xdata ucAddr;

 

CLR_SPI_CS;

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

 

SPIWriteByte(ucAddr);

SPIWriteByte(value);

SET_SPI_CS;

}

4.13 置和清RC522寄存器位

http://s15/bmiddle/001TjWaygy6F27oxU3I5e&690 

4.14  RC522ISO14443卡通讯

http://s7/bmiddle/001TjWaygy6F27pfgOia6&690 

char PcdComMF522(unsigned char data Command, 

                 unsigned char *pInData, 

                 unsigned char data InLenByte,

                 unsigned char *pOutData, 

                 unsigned int *pOutLenBit)

{

    char data status MI_ERR;

    unsigned char data irqEn   0x00;

    unsigned char data waitFor 0x00;

    unsigned char data lastBits;

    unsigned char data n;

    unsigned int data 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=0; i

      WriteRawRC(FIFODataReg, pInData[i]);    }

    WriteRawRC(CommandReg, Command);

   

    

    if (Command == PCD_TRANSCEIVE)

       SetBitMask(BitFramingReg,0x80);  }

    

    //i 600;//¸ù¾ÝʱÖÓÆµÂʵ÷Õû£¬²Ù×÷M1¿¨×î´óµÈ´ýʱ¼ä25ms

2000;

    do 

    {

        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)

            {

                ReadRawRC(FIFOLevelReg);

               lastBits ReadRawRC(ControlReg) 0x07;

                if (lastBits)

                  *pOutLenBit (n-1)*8 lastBits;   }

                else

                  *pOutLenBit n*8;   }

                if (n == 0)

                  1;    }

                if (n MAXRLEN)

                  MAXRLEN;   }

                for (i=0; i

                  pOutData[i] ReadRawRC(FIFODataReg);    }

            }

        }

        else

          status MI_ERR;   }

        

    }

   

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

    WriteRawRC(CommandReg,PCD_IDLE); 

    return status;

}

4.15 天线开启和关闭

http://s6/bmiddle/001TjWaygy6F27qnhA105&690 

4.16 扣款和充值

http://s4/bmiddle/001TjWaygy6F27r7eAra3&690 

char PcdValue(unsigned char data dd_mode,unsigned char data addr,unsigned char  *pValue)

{

    char data status;

    unsigned int data  unLen;

    unsigned char idata  ucComMF522Buf[MAXRLEN]; 

    

    ucComMF522Buf[0] dd_mode;

    ucComMF522Buf[1] addr;

    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

 

    status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

 

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] 0x0F) != 0x0A))

      status MI_ERR;   }

        

    if (status == MI_OK)

    {

        memcpy(ucComMF522Buf, pValue, 4);

       //  for (i=0; i<16; i++)

        //    ucComMF522Buf[i] *(pValue+i);   }

        CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);

        unLen 0;

        status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);

        if (status != MI_ERR)

           status MI_OK;    }

    }

    

    if (status == MI_OK)

    {

        ucComMF522Buf[0] PICC_TRANSFER;

        ucComMF522Buf[1] addr;

        CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); 

   

        status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

 

        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] 0x0F) != 0x0A))

          status MI_ERR;   }

    }

    return status;

}

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有