找回密码
 注册

QQ登录

只需一步,快速开始

搜索

stm32 rc522射频模块程序

[复制链接]
coolice 发表于 2021-8-14 01:20:02 | 显示全部楼层 |阅读模式
射频模块程序源码: RFID_RC522.zip (7.22 MB, 售价: 2 E币)
部分源码如下,完整源码见附件
  1. u8 SPIWriteByte(u8 Byte)
  2. {
  3.         while((SPI2->SR&0X02)==0);                //等待发送区空         
  4.         SPI2->DR=Byte;                             //发送一个byte   
  5.         while((SPI2->SR&0X01)==0);      //等待接收完一个byte  
  6.         return SPI2->DR;                      //返回收到的数据                       
  7. }

  8. //SPIx 读写一个字节
  9. //TxData:要写入的字节
  10. //返回值:读取到的字节
  11. u8 SPI2_ReadWriteByte(u8 TxData)
  12. {               
  13.         u8 retry=0;                                       
  14.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
  15.                 {
  16.                 retry++;
  17.                 if(retry>200)return 0;
  18.                 }                          
  19.         SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
  20.         retry=0;

  21.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
  22.                 {
  23.                 retry++;
  24.                 if(retry>200)return 0;
  25.                 }                                                              
  26.         return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据                                            
  27. }


  28. //SPI 速度设置函数
  29. //SpeedSet:
  30. //SPI_BaudRatePrescaler_2   2分频   
  31. //SPI_BaudRatePrescaler_8   8分频   
  32. //SPI_BaudRatePrescaler_16  16分频  
  33. //SPI_BaudRatePrescaler_256 256分频
  34.   
  35. void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
  36. {
  37.           assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
  38.         SPI2->CR1&=0XFFC7;
  39.         SPI2->CR1|=SPI_BaudRatePrescaler;        //设置SPI2速度
  40.         SPI_Cmd(SPI2,ENABLE);

  41. }




  42. void SPI2_Init(void)      
  43. {
  44.         GPIO_InitTypeDef GPIO_InitStructure;
  45.           SPI_InitTypeDef  SPI_InitStructure;
  46.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE );//PORTB时钟使能
  47.         RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能

  48.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;         //IO-->PF0、PF1 端口配置
  49.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  50.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  51.     GPIO_Init(GPIOF, &GPIO_InitStructure);                                         //根据设定参数初始化PF0、PF1
  52.     GPIO_ResetBits(GPIOF,GPIO_Pin_1);                                     //PF1输出低
  53.     //GPIO_SetBits(GPIOF,GPIO_Pin_0);

  54.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  55.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出
  56.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  57.         GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

  58.         GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

  59.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  60.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
  61.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
  62.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                //串行同步时钟的空闲状态为低电平
  63.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        //串行同步时钟的第一个跳变沿(上升或下降)数据被采样
  64.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  65.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
  66.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  67.         SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
  68.         SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

  69.         SPI_Cmd(SPI2, ENABLE); //使能SPI外设
  70.       
  71.         //SPI2_ReadWriteByte(0xff);//启动传输      
  72. }

  73. void InitRc522(void)
  74. {
  75.   SPI2_Init();
  76.   PcdReset();
  77.   PcdAntennaOff();
  78.   delay_ms(2);  
  79.   PcdAntennaOn();
  80.   M500PcdConfigISOType( 'A' );
  81. }
  82. void Reset_RC522(void)
  83. {
  84.   PcdReset();
  85.   PcdAntennaOff();
  86.   delay_ms(2);  
  87.   PcdAntennaOn();
  88. }                        
  89. /////////////////////////////////////////////////////////////////////
  90. //功    能:寻卡
  91. //参数说明: req_code[IN]:寻卡方式
  92. //                0x52 = 寻感应区内所有符合14443A标准的卡
  93. //                0x26 = 寻未进入休眠状态的卡
  94. //          pTagType[OUT]:卡片类型代码
  95. //                0x4400 = Mifare_UltraLight
  96. //                0x0400 = Mifare_One(S50)
  97. //                0x0200 = Mifare_One(S70)
  98. //                0x0800 = Mifare_Pro(X)
  99. //                0x4403 = Mifare_DESFire
  100. //返    回: 成功返回MI_OK
  101. /////////////////////////////////////////////////////////////////////
  102. char PcdRequest(u8   req_code,u8 *pTagType)
  103. {
  104.         char   status;  
  105.         u8   unLen;
  106.         u8   ucComMF522Buf[MAXRLEN];

  107.         ClearBitMask(Status2Reg,0x08);
  108.         WriteRawRC(BitFramingReg,0x07);
  109.         SetBitMask(TxControlReg,0x03);

  110.         ucComMF522Buf[0] = req_code;

  111.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);

  112.         if ((status == MI_OK) && (unLen == 0x10))
  113.         {   
  114.                 *pTagType     = ucComMF522Buf[0];
  115.                 *(pTagType+1) = ucComMF522Buf[1];
  116.         }
  117.         else
  118.         {   status = MI_ERR;   }
  119.    
  120.         return status;
  121. }

  122. /////////////////////////////////////////////////////////////////////
  123. //功    能:防冲撞
  124. //参数说明: pSnr[OUT]:卡片序列号,4字节
  125. //返    回: 成功返回MI_OK
  126. /////////////////////////////////////////////////////////////////////  
  127. char PcdAnticoll(u8 *pSnr)
  128. {
  129.     char   status;
  130.     u8   i,snr_check=0;
  131.     u8   unLen;
  132.     u8   ucComMF522Buf[MAXRLEN];
  133.    

  134.     ClearBitMask(Status2Reg,0x08);
  135.     WriteRawRC(BitFramingReg,0x00);
  136.     ClearBitMask(CollReg,0x80);

  137.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  138.     ucComMF522Buf[1] = 0x20;

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

  140.     if (status == MI_OK)
  141.     {
  142.              for (i=0; i<4; i++)
  143.          {   
  144.              *(pSnr+i)  = ucComMF522Buf[i];
  145.              snr_check ^= ucComMF522Buf[i];
  146.          }
  147.          if (snr_check != ucComMF522Buf[i])
  148.          {   status = MI_ERR;    }
  149.     }
  150.    
  151.     SetBitMask(CollReg,0x80);
  152.     return status;
  153. }

  154. /////////////////////////////////////////////////////////////////////
  155. //功    能:选定卡片
  156. //参数说明: pSnr[IN]:卡片序列号,4字节
  157. //返    回: 成功返回MI_OK
  158. /////////////////////////////////////////////////////////////////////
  159. char PcdSelect(u8 *pSnr)
  160. {
  161.     char   status;
  162.     u8   i;
  163.     u8   unLen;
  164.     u8   ucComMF522Buf[MAXRLEN];
  165.    
  166.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  167.     ucComMF522Buf[1] = 0x70;
  168.     ucComMF522Buf[6] = 0;
  169.     for (i=0; i<4; i++)
  170.     {
  171.             ucComMF522Buf[i+2] = *(pSnr+i);
  172.             ucComMF522Buf[6]  ^= *(pSnr+i);
  173.     }
  174.     CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
  175.   
  176.     ClearBitMask(Status2Reg,0x08);

  177.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
  178.    
  179.     if ((status == MI_OK) && (unLen == 0x18))
  180.     {   status = MI_OK;  }
  181.     else
  182.     {   status = MI_ERR;    }

  183.     return status;
  184. }

  185. /////////////////////////////////////////////////////////////////////
  186. //功    能:验证卡片密码
  187. //参数说明: auth_mode[IN]: 密码验证模式
  188. //                 0x60 = 验证A密钥
  189. //                 0x61 = 验证B密钥
  190. //          addr[IN]:块地址
  191. //          pKey[IN]:密码
  192. //          pSnr[IN]:卡片序列号,4字节
  193. //返    回: 成功返回MI_OK
  194. /////////////////////////////////////////////////////////////////////               
  195. char PcdAuthState(u8   auth_mode,u8   addr,u8 *pKey,u8 *pSnr)
  196. {
  197.     char   status;
  198.     u8   unLen;
  199.     u8   i,ucComMF522Buf[MAXRLEN];

  200.     ucComMF522Buf[0] = auth_mode;
  201.     ucComMF522Buf[1] = addr;
  202. //    for (i=0; i<6; i++)
  203. //    {    ucComMF522Buf[i+2] = *(pKey+i);   }
  204. //    for (i=0; i<6; i++)
  205. //    {    ucComMF522Buf[i+8] = *(pSnr+i);   }
  206.     memcpy(&ucComMF522Buf[2], pKey, 6);
  207.     memcpy(&ucComMF522Buf[8], pSnr, 4);
  208.    
  209.     status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
  210.     if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
复制代码


17688798040 发表于 2021-8-14 14:10:51 | 显示全部楼层
看起来好难啊
17688798040 发表于 2021-8-14 14:12:08 | 显示全部楼层
高手的必备技能
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-25 19:36

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表