12345下一页
返回列表 发新帖我要提问本帖赏金: 50.00元(功能说明)

[STM32F1] 从0开始设计_基于STM32F1的RC522读写卡

[复制链接]
 楼主| 二哲科技 发表于 2022-4-17 09:43 | 显示全部楼层 |阅读模式
<
#申请原创# @21小跑堂

1.介绍
看网上很多RC522的教程都是基于读卡ID的,这个对于很多应用来说其实没有什么用,最近刚好有个项目需要读写卡,而RC522又是非常常用的且不容易缺货的芯片,所以准备用RC522来进行读写卡。
2.设备准备
首先准备一个开发板和一个RC522模块,开发板这里我选择正点原子的精英板(STM32F103ZET6),具体如下板子如下图1所示。
1.jpg

图1

接下来就是接线,我选择的是SPI2,对应的接线如下:
RST   -->  PC4
MISO -->  PB14
MOSI -->  PB15
SCK   -->  PB13
SDA   -->  PB0
上面是硬件名称的相应接口,对于SPI来说SDA就是SPI的CS(片选)线,记得RC522模块的供电采用3.3V,可别接成5V了。
3.工程配置
首先打开外部时钟,配置如下图2所示。
2.png

图2

根据外部晶振配置对应的外部晶振频率,设置为最大的72MB。
3.png

图3

配置SPI2,首先配置位数,频率,以及模式,片选采用软件方式。
4.png

图4

接下来配置引脚,由于片选已经采用软件的方式,所以只需要配置MISO,MOSI和SCK了。
5.png

图5

RST和CS直接采用GPIO的配置。
6.png

图6

最后配置一下UART即可,选择115200波特率,引脚默认。
7.png

图7

设置完成之后,所有引脚如图8所示。
8.png

图8

4.程序编写
首先需要导入RC522的库,只有两个文件分别是【RC522.c】和【RC522.h】。
接下来修改RC522.c中的硬件接口,将SPI读写修改成如下代码。
  1. #include "RC522.h"

  2. //三目运算符true取前面那个
  3. #define RS522_RST(N) HAL_GPIO_WritePin(RC522_RST_GPIO_Port, RC522_RST_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)
  4. #define RS522_NSS(N) HAL_GPIO_WritePin(RC522_CS_GPIO_Port, RC522_CS_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)
  5. #define osDelay HAL_Delay
  6. /**************************************************************************************
  7. * 函数名称:MFRC_Init
  8. * 功能描述:MFRC初始化
  9. * 入口参数:无
  10. * 出口参数:无
  11. * 返 回 值:无
  12. * 说    明:MFRC的SPI接口速率为0~10Mbps
  13. ***************************************************************************************/
  14. void MFRC_Init(void)
  15. {
  16.     RS522_NSS(1);
  17.     RS522_RST(1);
  18. }

  19. /**************************************************************************************
  20. * 函数名称: SPI_RW_Byte
  21. * 功能描述: 模拟SPI读写一个字节
  22. * 入口参数: -byte:要发送的数据
  23. * 出口参数: -byte:接收到的数据
  24. ***************************************************************************************/
  25. static uint8_t ret;       //些函数是HAL与标准库不同和地方,【读写函数】
  26. uint8_t SPI2_RW_Byte(uint8_t byte)
  27. {
  28.     HAL_SPI_TransmitReceive(&hspi2, &byte, &ret, 1, 10);//把byte写入,并读出一个值 存入ret
  29.     return   ret;                 //入口是byte的地址,读取时用的也是ret的地址;1:一次只写入一个值 10:timeout     
  30. }   

  31. /**************************************************************************************
  32. * 函数名称:MFRC_WriteReg
  33. * 功能描述:写一个寄存器
  34. * 入口参数:-addr:待写的寄存器地址
  35. *           -data:待写的寄存器数据
  36. * 出口参数:无
  37. * 返 回 值:无
  38. * 说    明:无
  39. ***************************************************************************************/
  40. void MFRC_WriteReg(uint8_t addr, uint8_t data)
  41. {
  42.     uint8_t AddrByte;
  43.     AddrByte = (addr << 1 ) & 0x7E; //求出地址字节
  44.     RS522_NSS(0);                   //NSS拉低
  45.     SPI2_RW_Byte(AddrByte);         //写地址字节
  46.     SPI2_RW_Byte(data);             //写数据
  47.     RS522_NSS(1);                   //NSS拉高
  48. }


  49. /**************************************************************************************
  50. * 函数名称:MFRC_ReadReg
  51. * 功能描述:读一个寄存器
  52. * 入口参数:-addr:待读的寄存器地址
  53. * 出口参数:无
  54. * 返 回 值:-data:读到寄存器的数据
  55. * 说    明:无
  56. ***************************************************************************************/
  57. uint8_t MFRC_ReadReg(uint8_t addr)
  58. {
  59.     uint8_t AddrByte, data;
  60.     AddrByte = ((addr << 1 ) & 0x7E ) | 0x80;   //求出地址字节
  61.     RS522_NSS(0);                               //NSS拉低
  62.     SPI2_RW_Byte(AddrByte);                     //写地址字节
  63.     data = SPI2_RW_Byte(0x00);                  //读数据
  64.     RS522_NSS(1);                               //NSS拉高
  65.     return data;
  66. }
其他接口保持不变,我们来看一下RC522提供的接口和指令有哪些。
  1. #ifndef _RC522_H
  2. #define _RC522_H

  3. //头文件
  4. //************************************************
  5. #include "gpio.h"//要一些引脚上的宏定义
  6. #include "spi.h"//硬件SPI的定义
  7. #include "printf.h"
  8. #include "main.h"//Laber User上的宏定义
  9. //************************************************

  10. //MFRC522驱动程序
  11. //************************************************

  12. /*MFRC522寄存器定义*/
  13. //PAGE0
  14. #define MFRC_RFU00                      0x00   
  15. #define MFRC_CommandReg                 0x01   
  16. #define MFRC_ComIEnReg                     0x02   
  17. #define MFRC_DivlEnReg                     0x03   
  18. #define MFRC_ComIrqReg                     0x04   
  19. #define MFRC_DivIrqReg                     0x05
  20. #define MFRC_ErrorReg                      0x06   
  21. #define MFRC_Status1Reg                    0x07   
  22. #define MFRC_Status2Reg                    0x08   
  23. #define MFRC_FIFODataReg                   0x09
  24. #define MFRC_FIFOLevelReg                  0x0A
  25. #define MFRC_WaterLevelReg                 0x0B
  26. #define MFRC_ControlReg                    0x0C
  27. #define MFRC_BitFramingReg                 0x0D
  28. #define MFRC_CollReg                       0x0E
  29. #define MFRC_RFU0F                         0x0F
  30. //PAGE1     
  31. #define MFRC_RFU10                         0x10
  32. #define MFRC_ModeReg                       0x11
  33. #define MFRC_TxModeReg                     0x12
  34. #define MFRC_RxModeReg                     0x13
  35. #define MFRC_TxControlReg                  0x14
  36. #define MFRC_TxAutoReg                     0x15 //中文手册有误
  37. #define MFRC_TxSelReg                      0x16
  38. #define MFRC_RxSelReg                      0x17
  39. #define MFRC_RxThresholdReg                0x18
  40. #define MFRC_DemodReg                      0x19
  41. #define MFRC_RFU1A                         0x1A
  42. #define MFRC_RFU1B                         0x1B
  43. #define MFRC_MifareReg                     0x1C
  44. #define MFRC_RFU1D                         0x1D
  45. #define MFRC_RFU1E                         0x1E
  46. #define MFRC_SerialSpeedReg                0x1F
  47. //PAGE2   
  48. #define MFRC_RFU20                         0x20  
  49. #define MFRC_CRCResultRegM                 0x21
  50. #define MFRC_CRCResultRegL                 0x22
  51. #define MFRC_RFU23                         0x23
  52. #define MFRC_ModWidthReg                   0x24
  53. #define MFRC_RFU25                         0x25
  54. #define MFRC_RFCfgReg                      0x26
  55. #define MFRC_GsNReg                        0x27
  56. #define MFRC_CWGsCfgReg                    0x28
  57. #define MFRC_ModGsCfgReg                   0x29
  58. #define MFRC_TModeReg                      0x2A
  59. #define MFRC_TPrescalerReg                 0x2B
  60. #define MFRC_TReloadRegH                   0x2C
  61. #define MFRC_TReloadRegL                   0x2D
  62. #define MFRC_TCounterValueRegH             0x2E
  63. #define MFRC_TCounterValueRegL             0x2F
  64. //PAGE3      
  65. #define MFRC_RFU30                         0x30
  66. #define MFRC_TestSel1Reg                   0x31
  67. #define MFRC_TestSel2Reg                   0x32
  68. #define MFRC_TestPinEnReg                  0x33
  69. #define MFRC_TestPinValueReg               0x34
  70. #define MFRC_TestBusReg                    0x35
  71. #define MFRC_AutoTestReg                   0x36
  72. #define MFRC_VersionReg                    0x37
  73. #define MFRC_AnalogTestReg                 0x38
  74. #define MFRC_TestDAC1Reg                   0x39  
  75. #define MFRC_TestDAC2Reg                   0x3A   
  76. #define MFRC_TestADCReg                    0x3B   
  77. #define MFRC_RFU3C                         0x3C   
  78. #define MFRC_RFU3D                         0x3D   
  79. #define MFRC_RFU3E                         0x3E   
  80. #define MFRC_RFU3F                         0x3F

  81. /*MFRC522的FIFO长度定义*/
  82. #define MFRC_FIFO_LENGTH                       64

  83. /*MFRC522传输的帧长定义*/
  84. #define MFRC_MAXRLEN                18               

  85. /*MFRC522命令集,中文手册P59*/
  86. #define MFRC_IDLE                              0x00        //取消当前命令的执行
  87. #define MFRC_CALCCRC                           0x03    //激活CRC计算
  88. #define MFRC_TRANSMIT                          0x04    //发送FIFO缓冲区内容
  89. #define MFRC_NOCMDCHANGE            0x07        //无命令改变
  90. #define MFRC_RECEIVE                           0x08    //激活接收器接收数据
  91. #define MFRC_TRANSCEIVE                        0x0C    //发送并接收数据
  92. #define MFRC_AUTHENT                           0x0E    //执行Mifare认证(验证密钥)
  93. #define MFRC_RESETPHASE                        0x0F    //复位MFRC522

  94. /*MFRC522通讯时返回的错误代码*/
  95. #define MFRC_OK                         (char)(0)
  96. #define MFRC_NOTAGERR                    (char)(-1)
  97. #define MFRC_ERR                        (char)(-2)

  98. /*MFRC522函数声明*/
  99. void MFRC_Init(void);
  100. void MFRC_WriteReg(uint8_t addr, uint8_t data);
  101. uint8_t MFRC_ReadReg(uint8_t addr);
  102. void MFRC_SetBitMask(uint8_t addr, uint8_t mask);
  103. void MFRC_ClrBitMask(uint8_t addr, uint8_t mask);
  104. void MFRC_CalulateCRC(uint8_t *pInData, uint8_t len, uint8_t *pOutData);
  105. char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit);
  106. //********************************************************************

  107. //MFRC552与MF1卡通讯接口程序
  108. //*********************************************************************
  109. /*Mifare1卡片命令字*/
  110. #define PICC_REQIDL                   0x26                       //寻天线区内未进入休眠状态的卡
  111. #define PICC_REQALL                   0x52                       //寻天线区内全部卡
  112. #define PICC_ANTICOLL1                0x93                       //防冲撞
  113. #define PICC_ANTICOLL2                0x95                       //防冲撞
  114. #define PICC_AUTHENT1A                0x60                       //验证A密钥
  115. #define PICC_AUTHENT1B                0x61                       //验证B密钥
  116. #define PICC_READ                     0x30                       //读块
  117. #define PICC_WRITE                    0xA0                       //写块
  118. #define PICC_DECREMENT                0xC0                       //减值(扣除)
  119. #define PICC_INCREMENT                0xC1                       //增值(充值)
  120. #define PICC_TRANSFER                 0xB0                       //转存(传送)
  121. #define PICC_RESTORE                  0xC2                       //恢复(重储)
  122. #define PICC_HALT                     0x50                       //休眠

  123. /*PCD通讯时返回的错误代码*/
  124. #define PCD_OK                         (char)0                                //成功
  125. #define PCD_NOTAGERR            (char)(-1)                        //无卡
  126. #define PCD_ERR                        (char)(-2)                        //出错

  127. /*PCD函数声明*/
  128. void PCD_Init(void);//读写器初始化
  129. void PCD_Reset(void);
  130. void PCD_AntennaOn(void);
  131. void PCD_AntennaOff(void);
  132. char PCD_Request(uint8_t RequestMode, uint8_t *pCardType);  //寻卡,并返回卡的类型
  133. char PCD_Anticoll(uint8_t *pSnr);                           //防冲突,返回卡号
  134. char PCD_Select(uint8_t *pSnr);                             //选卡
  135. char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t *pKey, uint8_t *pSnr); //验证密码(密码A和密码B)   
  136. char PCD_WriteBlock(uint8_t BlockAddr, uint8_t *pData);   //写数据
  137. char PCD_ReadBlock(uint8_t BlockAddr, uint8_t *pData);    //读数据
  138. char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t *pValue);   
  139. char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr);                                 
  140. char PCD_Halt(void);
  141. //******************************************************************************************

  142. #endif
不过接下来我们需要测试一下,SPI是否正常,接上便携示波器,最近出门在外,不方便带示波器,所以带了一个LOTO的便携示波器,不过他刚好有逻辑分析仪的功能,刚好测试一下它的性能,接线图如下,需要将ChA口接到时钟线上,这样才能执行触发功能。
9.jpg

图9

然后将代码进入调试,进入读寄存器函数,在进入前打个断点,然后开启LOTO示波器的触发功能,然后运行到读取结束,可以看到读取到了【0x83】这个值。
10.png

图10

再来看看逻辑分析仪读取到的值,可以看到也是【0x83】,说明这个逻辑分析仪性能还行。
11.png

图11

SPI功能测试完了,接下来就要进行读写卡了。首先科普一下读写卡的整个过程【寻卡-》放冲撞-》选卡-》解密卡-》读/写卡】。
按照上面的流程,调用相关的函数,整体代码如下。
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  5.   * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>© Copyright (c) 2021 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "spi.h"
  23. #include "usart.h"
  24. #include "gpio.h"

  25. /* Private includes ----------------------------------------------------------*/
  26. /* USER CODE BEGIN Includes */
  27. #include "delay.h"
  28. #include "printf.h"
  29. #include "rc522.h"
  30. #include "string.h"
  31. /* USER CODE END Includes */

  32. /* Private typedef -----------------------------------------------------------*/
  33. /* USER CODE BEGIN PTD */

  34. /* USER CODE END PTD */

  35. /* Private define ------------------------------------------------------------*/
  36. /* USER CODE BEGIN PD */
  37. /* USER CODE END PD */

  38. /* Private macro -------------------------------------------------------------*/
  39. /* USER CODE BEGIN PM */

  40. /* USER CODE END PM */

  41. /* Private variables ---------------------------------------------------------*/

  42. /* USER CODE BEGIN PV */

  43. /* USER CODE END PV */

  44. /* Private function prototypes -----------------------------------------------*/
  45. void SystemClock_Config(void);
  46. /* USER CODE BEGIN PFP */

  47. /* USER CODE END PFP */

  48. /* Private user code ---------------------------------------------------------*/
  49. /* USER CODE BEGIN 0 */
  50. uint8_t key_A[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  51. char *WriteData = {"1234567890ABCDEF"};
  52. char ReadData[16] = {0};
  53. /* USER CODE END 0 */

  54. /**
  55.   * @brief  The application entry point.
  56.   * @retval int
  57.   */
  58. int main(void)
  59. {
  60.   /* USER CODE BEGIN 1 */
  61.   char pcd_err = 0;
  62.   /* USER CODE END 1 */

  63.   /* MCU Configuration--------------------------------------------------------*/

  64.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  65.   HAL_Init();

  66.   /* USER CODE BEGIN Init */

  67.   /* USER CODE END Init */

  68.   /* Configure the system clock */
  69.   SystemClock_Config();

  70.   /* USER CODE BEGIN SysInit */

  71.   /* USER CODE END SysInit */

  72.   /* Initialize all configured peripherals */
  73.   MX_GPIO_Init();
  74.   MX_USART1_UART_Init();
  75.   MX_SPI2_Init();
  76.   /* USER CODE BEGIN 2 */
  77.   //初始化
  78.   //*************************
  79.   PCD_Init();//RC522初始化
  80.   //*************************
  81.   //全局变量
  82.   //*************************
  83.   uint8_t RxBuffer[4];
  84.   char Card_ID[8];
  85.   //*************************
  86.   /* USER CODE END 2 */

  87.   /* Infinite loop */
  88.   /* USER CODE BEGIN WHILE */
  89.   while (1)
  90.   {
  91.     /* USER CODE END WHILE */

  92.     /* USER CODE BEGIN 3 */
  93.     pcd_err = PCD_Request(PICC_REQIDL, RxBuffer);//返回值为0,代表寻卡成功;并把卡类型存入RxBuffer中
  94.     if(pcd_err == PCD_OK)
  95.     {
  96.         uint16_t cardType = (RxBuffer[0] << 8) | RxBuffer[1];
  97.         
  98.         printf("卡类型:0x%04X\r\n", cardType);
  99.         
  100.         pcd_err = PCD_Anticoll(RxBuffer);   //防冲撞,完成这部就可以简单地 读取卡号,本次不涉及更高层次应用
  101.         if(pcd_err == PCD_OK)
  102.         {
  103.             sprintf(Card_ID,"%x%x%x%x",RxBuffer[0],RxBuffer[1],RxBuffer[2],RxBuffer[3]);
  104.             printf("ID=%s\r\n",Card_ID);
  105.         }
  106.         
  107.         pcd_err = PCD_Select((uint8_t *)RxBuffer);       //选卡
  108.         if(pcd_err == PCD_OK)
  109.         {
  110.             printf("Select Card OK\r\n");
  111.         }
  112.         else
  113.         {
  114.             printf("Select Card Error\r\n");
  115.         }
  116.         
  117.         pcd_err = PCD_AuthState(PICC_AUTHENT1A, 5, key_A, RxBuffer);    //解密
  118.         if(pcd_err == PCD_OK)
  119.         {
  120.             printf("Auth Card OK\r\n");
  121.         }
  122.         else
  123.         {
  124.             printf("Auth Card Error\r\n");
  125.         }
  126.         
  127.         pcd_err = PCD_WriteBlock(6, (uint8_t *)WriteData);  //写卡
  128.         if(pcd_err == PCD_OK)
  129.         {
  130.             printf("写卡成功\r\n");
  131.         }
  132.         else
  133.         {
  134.             printf("写卡失败:%d\r\n",pcd_err);
  135.         }
  136.         
  137.         HAL_Delay(1);
  138.         pcd_err = PCD_ReadBlock(6, (uint8_t *)ReadData);    //读卡
  139.         if(pcd_err == PCD_OK)
  140.         {
  141.             printf("读卡成功:%s\r\n", ReadData);
  142.         }
  143.         else
  144.         {
  145.             printf("读卡失败:%d\r\n",pcd_err);
  146.         }
  147.         
  148.         PCD_Halt();
  149.         
  150.         memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串,这里要清除RxBuffer才行
  151.         HAL_Delay(1000);
  152.     }
  153.     HAL_Delay(100);
  154.   }
  155.   /* USER CODE END 3 */
  156. }

  157. /**
  158.   * @brief System Clock Configuration
  159.   * @retval None
  160.   */
  161. void SystemClock_Config(void)
  162. {
  163.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  164.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  165.   /** Initializes the RCC Oscillators according to the specified parameters
  166.   * in the RCC_OscInitTypeDef structure.
  167.   */
  168.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  169.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  170.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  171.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  172.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  173.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  174.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  175.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  176.   {
  177.     Error_Handler();
  178.   }
  179.   /** Initializes the CPU, AHB and APB buses clocks
  180.   */
  181.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  182.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  183.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  184.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  185.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  186.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  187.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  188.   {
  189.     Error_Handler();
  190.   }
  191. }

  192. /* USER CODE BEGIN 4 */

  193. /* USER CODE END 4 */

  194. /**
  195.   * @brief  This function is executed in case of error occurrence.
  196.   * @retval None
  197.   */
  198. void Error_Handler(void)
  199. {
  200.   /* USER CODE BEGIN Error_Handler_Debug */
  201.   /* User can add his own implementation to report the HAL error return state */
  202.   __disable_irq();
  203.   printf("error\r\n");
  204.   while (1)
  205.   {
  206.   }
  207.   /* USER CODE END Error_Handler_Debug */
  208. }

  209. #ifdef  USE_FULL_ASSERT
  210. /**
  211.   * @brief  Reports the name of the source file and the source line number
  212.   *         where the assert_param error has occurred.
  213.   * @param  file: pointer to the source file name
  214.   * @param  line: assert_param error line source number
  215.   * @retval None
  216.   */
  217. void assert_failed(uint8_t *file, uint32_t line)
  218. {
  219.   /* USER CODE BEGIN 6 */
  220.   /* User can add his own implementation to report the file name and line number,
  221.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  222.   /* USER CODE END 6 */
  223. }
  224. #endif /* USE_FULL_ASSERT */

  225. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
代码是先进**,然后进**,再进**。关于解密,卡默认的密码是【FFFFFFFFFFFF】,一共是6个【0xFF】。
最终的输出结果如下图12所示,写入【“1234567890ABCDEF”】内容,读出的也是【“1234567890ABCDEF”】内容。
12.png

图12

5.总结
SPI配置下来还是比较简单的,这个工程最主要的还是得读懂RC522的工作流程,如果能对IC卡进行读写,项目的基本功能就实现了,后续只要调用相关的接口接可以了,这次的分享就到这里了!
项目工程(由于分卷原因,需要重新命名,把.00x放在.zip后面): RC522.001.zip (9 MB, 下载次数: 32) RC522.002.zip (7.62 MB, 下载次数: 27)

打赏榜单

21小跑堂 打赏了 50.00 元 2022-04-21
理由:恭喜通过原创文章审核!请多多加油哦!

评论

代码详细,备注清晰。对于首次接触该射频卡的坛友具备参考一定的参考价值。但是功能有些单一,对于用卡的逻辑处理所做完善度有待加强~  发表于 2022-4-21 16:04
mutable 发表于 2022-4-28 14:51 | 显示全部楼层
这是?
射频卡么
ccmj4708 发表于 2022-4-28 21:33 | 显示全部楼层
问一下,这个压缩包解压错误
问天少年 发表于 2022-4-28 22:14 | 显示全部楼层
有没有错误返回代码呀,
littlelida 发表于 2022-4-29 14:34 | 显示全部楼层
射频卡价格一般在多少
ulystronglll 发表于 2022-5-29 08:34 | 显示全部楼层
spi读写数据,简单可靠一些。
claretttt 发表于 2022-5-29 09:53 | 显示全部楼层
RC522如何读写卡?
geraldbetty 发表于 2022-5-29 11:43 | 显示全部楼层
RC522效果怎么样?
carpsnow 发表于 2022-5-29 15:36 | 显示全部楼层
挺不错啊~
xiaoyaodz 发表于 2022-5-29 19:28 | 显示全部楼层
有的时候读不到卡,这个是什么问题呢?
rosemoore 发表于 2022-6-7 11:36 | 显示全部楼层
RC522可以用哪些元件来组合?
robincotton 发表于 2022-6-7 11:44 | 显示全部楼层
RC522的最大读取距离是多少呢?
alvpeg 发表于 2022-6-7 17:36 | 显示全部楼层
RC522发射的射频信号频率是多少?
maudlu 发表于 2022-6-20 17:31 | 显示全部楼层
rc522 怎么搞增加感应距离
beacherblack 发表于 2022-6-20 18:26 | 显示全部楼层
单片机程序怎么样?
1988020566 发表于 2022-6-22 20:41 | 显示全部楼层
之前用过RC522 ,只是读取卡号而已。   
minzisc 发表于 2022-6-22 21:58 | 显示全部楼层
rc500引脚与rc522引脚有区别吗
typeof 发表于 2022-6-23 20:08 | 显示全部楼层
rc522射频卡,寻卡的时候很不稳定怎么办
bestwell 发表于 2022-6-24 11:24 | 显示全部楼层
mfrc522模块可以接5v单片机吗
sdlls 发表于 2022-6-24 12:30 | 显示全部楼层
为什么RC522的IRQ要空置
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

175

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部