你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于Stm32的RFID-RC522模块的对RFID读写使用

[复制链接]
STMCU小助手 发布时间:2021-7-9 10:03

RFID-RC522是一个淘宝上比较常见的一个识别RFID的一个模块。他可以做到对RFID的读写。MF RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP公司针对“三表”应用推出的一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携 式手持设备研发的较好选择

##RFID读写卡的过程     读写卡主要有五个步骤:寻卡,防冲突,选卡,认证,读/写卡。 ###寻卡

  1. <font face="微软雅黑" size="3">// REQ_ALL代表寻天线区内所有卡,TagType为返回的卡的类型
  2. status= PcdRequest( REQ_ALL , TagType );</font>
复制代码

TagType返回的卡类型有: 0x4400 = Mifare_UltraLight 0x0400 = Mifare_One(S50) 0x0200 = Mifare_One(S70) 0x0800 = Mifare_Pro(X) 0x4403 = Mifare_DESFire ###防冲突

  1. <font face="微软雅黑" size="3">
  2. if(!status)
  3. {
  4.         status = PcdAnticoll(SelectedSnr);
  5.         // ......
  6. }</font>
复制代码

###认证

  1. <font face="微软雅黑" size="3">if(!status)
  2. {
  3.         // 认证
  4.         snr = 1;    // 扇区号1
  5.         status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr);    // 校验1扇区密码,密码位于每一扇区第3块
  6.         // ......
  7. }</font>
复制代码

四个参数分别是:验证A密钥,块地址,扇区密码,卡序列号 ###读写卡

  1. <font face="微软雅黑" size="3">
  2. if(!status)
  3. {
  4.         //读写卡
  5.         status = PcdRead((snr*4+0), buf);   // 读卡,读取1扇区0块数据到buf[0]-buf[16]
  6.         status = PcdWrite((snr*4+0), "way2");   // 写卡,将buf[0]-buf[16]写入1扇区0块
  7.         if(!status)
  8.         {
  9.                 //读写成功
  10.                 printf("read finish!\n");
  11.                 printf("读到的值是: %s\n",buf);
  12.                 WaitCardOff();
  13.         }
  14. </font>
复制代码

##代码 以下为核心代码: main.c

  1. <font face="微软雅黑" size="3">
  2. #include "stm32f10x.h"
  3. #include "delay.h"
  4. #include "bsp_usart.h"
  5. #include "RC522.h"

  6. int main()
  7. {
  8.     char status;
  9.         unsigned char snr, buf[16], TagType[2], SelectedSnr[4], DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  10.    
  11.     delay_init();
  12.     usart_init();
  13.    
  14.     PcdInit();
  15.         PcdReset();
  16.         PcdAntennaOff();
  17.         PcdAntennaOn();
  18.         M500PcdConfigISOType( 'A' );

  19.     printf( "init over!\n" );
  20.         while(1){
  21.         // 寻卡
  22.                 status= PcdRequest( REQ_ALL , TagType );    // REQ_ALL代表寻天线区内所有卡。TagType为返回的卡类型
  23.                 if(!status)
  24.                 {
  25.             // 防冲突
  26.                         status = PcdAnticoll(SelectedSnr);
  27.                         if(!status)
  28.                         {
  29.                 // 选卡
  30.                                 status=PcdSelect(SelectedSnr);
  31.                                 if(!status)
  32.                                 {
  33.                     // 认证
  34.                                         snr = 1;    // 扇区号1
  35.                                         status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr);    // 校验1扇区密码,密码位于每一扇区第3块
  36.                                           // 验证A密钥,块地址,扇区密码,卡序列号
  37.                                         {
  38.                                                 if(!status)
  39.                                                 {
  40.                             //读写卡
  41.                                                         status = PcdRead((snr*4+0), buf);   // 读卡,读取1扇区0块数据到buf[0]-buf[16]
  42. //                                                        status = PcdWrite((snr*4+0), "way2");   // 写卡,将buf[0]-buf[16]写入1扇区0块
  43.                                                         if(!status)
  44.                                                         {
  45.                                 //读写成功
  46.                                 printf("read finish!\n");
  47.                                 printf("读到的值是: %s\n",buf);
  48.                                                                 WaitCardOff();
  49.                                                         }
  50.                                                 }
  51.                                         }
  52.                                 }
  53.                         }
  54.                 }
  55.         }
  56. }
  57. </font>
复制代码

RC522.h

  1. <font face="微软雅黑" size="3">
  2. #ifndef __RC522_H
  3. #define __RC522_H

  4. #define MF522_RST_PIN                    GPIO_Pin_11
  5. #define MF522_RST_PORT                   GPIOB
  6. #define MF522_RST_CLK                    RCC_APB2Periph_GPIOB

  7. #define MF522_MISO_PIN                   GPIO_Pin_10
  8. #define MF522_MISO_PORT                  GPIOB
  9. #define MF522_MISO_CLK                   RCC_APB2Periph_GPIOB

  10. #define MF522_MOSI_PIN                   GPIO_Pin_1
  11. #define MF522_MOSI_PORT                  GPIOB
  12. #define MF522_MOSI_CLK                   RCC_APB2Periph_GPIOB

  13. #define MF522_SCK_PIN                    GPIO_Pin_0
  14. #define MF522_SCK_PORT                   GPIOB
  15. #define MF522_SCK_CLK                    RCC_APB2Periph_GPIOB

  16. #define MF522_NSS_PIN                    GPIO_Pin_7
  17. #define MF522_NSS_PORT                   GPIOA
  18. #define MF522_NSS_CLK                    RCC_APB2Periph_GPIOA

  19. #define RST_H                            GPIO_SetBits(MF522_RST_PORT, MF522_RST_PIN)
  20. #define RST_L                            GPIO_ResetBits(MF522_RST_PORT, MF522_RST_PIN)
  21. #define MOSI_H                           GPIO_SetBits(MF522_MOSI_PORT, MF522_MOSI_PIN)
  22. #define MOSI_L                           GPIO_ResetBits(MF522_MOSI_PORT, MF522_MOSI_PIN)
  23. #define SCK_H                            GPIO_SetBits(MF522_SCK_PORT, MF522_SCK_PIN)
  24. #define SCK_L                            GPIO_ResetBits(MF522_SCK_PORT, MF522_SCK_PIN)
  25. #define NSS_H                            GPIO_SetBits(MF522_NSS_PORT, MF522_NSS_PIN)
  26. #define NSS_L                            GPIO_ResetBits(MF522_NSS_PORT, MF522_NSS_PIN)
  27. #define READ_MISO                        GPIO_ReadInputDataBit(MF522_MISO_PORT, MF522_MISO_PIN)

  28. // 函数原型
  29. void PcdInit(void);
  30. char PcdReset(void);
  31. void PcdAntennaOn(void);
  32. void PcdAntennaOff(void);
  33. char PcdRequest(unsigned char req_code,unsigned char *pTagType);
  34. char PcdAnticoll(unsigned char *pSnr);
  35. char PcdSelect(unsigned char *pSnr);
  36. char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr);
  37. char PcdRead(unsigned char addr,unsigned char *pData);
  38. char PcdWrite(unsigned char addr,unsigned char *pData);
  39. char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue);
  40. char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr);
  41. char PcdHalt(void);
  42. char PcdComMF522(unsigned char Command,
  43.                  unsigned char *pInData,
  44.                  unsigned char InLenByte,
  45.                  unsigned char *pOutData,
  46.                  unsigned int  *pOutLenBit);
  47. void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData);
  48. void WriteRawRC(unsigned char Address,unsigned char value);
  49. unsigned char ReadRawRC(unsigned char Address);
  50. void SetBitMask(unsigned char reg,unsigned char mask);
  51. void ClearBitMask(unsigned char reg,unsigned char mask);
  52. char M500PcdConfigISOType(unsigned char type);
  53. void delay_10ms(unsigned int _10ms);
  54. void WaitCardOff(void);

  55. // MF522命令字
  56. #define PCD_IDLE              0x00               //取消当前命令
  57. #define PCD_AUTHENT           0x0E               //验证密钥
  58. #define PCD_RECEIVE           0x08               //接收数据
  59. #define PCD_TRANSMIT          0x04               //发送数据
  60. #define PCD_TRANSCEIVE        0x0C               //发送并接收数据
  61. #define PCD_RESETPHASE        0x0F               //复位
  62. #define PCD_CALCCRC           0x03               //CRC计算


  63. // Mifare_One卡片命令字
  64. #define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
  65. #define PICC_REQALL           0x52               //寻天线区内全部卡
  66. #define PICC_ANTICOLL1        0x93               //防冲撞
  67. #define PICC_ANTICOLL2        0x95               //防冲撞
  68. #define PICC_AUTHENT1A        0x60               //验证A密钥
  69. #define PICC_AUTHENT1B        0x61               //验证B密钥
  70. #define PICC_READ             0x30               //读块
  71. #define PICC_WRITE            0xA0               //写块
  72. #define PICC_DECREMENT        0xC0               //扣款
  73. #define PICC_INCREMENT        0xC1               //充值
  74. #define PICC_RESTORE          0xC2               //调块数据到缓冲区
  75. #define PICC_TRANSFER         0xB0               //保存缓冲区中数据
  76. #define PICC_HALT             0x50               //休眠

  77. // MF522 FIFO长度定义
  78. #define DEF_FIFO_LENGTH       64                 //FIFO size=64byte

  79. // MF522寄存器定义
  80. // PAGE 0
  81. #define     RFU00                 0x00   
  82. #define     CommandReg            0x01   
  83. #define     ComIEnReg             0x02   
  84. #define     DivlEnReg             0x03   
  85. #define     ComIrqReg             0x04   
  86. #define     DivIrqReg             0x05
  87. #define     ErrorReg              0x06   
  88. #define     Status1Reg            0x07   
  89. #define     Status2Reg            0x08   
  90. #define     FIFODataReg           0x09
  91. #define     FIFOLevelReg          0x0A
  92. #define     WaterLevelReg         0x0B
  93. #define     ControlReg            0x0C
  94. #define     BitFramingReg         0x0D
  95. #define     CollReg               0x0E
  96. #define     RFU0F                 0x0F
  97. // PAGE 1     
  98. #define     RFU10                 0x10
  99. #define     ModeReg               0x11
  100. #define     TxModeReg             0x12
  101. #define     RxModeReg             0x13
  102. #define     TxControlReg          0x14
  103. #define     TxAutoReg             0x15
  104. #define     TxSelReg              0x16
  105. #define     RxSelReg              0x17
  106. #define     RxThresholdReg        0x18
  107. #define     DemodReg              0x19
  108. #define     RFU1A                 0x1A
  109. #define     RFU1B                 0x1B
  110. #define     MifareReg             0x1C
  111. #define     RFU1D                 0x1D
  112. #define     RFU1E                 0x1E
  113. #define     SerialSpeedReg        0x1F
  114. // PAGE 2   
  115. #define     RFU20                 0x20  
  116. #define     CRCResultRegM         0x21
  117. #define     CRCResultRegL         0x22
  118. #define     RFU23                 0x23
  119. #define     ModWidthReg           0x24
  120. #define     RFU25                 0x25
  121. #define     RFCfgReg              0x26
  122. #define     GsNReg                0x27
  123. #define     CWGsCfgReg            0x28
  124. #define     ModGsCfgReg           0x29
  125. #define     TModeReg              0x2A
  126. #define     TPrescalerReg         0x2B
  127. #define     TReloadRegH           0x2C
  128. #define     TReloadRegL           0x2D
  129. #define     TCounterValueRegH     0x2E
  130. #define     TCounterValueRegL     0x2F
  131. // PAGE 3      
  132. #define     RFU30                 0x30
  133. #define     TestSel1Reg           0x31
  134. #define     TestSel2Reg           0x32
  135. #define     TestPinEnReg          0x33
  136. #define     TestPinValueReg       0x34
  137. #define     TestBusReg            0x35
  138. #define     AutoTestReg           0x36
  139. #define     VersionReg            0x37
  140. #define     AnalogTestReg         0x38
  141. #define     TestDAC1Reg           0x39  
  142. #define     TestDAC2Reg           0x3A   
  143. #define     TestADCReg            0x3B   
  144. #define     RFU3C                 0x3C   
  145. #define     RFU3D                 0x3D   
  146. #define     RFU3E                 0x3E   
  147. #define     RFU3F                          0x3F


  148. #define     REQ_ALL               0x52
  149. #define     KEYA                  0x60

  150. // 和MF522通讯时返回的错误代码
  151. #define MI_OK                          (char)0
  152. #define MI_NOTAGERR                    (char)(-1)
  153. #define MI_ERR                         (char)(-2)

  154. #endif
  155. </font>
复制代码

RC522.c

  1. <font face="微软雅黑" size="3">#include "RC522.H"
  2. #include "stm32f10x_gpio.h"

  3. #define MAXRLEN 18                        

  4. void PcdInit()
  5. {
  6.           GPIO_InitTypeDef  GPIO_InitStructure;

  7.           /* Enable the GPIO Clock */
  8.           RCC_APB2PeriphClockCmd(MF522_RST_CLK, ENABLE);

  9.           /* Configure the GPIO pin */
  10.           GPIO_InitStructure.GPIO_Pin = MF522_RST_PIN;
  11.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  12.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  13.           GPIO_Init(MF522_RST_PORT, &GPIO_InitStructure);

  14.           /* Enable the GPIO Clock */
  15.           RCC_APB2PeriphClockCmd(MF522_MISO_CLK, ENABLE);

  16.           /* Configure the GPIO pin */
  17.           GPIO_InitStructure.GPIO_Pin = MF522_MISO_PIN;
  18.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  19.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  20.           GPIO_Init(MF522_MISO_PORT, &GPIO_InitStructure);

  21.           /* Enable the GPIO Clock */
  22.           RCC_APB2PeriphClockCmd(MF522_MOSI_CLK, ENABLE);

  23.           /* Configure the GPIO pin */
  24.           GPIO_InitStructure.GPIO_Pin = MF522_MOSI_PIN;
  25.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  26.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  27.           GPIO_Init(MF522_MOSI_PORT, &GPIO_InitStructure);

  28.           /* Enable the GPIO Clock */
  29.           RCC_APB2PeriphClockCmd(MF522_SCK_CLK, ENABLE);

  30.           /* Configure the GPIO pin */
  31.           GPIO_InitStructure.GPIO_Pin = MF522_SCK_PIN;
  32.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  33.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  34.           GPIO_Init(MF522_SCK_PORT, &GPIO_InitStructure);

  35.           /* Enable the GPIO Clock */
  36.           RCC_APB2PeriphClockCmd(MF522_NSS_CLK, ENABLE);

  37.           /* Configure the GPIO pin */
  38.           GPIO_InitStructure.GPIO_Pin = MF522_NSS_PIN;
  39.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  40.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  41.           GPIO_Init(MF522_NSS_PORT, &GPIO_InitStructure);
  42. }

  43. //功    能:寻卡
  44. //参数说明: req_code[IN]:寻卡方式
  45. //                0x52 = 寻感应区内所有符合14443A标准的卡
  46. //                0x26 = 寻未进入休眠状态的卡
  47. //                    pTagType[OUT]:卡片类型代码
  48. //                0x4400 = Mifare_UltraLight
  49. //                0x0400 = Mifare_One(S50)
  50. //                0x0200 = Mifare_One(S70)
  51. //                0x0800 = Mifare_Pro(X)
  52. //                0x4403 = Mifare_DESFire
  53. //返    回: 成功返回MI_OK
  54. char PcdRequest(unsigned char req_code,unsigned char *pTagType)
  55. {
  56.    char status;  
  57.    unsigned int  unLen;
  58.    unsigned char ucComMF522Buf[MAXRLEN];
  59. //  unsigned char xTest ;
  60.    ClearBitMask(Status2Reg,0x08);
  61.    WriteRawRC(BitFramingReg,0x07);

  62. //  xTest = ReadRawRC(BitFramingReg);
  63. //  if(xTest == 0x07 )
  64. //   { LED_GREEN  =0 ;}
  65. // else {LED_GREEN =1 ;while(1){}}
  66.    SetBitMask(TxControlReg,0x03);

  67.    ucComMF522Buf[0] = req_code;

  68.    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
  69. //     if(status  == MI_OK )
  70. //   { LED_GREEN  =0 ;}
  71. //   else {LED_GREEN =1 ;}
  72.    if ((status == MI_OK) && (unLen == 0x10))
  73.    {   
  74.        *pTagType     = ucComMF522Buf[0];
  75.        *(pTagType+1) = ucComMF522Buf[1];
  76.    }
  77.    else
  78.    {   status = MI_ERR;   }
  79.    
  80.    return status;
  81. }

  82. //功    能:防冲撞
  83. //参数说明: pSnr[OUT]:卡片序列号,4字节
  84. //返    回: 成功返回MI_OK
  85. char PcdAnticoll(unsigned char *pSnr)
  86. {
  87.     char status;
  88.     unsigned char i,snr_check=0;
  89.     unsigned int  unLen;
  90.     unsigned char ucComMF522Buf[MAXRLEN];
  91.    

  92.     ClearBitMask(Status2Reg,0x08);
  93.     WriteRawRC(BitFramingReg,0x00);
  94.     ClearBitMask(CollReg,0x80);

  95.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  96.     ucComMF522Buf[1] = 0x20;

  97.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

  98.     if (status == MI_OK)
  99.     {
  100.              for (i=0; i<4; i++)
  101.          {   
  102.              *(pSnr+i)  = ucComMF522Buf[i];
  103.              snr_check ^= ucComMF522Buf[i];
  104.          }
  105.          if (snr_check != ucComMF522Buf[i])
  106.          {   status = MI_ERR;    }
  107.     }
  108.    
  109.     SetBitMask(CollReg,0x80);
  110.     return status;
  111. }

  112. //功    能:选定卡片
  113. //参数说明: pSnr[IN]:卡片序列号,4字节
  114. //返    回: 成功返回MI_OK
  115. char PcdSelect(unsigned char *pSnr)
  116. {
  117.     char status;
  118.     unsigned char i;
  119.     unsigned int  unLen;
  120.     unsigned char ucComMF522Buf[MAXRLEN];
  121.    
  122.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  123.     ucComMF522Buf[1] = 0x70;
  124.     ucComMF522Buf[6] = 0;
  125.     for (i=0; i<4; i++)
  126.     {
  127.             ucComMF522Buf[i+2] = *(pSnr+i);
  128.             ucComMF522Buf[6]  ^= *(pSnr+i);
  129.     }
  130.     CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
  131.   
  132.     ClearBitMask(Status2Reg,0x08);

  133.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
  134.    
  135.     if ((status == MI_OK) && (unLen == 0x18))
  136.     {   status = MI_OK;  }
  137.     else
  138.     {   status = MI_ERR;    }

  139.     return status;
  140. }

  141. //功    能:验证卡片密码
  142. //参数说明: auth_mode[IN]: 密码验证模式
  143. //                 0x60 = 验证A密钥
  144. //                 0x61 = 验证B密钥
  145. //          addr[IN]:块地址
  146. //          pKey[IN]:密码
  147. //          pSnr[IN]:卡片序列号,4字节
  148. //返    回: 成功返回MI_OK      
  149. char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
  150. {
  151.     char status;
  152.     unsigned int  unLen;
  153.     unsigned char i,ucComMF522Buf[MAXRLEN];

  154.     ucComMF522Buf[0] = auth_mode;
  155.     ucComMF522Buf[1] = addr;
  156.     for (i=0; i<6; i++)
  157.     {    ucComMF522Buf[i+2] = *(pKey+i);   }
  158.     for (i=0; i<6; i++)
  159.     {    ucComMF522Buf[i+8] = *(pSnr+i);   }
  160. //   memcpy(&ucComMF522Buf[2], pKey, 6);
  161. //   memcpy(&ucComMF522Buf[8], pSnr, 4);
  162.    
  163.     status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
  164.     if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
  165.     {   status = MI_ERR;   }
  166.    
  167.     return status;
  168. }

  169. //功    能:读取M1卡一块数据
  170. //参数说明: addr[IN]:块地址
  171. //          pData[OUT]:读出的数据,16字节
  172. //返    回: 成功返回MI_OK
  173. char PcdRead(unsigned char addr,unsigned char *pData)
  174. {
  175.     char status;
  176.     unsigned int  unLen;
  177.     unsigned char i,ucComMF522Buf[MAXRLEN];

  178.     ucComMF522Buf[0] = PICC_READ;
  179.     ucComMF522Buf[1] = addr;
  180.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
  181.    
  182.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
  183.     if ((status == MI_OK) && (unLen == 0x90))
  184. //   {   memcpy(pData, ucComMF522Buf, 16);   }
  185.     {
  186.         for (i=0; i<16; i++)
  187.         {    *(pData+i) = ucComMF522Buf[i];   }
  188.     }
  189.     else
  190.     {   status = MI_ERR;   }
  191.    
  192.     return status;
  193. }

  194. //功    能:写数据到M1卡一块
  195. //参数说明: addr[IN]:块地址
  196. //          pData[IN]:写入的数据,16字节
  197. //返    回: 成功返回MI_OK         
  198. char PcdWrite(unsigned char addr,unsigned char *pData)
  199. {
  200.     char status;
  201.     unsigned int  unLen;
  202.     unsigned char i,ucComMF522Buf[MAXRLEN];
  203.    
  204.     ucComMF522Buf[0] = PICC_WRITE;
  205.     ucComMF522Buf[1] = addr;
  206.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

  207.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

  208.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  209.     {   status = MI_ERR;   }
  210.         
  211.     if (status == MI_OK)
  212.     {
  213.         //memcpy(ucComMF522Buf, pData, 16);

  214.         for (i=0; i<16; i++)
  215.         {    ucComMF522Buf[i] = *(pData+i);   }
  216.         CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

  217.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);
  218.         if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  219.         {   status = MI_ERR;   }
  220.     }
  221.    
  222.     return status;
  223. }

  224. //功    能:命令卡片进入休眠状态
  225. //返    回: 成功返回MI_OK
  226. char PcdHalt(void)
  227. {
  228.     unsigned int  unLen;
  229.     unsigned char ucComMF522Buf[MAXRLEN];

  230.     ucComMF522Buf[0] = PICC_HALT;
  231.     ucComMF522Buf[1] = 0;
  232.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

  233.     PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

  234.     return MI_OK;
  235. }

  236. //用MF522计算CRC16函数
  237. void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
  238. {
  239.     unsigned char i,n;
  240.     ClearBitMask(DivIrqReg,0x04);
  241.     WriteRawRC(CommandReg,PCD_IDLE);
  242.     SetBitMask(FIFOLevelReg,0x80);
  243.     for (i=0; i<len; i++)
  244.     {   WriteRawRC(FIFODataReg, *(pIndata+i));   }
  245.     WriteRawRC(CommandReg, PCD_CALCCRC);
  246.     i = 0xFF;
  247.     do
  248.     {
  249.         n = ReadRawRC(DivIrqReg);
  250.         i--;
  251.     }
  252.     while ((i!=0) && !(n&0x04));
  253.     pOutData[0] = ReadRawRC(CRCResultRegL);
  254.     pOutData[1] = ReadRawRC(CRCResultRegM);
  255. }

  256. //功    能:复位RC522
  257. //返    回: 成功返回MI_OK
  258. char PcdReset(void)
  259. {
  260.     RST_H;
  261.     delay_10ms(1);
  262.     RST_L;
  263.     delay_10ms(1);
  264.     RST_H;
  265.           delay_10ms(10);
  266.        
  267.                 if(ReadRawRC(0x02) == 0x80)
  268.                 {
  269.                 }

  270.     WriteRawRC(CommandReg,PCD_RESETPHASE);
  271.    
  272.     WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
  273.     WriteRawRC(TReloadRegL,30);           
  274.     WriteRawRC(TReloadRegH,0);
  275.     WriteRawRC(TModeReg,0x8D);
  276.     WriteRawRC(TPrescalerReg,0x3E);
  277.     WriteRawRC(TxAutoReg,0x40);     
  278.     return MI_OK;
  279. }

  280. //设置RC632的工作方式
  281. char M500PcdConfigISOType(unsigned char type)
  282. {
  283.    if (type == 'A')                     //ISO14443_A
  284.    {
  285.        ClearBitMask(Status2Reg,0x08);

  286. /*     WriteRawRC(CommandReg,0x20);    //as default   
  287.        WriteRawRC(ComIEnReg,0x80);     //as default
  288.        WriteRawRC(DivlEnReg,0x0);      //as default
  289.            WriteRawRC(ComIrqReg,0x04);     //as default
  290.            WriteRawRC(DivIrqReg,0x0);      //as default
  291.            WriteRawRC(Status2Reg,0x0);//80    //trun off temperature sensor
  292.            WriteRawRC(WaterLevelReg,0x08); //as default
  293.        WriteRawRC(ControlReg,0x20);    //as default
  294.            WriteRawRC(CollReg,0x80);    //as default
  295. */
  296.        WriteRawRC(ModeReg,0x3D);//3F
  297. /*           WriteRawRC(TxModeReg,0x0);      //as default???
  298.            WriteRawRC(RxModeReg,0x0);      //as default???
  299.            WriteRawRC(TxControlReg,0x80);  //as default???
  300.            WriteRawRC(TxSelReg,0x10);      //as default???
  301.    */
  302.        WriteRawRC(RxSelReg,0x86);//84
  303. //      WriteRawRC(RxThresholdReg,0x84);//as default
  304. //      WriteRawRC(DemodReg,0x4D);      //as default

  305. //      WriteRawRC(ModWidthReg,0x13);//26
  306.        WriteRawRC(RFCfgReg,0x7F);   //4F
  307.         /*   WriteRawRC(GsNReg,0x88);        //as default???
  308.            WriteRawRC(CWGsCfgReg,0x20);    //as default???
  309.        WriteRawRC(ModGsCfgReg,0x20);   //as default???
  310. */
  311.               WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
  312.            WriteRawRC(TReloadRegH,0);
  313.        WriteRawRC(TModeReg,0x8D);
  314.            WriteRawRC(TPrescalerReg,0x3E);
  315.           

  316.   //     PcdSetTmo(106);
  317.            delay_10ms(1);
  318.        PcdAntennaOn();
  319.    }
  320.    else{ return (char)-1; }
  321.    
  322.    return MI_OK;
  323. }

  324. //功    能:读RC632寄存器
  325. //参数说明:Address[IN]:寄存器地址
  326. //返    回:读出的值
  327. unsigned char ReadRawRC(unsigned char Address)
  328. {
  329.      unsigned char i, ucAddr;
  330.      unsigned char ucResult=0;

  331.      NSS_L;
  332.      ucAddr = ((Address<<1)&0x7E)|0x80;

  333.      for(i=8;i>0;i--)
  334.      {
  335.          SCK_L;
  336.                   if(ucAddr&0x80)
  337.                  MOSI_H;
  338.                  else
  339.                                  MOSI_L;
  340.          SCK_H;
  341.          ucAddr <<= 1;
  342.      }

  343.      for(i=8;i>0;i--)
  344.      {
  345.          SCK_L;
  346.          ucResult <<= 1;
  347.          SCK_H;
  348.                  if(READ_MISO == 1)
  349.                  ucResult |= 1;
  350.      }

  351.      NSS_H;
  352.      SCK_H;
  353.      return ucResult;
  354. }

  355. //功    能:写RC632寄存器
  356. //参数说明:Address[IN]:寄存器地址
  357. //          value[IN]:写入的值
  358. void WriteRawRC(unsigned char Address, unsigned char value)
  359. {  
  360.     unsigned char i, ucAddr;

  361.     SCK_L;
  362.     NSS_L;
  363.     ucAddr = ((Address<<1)&0x7E);

  364.     for(i=8;i>0;i--)
  365.     {
  366.                 if(ucAddr&0x80)
  367.                 MOSI_H;
  368.                 else
  369.                         MOSI_L;
  370.         SCK_H;
  371.         ucAddr <<= 1;
  372.         SCK_L;
  373.     }

  374.     for(i=8;i>0;i--)
  375.     {
  376.                 if(value&0x80)
  377.                 MOSI_H;
  378.                 else
  379.                         MOSI_L;
  380.         SCK_H;
  381.         value <<= 1;
  382.         SCK_L;
  383.     }
  384.     NSS_H;
  385.     SCK_H;
  386. }

  387. //功    能:置RC522寄存器位
  388. //参数说明:reg[IN]:寄存器地址
  389. //          mask[IN]:置位值
  390. void SetBitMask(unsigned char reg,unsigned char mask)  
  391. {
  392.     char tmp = 0x0;
  393.     tmp = ReadRawRC(reg);
  394.     WriteRawRC(reg,tmp | mask);  // set bit mask
  395. }

  396. //功    能:清RC522寄存器位
  397. //参数说明:reg[IN]:寄存器地址
  398. //          mask[IN]:清位值
  399. void ClearBitMask(unsigned char reg,unsigned char mask)  
  400. {
  401.     char tmp = 0x0;
  402.     tmp = ReadRawRC(reg);
  403.     WriteRawRC(reg, tmp & ~mask);  // clear bit mask
  404. }

  405. //功    能:通过RC522和ISO14443卡通讯
  406. //参数说明:Command[IN]:RC522命令字
  407. //          pInData[IN]:通过RC522发送到卡片的数据
  408. //          InLenByte[IN]:发送数据的字节长度
  409. //          pOutData[OUT]:接收到的卡片返回数据
  410. //          *pOutLenBit[OUT]:返回数据的位长度
  411. char PcdComMF522(unsigned char Command,
  412.                  unsigned char *pInData,
  413.                  unsigned char InLenByte,
  414.                  unsigned char *pOutData,
  415.                  unsigned int  *pOutLenBit)
  416. {
  417.     char status = MI_ERR;
  418.     unsigned char irqEn   = 0x00;
  419.     unsigned char waitFor = 0x00;
  420.     unsigned char lastBits;
  421.     unsigned char n;
  422.     unsigned int i;
  423.     switch (Command)
  424.     {
  425.        case PCD_AUTHENT:
  426.           irqEn   = 0x12;
  427.           waitFor = 0x10;
  428.           break;
  429.        case PCD_TRANSCEIVE:
  430.           irqEn   = 0x77;
  431.           waitFor = 0x30;
  432.           break;
  433.        default:
  434.          break;
  435.     }
  436.    
  437.     WriteRawRC(ComIEnReg,irqEn|0x80);
  438.     ClearBitMask(ComIrqReg,0x80);
  439.     WriteRawRC(CommandReg,PCD_IDLE);
  440.     SetBitMask(FIFOLevelReg,0x80);
  441.    
  442.     for (i=0; i<InLenByte; i++)
  443.     {   WriteRawRC(FIFODataReg, pInData[i]);    }
  444.     WriteRawRC(CommandReg, Command);
  445.    
  446.    
  447.     if (Command == PCD_TRANSCEIVE)
  448.     {    SetBitMask(BitFramingReg,0x80);  }
  449.    
  450. //    i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
  451. i = 2000;
  452.     do
  453.     {
  454.          n = ReadRawRC(ComIrqReg);
  455.          i--;
  456.     }
  457.     while ((i!=0) && !(n&0x01) && !(n&waitFor));
  458.     ClearBitMask(BitFramingReg,0x80);
  459.              
  460.     if (i!=0)
  461.     {   
  462.          if(!(ReadRawRC(ErrorReg)&0x1B))
  463.          {
  464.              status = MI_OK;
  465.              if (n & irqEn & 0x01)
  466.              {   status = MI_NOTAGERR;   }
  467.              if (Command == PCD_TRANSCEIVE)
  468.              {
  469.                        n = ReadRawRC(FIFOLevelReg);
  470.                       lastBits = ReadRawRC(ControlReg) & 0x07;
  471.                 if (lastBits)
  472.                 {   *pOutLenBit = (n-1)*8 + lastBits;   }
  473.                 else
  474.                 {   *pOutLenBit = n*8;   }
  475.                 if (n == 0)
  476.                 {   n = 1;    }
  477.                 if (n > MAXRLEN)
  478.                 {   n = MAXRLEN;   }
  479.                 for (i=0; i<n; i++)
  480.                 {   pOutData[i] = ReadRawRC(FIFODataReg);    }
  481.             }
  482.          }
  483.          else
  484.          {   status = MI_ERR;   }
  485.         
  486.    }
  487.    

  488.    SetBitMask(ControlReg,0x80);           // stop timer now
  489.    WriteRawRC(CommandReg,PCD_IDLE);
  490.    return status;
  491. }

  492. //开启天线  
  493. //每次启动或关闭天险发射之间应至少有1ms的间隔
  494. void PcdAntennaOn()
  495. {
  496.     unsigned char i;
  497.     i = ReadRawRC(TxControlReg);
  498.     if (!(i & 0x03))
  499.     {
  500.         SetBitMask(TxControlReg, 0x03);
  501.     }
  502. }

  503. //关闭天线
  504. void PcdAntennaOff()
  505. {
  506.     ClearBitMask(TxControlReg, 0x03);
  507. }

  508. //等待卡离开
  509. void WaitCardOff(void)
  510. {
  511.         char          status;
  512.   unsigned char        TagType[2];

  513.         while(1)
  514.         {
  515.                 status = PcdRequest(REQ_ALL, TagType);
  516.                 if(status)
  517.                 {
  518.                         status = PcdRequest(REQ_ALL, TagType);
  519.                         if(status)
  520.                         {
  521.                                 status = PcdRequest(REQ_ALL, TagType);
  522.                                 if(status)
  523.                                 {
  524.                                         return;
  525.                                 }
  526.                         }
  527.                 }
  528.                 delay_10ms(10);
  529.         }
  530. }

  531. // Delay 10ms
  532. void delay_10ms(unsigned int _10ms)
  533. {
  534.         unsigned int i, j;

  535.         for(i=0; i<_10ms; i++)
  536.         {
  537.                 for(j=0; j<60000; j++);
  538.         }
  539. }</font>
复制代码




收藏 评论1 发布时间:2021-7-9 10:03

举报

1个回答
寒门过河卒 回答时间:2021-7-12 10:33:40
RC522手册里说支持14443智能卡协议,有研究没?

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版