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

这篇博客详细介绍了如何使用51单片机通过SPI接口与RC522模块进行通信,包括硬件接口配置、SPI模拟通信函数以及RC522的14443协议驱动程序,涉及寻卡、防冲撞、选定卡片、验证密码、读写数据等关键操作。通过这段代码,读者可以理解并实现13.56M RFID读卡器的开发。
摘要由CSDN通过智能技术生成

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通信函数

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

Name        : delay_ns(unsigned int data ns)

Description : 纳秒延时函数

Input       : None

Output      : None

Return      : None

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

void delay_ns(unsigned int data ns)

{

  unsigned int xdata i;

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

  {

    nop();

    nop();

    nop();

  }

}

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

Name        : SPIReadByte(void)

Description : 读SPI数据

Input       : None

Output      : None

Return      : None

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

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

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

Name        : SPIReadByte(void)

Description :写SPI数据

Input       : None

Output      : None

Return      : None

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

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数据手册编写的代码。

    

  3.2. RC522寄存器地址定义

 

 

 

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

  4.1寻卡程序

 

///////////////////////////////////////////////////////////////////// //功 能:寻卡 //参数说明: 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 ///////////////////////////////////////////////////////////////////// signed char PcdRequest(unsigned char req_code,unsigned char *pTagType) { signed 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; } ///////////////////////////////////////////////////////////////////// //功 能:防冲撞 //参数说明: pSnr[OUT]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAnticoll(unsigned char *pSnr) { signed 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=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; } ///////////////////////////////////////////////////////////////////// //功 能:选定卡片 //参数说明: pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdSelect(unsigned char *pSnr) { signed char status; unsigned char i; unsigned int unLen; unsigned char 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; } ///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码 //参数说明: auth_mode[IN]: 密码验证模式 // 0x60 = 验证A密钥 // 0x61 = 验证B密钥 // addr[IN]:块地址 // pKey[IN]:密码 // pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) { signed char status; unsigned int unLen; unsigned char 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; }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值