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

[复制链接]
4974|110
 楼主| 个百zz分点个 发表于 2022-9-29 16:03 | 显示全部楼层
在sensor_rfid.c文件中添加RFID_Read()函数,实现从卡中读出数据

 楼主| 个百zz分点个 发表于 2022-9-29 16:04 | 显示全部楼层
int8_t RFID_Read(const uint8_t block_num, const uint8_t* passwd, uint8_t* buffer)
{       
        if(block_num < 1 || block_num > 63 || block_num % 4 == 3)
        {
            return MI_PARAM_ERR;
        }
       
        int8_t state = Card_Init(block_num, passwd);
        if(state != MI_OK)
        {
            return state;
        }
       
        return Card_Read(block_num, buffer);
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:06 | 显示全部楼层
在sensor_rfid.c文件中添加RFID_Increment()函数,实现给卡中数据充值
 楼主| 个百zz分点个 发表于 2022-9-29 16:07 | 显示全部楼层
int8_t RFID_Increment(const uint8_t block_num, const uint8_t* passwd, uint32_t value)
{
        if(block_num < 1 || block_num > 63 || block_num % 4 == 3)
        {
            return MI_PARAM_ERR;
        }
       
        int8_t state = Card_Init(block_num, passwd);
        if(state != MI_OK)
        {
            return state;
        }
       
        return Card_Adjust(PICC_INCREMENT, block_num, value);
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:07 | 显示全部楼层
在sensor_rfid.c文件中添加RFID_Decrement()函数,实现给卡中数据扣款
 楼主| 个百zz分点个 发表于 2022-9-29 16:08 | 显示全部楼层
int8_t RFID_Decrement(const uint8_t block_num, const uint8_t* passwd, uint32_t value)
{
        if(block_num < 1 || block_num > 63 || block_num % 4 == 3)
        {
            return MI_PARAM_ERR;
        }
        int8_t state = Card_Init(block_num, passwd);
        if(state != MI_OK)
        {
            return state;
        }
        return Card_Adjust(PICC_DECREMENT, block_num, value);
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:09 | 显示全部楼层
在sensor_rfid.c文件中添加RFID_ValueBlock_Init()函数,实现初始化数据块中的数据格式,用来充值和扣款
 楼主| 个百zz分点个 发表于 2022-9-29 16:10 | 显示全部楼层
int8_t RFID_ValueBlock_Init(const uint8_t block_num, const int32_t value, const uint8_t* passwd)
{
        uint8_t buffer[16] = {0};
        *((int32_t*)buffer+0) = value;
        *((int32_t*)buffer+1) = ~value;
        *((int32_t*)buffer+2) = value;
        buffer[12] = buffer[14] = block_num;
        buffer[13] = buffer[15] = ~block_num;
       
        Buzzer_Bi();
       
        return RFID_Write(block_num, passwd, buffer);
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:12 | 显示全部楼层
在main.c文件中引用相关头文件,并定义相关变量
  1. #include "sensor_rfid.h"
  2. #include "bsp_buzzer.h"
  3. #include "bsp_systick.h"
  4. #include "bsp_usart.h"
  5. #include "bsp_spi.h"

  6. extern uint8_t usart1_data;
  7. uint8_t Read_Data[16]; // 读取数据缓冲区
  8. uint8_t Card_ID[4]; // 读取卡的ID
  9. uint8_t Card_DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 验证密钥A
  10. int32_t money = 0; // 当前钱数
 楼主| 个百zz分点个 发表于 2022-9-29 16:13 | 显示全部楼层
在main.c文件中定义Error_Display()函数,实现显示错误类型
  1. void Error_Display(int8_t status)
  2. {
  3.         switch(status)
  4.         {
  5.             case -1:
  6.                 printf("Error!\r\n");
  7.                 break;
  8.             case -2:
  9.                 printf("Parameter input error!\r\n");
  10.                 break;
  11.             case -3:
  12.                 printf("Find card error!\r\n");
  13.                 break;
  14.             case -4:
  15.                 printf("Anti-collision error!\r\n");
  16.                 break;
  17.             case -5:
  18.                 printf("Selected card error!\r\n");
  19.                 break;
  20.             case -6:
  21.                 printf("Password verification error!\r\n");
  22.                 break;               
  23.         }
  24. }
 楼主| 个百zz分点个 发表于 2022-9-29 16:14 | 显示全部楼层
在main.c文件中定义Money_Increment()函数,实现向卡第4数据块中充值100元并输出充值结果
 楼主| 个百zz分点个 发表于 2022-9-29 16:15 | 显示全部楼层
// 加数据函数
void Money_Increment(void)
{
        int8_t status = 0;
        status = RFID_Increment(0x04, Card_DefaultKey, 100);
        if(status == MI_OK)
        {
            printf("Increment successfully!!\r\n");
            RFID_Read(4, Card_DefaultKey, Read_Data);
            money = *(int32_t*)Read_Data;
            printf("Money count: %d\r\n", money);
        }
        else
        {
            printf("Increment failed, ");
            Error_Display(status);
        }       
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:15 | 显示全部楼层
在main.c文件中定义Money_Decrement()函数,实现向第4数据块卡中扣款100元并输出扣款结果
  1. // 减数据函数
  2. void Money_Decrement(void)
  3. {
  4.         int8_t status = 0;
  5.         status = RFID_DECREMENT(0x04, Card_DefaultKey, 100);
  6.         if(status == MI_OK)
  7.         {
  8.             printf("Decrement successfully!!\r\n");
  9.             RFID_Read(4, Card_DefaultKey, Read_Data);
  10.             money = *(int32_t*)Read_Data;
  11.             printf("Money count: %d\r\n", money);
  12.         }
  13.         else
  14.         {
  15.             printf("Decrement failed, ");
  16.             Error_Display(status);
  17.         }               
  18. }
 楼主| 个百zz分点个 发表于 2022-9-29 16:19 | 显示全部楼层
在main.c文件中定义Read_CardID()函数,实现读取卡的ID并通过串口打印出值


 楼主| 个百zz分点个 发表于 2022-9-29 16:27 | 显示全部楼层
// 读取卡的ID
void Read_CardID(void)
{
        int8_t status = 0;
        uint32_t ID = 0;
        status = RC522_Read_ID(Card_ID);
        if(status == MI_OK)
        {
            ID = *(uint32_t*)Card_ID;
            printf("IC ID: 0x%X\r\n", ID);
        }
        else
        {
            printf("Read Card ID error, ");
            Error_Display(status);
        }
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:28 | 显示全部楼层
在main.c文件中定义Fill_Money()函数,实现向IC卡中所有数据块(不包括4)填充数据,并打印出每个扇区中填充成功的数据个数以及所有扇区填充成功的总数
 楼主| 个百zz分点个 发表于 2022-9-29 16:29 | 显示全部楼层
// 向IC卡填充数据函数
void Fill_Money(void)
{
        uint8_t Write_Data[16] = {0}; // 写入数据缓冲区
        data.blocks_total = 0;
        for(uint8_t i=5; i<64; i++)
        {
            if(i%4 == 3) // 如果是密码数据块 则跳过
            {       
                printf("Writing the %d sector, succeed number is:%d\r\n", i/4, data.blocks_of_sector);
                data.blocks_of_sector = 0;       
                continue;
            }
            memset(Write_Data, i, 16); // 填入数据到写入缓冲区
            if(RFID_Write(i, Card_DefaultKey, Write_Data) == MI_OK)
            {
                data.blocks_of_sector++; // 当前扇区成功写入次数       
                data.blocks_total++; // 总写入成功次数                       
            }
            else
            {
                data.blocks_error++;
            }
            SYSTICK_DelayMs(100);
        }
        printf("Number of sectors successfully written:%d\r\n", data.blocks_total);
        printf("Write Error Number is:%d count\r\n", data.blocks_error);
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:32 | 显示全部楼层
在main.c文件中的main()函数中初始化相应外设,并通过判断串口输入的命令来完成充值、扣款、读取ID以及填充所有扇区的功能
 楼主| 个百zz分点个 发表于 2022-9-29 16:43 | 显示全部楼层
int main()
{
        for(uint16_t i=0; i<0xFFFF; i++);
        SYSTICK_Init(1); // 滴答定时器初始化
        USART1_Init();
        Buzzer_Init(); // 蜂鸣器初始化函数调用
        SPI_GPIO_Init();
        RC522_Init();

        printf("**********Operating instructions**********\r\n");
        printf("Money count: 0\r\n");
        printf("\'+\':Increment 100\r\n");
        printf("\'-\':Decrement 100\r\n");
        printf("\'1\':Read Card ID\r\n");
        printf("\'2\':Write all sectors\r\n");
        printf("******************************************\r\n");       
       
        RFID_ValueBlock_Init(0x04, money, Card_DefaultKey);
       
          while(1)
          {
            switch(usart1_data)
            {
                case '+': // 充值100元
                    Money_Increment();
                    break;
                case '-': // 扣费100元
                    Money_Decrement();
                    break;
                case '1': // 读取卡中ID
                    Read_CardID();
                    break;
                case '2': // 向卡中各扇区写入数据
                    Fill_Money();
                    break;
                default:
                    break;
            }
            usart1_data = 0;
            SYSTICK_DelayMs(50);
  }
}
 楼主| 个百zz分点个 发表于 2022-9-29 16:47 | 显示全部楼层
现象
将程序下载到开发板中,打开串口调试助手,可以看到窗口中提示可输入命令选项,可以分别输入相应的命令,实现充值、扣款、读取ID以及填充所有扇区的功能。

2704863355ab093e6f.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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