[STM32F0] 基于STM32F030实现RFID射频识别

[复制链接]
4975|110
 楼主| 个百zz分点个 发表于 2022-9-29 15:10 | 显示全部楼层
  1. // 读RC522寄存器
  2. uint8_t RC522_ReadData(uint8_t address)
  3. {
  4.         uint8_t data = 0;
  5.        
  6.         SPI2_CS_ENABLE;       
  7.         SPI2_ReadWriteByte(((address << 1) | 0x80) & 0xfe);
  8.         data = SPI2_ReadWriteByte(DUMMY_BYTE);
  9.         SPI2_CS_DISABLE;
  10.        
  11.         return data;
  12. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:11 | 显示全部楼层
在sensor_rfid.c文件中定义RC522_WriteData()函数,函数通过SPI时序实现写RC522寄存器操作
 楼主| 个百zz分点个 发表于 2022-9-29 15:12 | 显示全部楼层
  1. // 写RC522寄存器
  2. void RC522_WriteData(uint8_t address, uint8_t data)
  3. {   
  4.         SPI2_CS_ENABLE;
  5.         SPI2_ReadWriteByte((address << 1) & 0x7e);
  6.         SPI2_ReadWriteByte(data);
  7.         SPI2_CS_DISABLE;
  8. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:14 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_SetReg()函数,将RC522某寄存器进行置位
 楼主| 个百zz分点个 发表于 2022-9-29 15:15 | 显示全部楼层
  1. // 置RC522寄存器位
  2. void RC522_SetReg(uint8_t reg, uint8_t data)  
  3. {
  4.         uint8_t reg_data = RC522_ReadData(reg);
  5.         RC522_WriteData(reg, reg_data|data);  
  6. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:19 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_ClearReg()函数,将RC522某寄存器进行复位
 楼主| 个百zz分点个 发表于 2022-9-29 15:20 | 显示全部楼层
  1. // 清RC522寄存器位
  2. void RC522_ClearReg(uint8_t reg, uint8_t data)
  3. {
  4. uint8_t reg_data = RC522_ReadData(reg);
  5.           RC522_WriteData(reg, reg_data & ~data);
  6. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:23 | 显示全部楼层
在sensor_rfid.c文件中定义RC522_Reset()函数,实现对芯片进行复位。函数通过向RC522中寄存器写相应数据实现对RC522芯片的复位操作
 楼主| 个百zz分点个 发表于 2022-9-29 15:25 | 显示全部楼层
  1. // 对RCC522芯片进行复位
  2. void RC522_Reset(void)
  3. {
  4.         RC522_WriteData(CommandReg, PCD_RESETPHASE);
  5.         RC522_WriteData(ModeReg, 0x3D);           
  6.         RC522_WriteData(TReloadRegL, 30);           
  7.         RC522_WriteData(TReloadRegH, 0);
  8.         RC522_WriteData(TModeReg, 0x8D);
  9.         RC522_WriteData(TPrescalerReg, 0x3E);
  10.         RC522_WriteData(TxASKReg, 0x40);
  11. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:27 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_AntennaOn()函数,打开RC522天线
 楼主| 个百zz分点个 发表于 2022-9-29 15:28 | 显示全部楼层
// 打开天线
void RC522_AntennaOn(void)
{
if(!(RC522_ReadData(TxControlReg) & 0x03))
          {
                RC522_SetReg(TxControlReg, 0x03);
          }
}
 楼主| 个百zz分点个 发表于 2022-9-29 15:29 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_AntennaOff()函数,关闭RC522天线
  1. // 关闭天线
  2. void RC522_AntennaOff(void)
  3. {
  4.         RC522_ClearReg(TxControlReg, 0x03);
  5. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:33 | 显示全部楼层
在sensor_rfid.c文件中添加M1Card_Config()函数,实现ISO14443A型卡初始化
 楼主| 个百zz分点个 发表于 2022-9-29 15:34 | 显示全部楼层
  1. // 针对M1卡进行初始化
  2. void M1Card_Config(void)
  3. {
  4.         RC522_ClearReg(Status2Reg, 0x08);
  5.         RC522_WriteData(ModeReg, 0x3D);
  6.         RC522_WriteData(RxSelReg, 0x86);
  7.         RC522_WriteData(RFCfgReg, 0x7F);   
  8.         RC522_WriteData(TReloadRegL, 30);
  9.         RC522_WriteData(TReloadRegH, 0);
  10.         RC522_WriteData(TModeReg, 0x8D);
  11.         RC522_WriteData(TPrescalerReg, 0x3E);
  12.         RC522_AntennaOn();
  13. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:35 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_Init()函数,函数中实现了RC522复位、关闭天线、打开天线和ISO14443A型卡初始化

 楼主| 个百zz分点个 发表于 2022-9-29 15:37 | 显示全部楼层
// 初始化RC522
void RC522_Init(void)
{
RC522_Reset();        // 对RC522芯片进行复位
          RC522_AntennaOff(); // 关闭天线
          RC522_AntennaOn();        // 打开天线
          M1Card_Config(); // 针对M1卡进行初始化
}
 楼主| 个百zz分点个 发表于 2022-9-29 15:38 | 显示全部楼层
// 初始化RC522
void RC522_Init(void)
{
RC522_Reset();        // 对RC522芯片进行复位
          RC522_AntennaOff(); // 关闭天线
          RC522_AntennaOn();        // 打开天线
          M1Card_Config(); // 针对M1卡进行初始化
}
 楼主| 个百zz分点个 发表于 2022-9-29 15:39 | 显示全部楼层
在sensor_rfid.c文件中添加RC522_CardCom()函数,实现RC522和IC卡通讯,函数如下
 楼主| 个百zz分点个 发表于 2022-9-29 15:41 | 显示全部楼层
  1. // 通过RC522和ISO14443卡通讯
  2. int8_t RC522_CardCom(uint8_t Command, uint8_t *InData, uint8_t InLength, uint8_t *OutData, uint32_t *OutLength)
  3. {
  4.         uint8_t  waitFor = 0x00;
  5.         switch(Command)
  6.         {
  7.             case PCD_AUTHENT: // 验证密钥
  8.                 waitFor = 0x10; // 认证寻卡等待时间 查询空闲中断标志位
  9.                 break;
  10.             case PCD_TRANSCEIVE: // 接收发送 发送接收
  11.                 waitFor = 0x30;
  12.                 break;
  13.             default:
  14.                 break;
  15.         }

  16.         RC522_ClearReg(ComIrqReg, 0x80); // 清楚中断标志
  17.         RC522_WriteData(CommandReg, PCD_IDLE); // 关闭接收机的模拟部分,进入软关机模式,进入IDLE模式
  18.         RC522_SetReg(FIFOLevelReg, 0x80); // 清楚Fifo缓冲区及状态位

  19.         // 写数据进FIFOdata
  20.         for(uint32_t i=0; i<InLength; i++)
  21.         {
  22.             RC522_WriteData(FIFODataReg, InData[i]);
  23.         }
  24.        
  25.         // 写入命令(PCD_TRANSCEIVE:开始传输并且传输完成后自动接收数据    PCD_AUTHENT:作为读取器执行MIFARE®标准身份验证)
  26.         RC522_WriteData(CommandReg, Command);          
  27.   
  28.         if(Command == PCD_TRANSCEIVE)
  29.         {
  30.             // 开始传输数据
  31.             RC522_SetReg(BitFramingReg, 0x80);
  32.         }
  33.        
  34.         // 读取中断状态。PCD_TRANSCEIVE:等待接收完成或空闲模式  PCD_AUTHENT:等待系统进入空闲模式。
  35.         uint8_t state;
  36.         uint16_t i;
  37.         for(i=1200; i>0; i--)
  38.         {
  39.             state = RC522_ReadData(ComIrqReg);
  40.             if(state&waitFor || state&0x01)
  41.             {
  42.                 break;
  43.             }
  44.         }       
  45.         // 停止传输数据
  46.         RC522_ClearReg(BitFramingReg, 0x80);

  47.         int8_t status = MI_ERR;
  48.         if(i!=0) // 如果进入空闲模式
  49.         {   
  50.             if(!(RC522_ReadData(ErrorReg)&0x1B)) // 判断是否存在错误。FIFO溢出、位冲突、奇偶校验错误、协议错误
  51.             {
  52.                 status = MI_OK;
  53.                 if(Command == PCD_TRANSCEIVE)
  54.                 {
  55.                     // 计算输出数据长度(位)
  56.                     uint8_t number = RC522_ReadData(FIFOLevelReg); // 读FIFO中保存的字节数
  57.                     uint8_t rxLastBits = RC522_ReadData(ControlReg) & 0x07; // 最后接收到的字节的有效位数
  58.                     if(rxLastBits)
  59.                     {
  60.                         *OutLength = (number-1) * 8 + rxLastBits; // 读取到的数据总位数
  61.                     }
  62.                     else
  63.                     {
  64.                         *OutLength = number * 8; // 最后接收到的字节整个字节有效
  65.                     }
  66.                                
  67.                     // 计算输出数据长度(位)
  68.                     if(number == 0)
  69.                     {
  70.                         number = 1;
  71.                     }
  72.                     if(number > MAXRLEN)
  73.                     {
  74.                         number = MAXRLEN;
  75.                     }
  76.                     for(i=0; i<number; i++)
  77.                     {
  78.                         OutData[i] = RC522_ReadData(FIFODataReg);
  79.                     }
  80.                 }
  81.             }
  82.             else
  83.             {
  84.                 status = MI_ERR;
  85.             }
  86.         }
  87.         RC522_SetReg(ControlReg, 0x80);
  88.         RC522_WriteData(CommandReg, PCD_IDLE);
  89.         return status;
  90. }
 楼主| 个百zz分点个 发表于 2022-9-29 15:42 | 显示全部楼层
在sensor_rfid.c文件中添加Card_Find()函数,实现寻卡操作。函数将我们的寻卡命令PICC_REQIDL装填入要发送的数组,通过PcdComMF522()函数发送出去,如果此时在PCD有效范围内没有寻找到卡,则函数返回MI_ERR,若函数返回MI_OK,并且OutLen为0x10(16bit)为两个字节则说明寻卡成功,返回的两字节被装填入CardRevBuf数组
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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