[STM32F4] STM32F407基于RTThread通过SPI实现RC522的读写

[复制链接]
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:55 | 显示全部楼层 |阅读模式
CubeMX的配置

RCC、SYS的配置

5283266a863d151146.png

配置SPI1如下
5871966a864195289f.png
7255966a8642c26cd7.png

 楼主| 花间一壶酒sd 发表于 2024-7-30 11:55 | 显示全部楼层
配置串口
6379166a8643d80cce.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:56 | 显示全部楼层
配置RTThread(用的是3.1.3版本内核)
5728966a86454ee2ab.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:56 | 显示全部楼层
配置片选 置位引脚
717666a86462f2b9e.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:56 | 显示全部楼层
配置NVIC
8795666a864759f4e0.png
8092466a8647c0fa72.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:57 | 显示全部楼层
配置时钟树
624566a8648976259.png

之后生成工程文件
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:57 | 显示全部楼层
keil配置
①修改context_rvds.S的文件类型 避免keil识别不出
3479566a8649c47ef1.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:57 | 显示全部楼层
注释掉shell文件里第182行处的

  extern char rt_hw_console_getchar(void);

  return rt_hw_console_getchar();
 楼主| 花间一壶酒sd 发表于 2024-7-30 11:59 | 显示全部楼层
代码添加与修改
打开下面的百度网盘链接,里面包含rc522的配置文件,加入工程里

链接:https://pan.baidu.com/s/1JAcmRkJxuOb12wdRRySGXg?pwd=lch6
提取码:lch6

在main.c文件里原有的头文件后面再加上下面的头文件

#include "mfrc522.h"

#include <rtthread.h>
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:00 | 显示全部楼层
加上一些参数、变量的定义

#define THREAD_PRIORITY      10

#define THREAD_TIMESLICE     5

uint8_t CompareID(uint8_t* CardID, uint8_t* CompareID);

void Read64Block( void);

void UARTmain_Init(void);

uint8_t status; uint8_t g_ucTempbuf[20];

bool flag_loop=0;uint8_t g_ucTempbuf1[20];uint8_t status1;

uint8_t g_ucTempbuf2[20];uint8_t status2;

uint8_t defaultKeyA[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

uint8_t MyID[5] = {0x32,0xfe,0x7b,0xe7};

uint8_t idData[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};

uint8_t readData[5] = {0,0,0,0};uint8_t z=0;uint8_t h=0;
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:00 | 显示全部楼层
加上邮箱控制块的代码
static struct rt_mailbox mb;

/* 用于放邮件的内存池 */

static char mb_pool[128];

static char mb_str1[] = "here hav a card";

static char mb_str2[] = "this is another mail!";

static char mb_str3[] = "over";
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:01 | 显示全部楼层
代码说明
邮箱控制块初始化:

rt_mailbox_init 用于初始化邮箱控制块 mb。
mb_pool 是用于存放邮件的内存池。
sizeof(mb_pool) 是内存池的大小。
RT_IPC_FLAG_FIFO 表示采用先进先出的方式处理邮件。
发送邮件:

使用 rt_mailbox_send 将邮件发送到邮箱中。
这里创建了一个 mail_t 结构体实例 mail,将邮件内容设置为不同的字符串,并发送到邮箱中。
接收邮件:

使用 rt_mailbox_recv 从邮箱中接收邮件。
收到的邮件内容通过 rt_kprintf 打印到终端。
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:02 | 显示全部楼层
加上两个线程事件的代码

/* 邮箱控制块 */
static struct rt_mailbox mb;
/* 用于放邮件的内存池 */
static char mb_pool[128];

static char mb_str1[] = "here hav a card";
static char mb_str2[] = "this is another mail!";
static char mb_str3[] = "over";

ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;

/* 线程 1 入口 */
static void thread1_entry(void *parameter)
{
    char *str;

    while (1)
    {
                //                printf("bbbbbbbbbb");       
        /* 从邮箱中收取邮件 */
        if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK)
        {
                                //        printf("00000000000");       
            if (str == mb_str3)
                break;
            if (str == mb_str1)
                                                {
                                //                        printf("bbbbbbbbbb");       
                                                status = MFRC522_Anticoll(g_ucTempbuf);
                                                        if (status != MI_OK)
                                                         {  
                                                                // printf("222222222222");       
                                                                 flag_loop=0;  
                                                                 continue;
                                                         }
                                                         
                                                        if(flag_loop==1)
                                                        {
                                                //                printf("99999");       
                                                         MFRC522_Halt();       
                                                         continue;
                                                        }
                                                        if (CompareID(g_ucTempbuf,MyID) == MI_OK)
                                                        {
                                                                printf("Welcome! Card is correct\n");
                                                        }
                                                else
                                                        {
                                                                printf(" Card is NOT correct\n");
                                                        }
                                                        flag_loop=1;
                                                        printf("\n UID=%x:%x:%x:%x\r\n",g_ucTempbuf[0],g_ucTempbuf[1],g_ucTempbuf[2],g_ucTempbuf[3] );
                                                        MFRC522_Halt();
                                                }
            /* 延时 100ms */
            rt_thread_mdelay(100);
        }
    }
    /* 执行邮箱对象脱离 */
    rt_mb_detach(&mb);
}

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;

/* 线程 2 入口 */
static void thread2_entry(void *parameter)
{
          

    while(1)
    {    status = MFRC522_Request(PICC_REQALL, g_ucTempbuf);///YNT
                              if (status == MI_OK)
                                                {            /* 发送 mb_str1 地址到邮箱中 */
            rt_mb_send(&mb, (rt_uint32_t)&mb_str1);        printf("aaaaaaaaaaaa");
                                                }  
            else{                                               
            /* 发送 mb_str2 地址到邮箱中 */
            rt_mb_send(&mb, (rt_uint32_t)&mb_str2);
                                                }
        /* 延时 200ms */
        rt_thread_mdelay(200);
                                                               
    }

    /* 发送邮件告诉线程 1,线程 2 已经运行结束 */
    rt_mb_send(&mb, (rt_uint32_t)&mb_str3);
}
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:02 | 显示全部楼层
加上线程初始化配置代码

int mailbox_sample(void)

{

    rt_err_t result;



    /* 初始化一个 mailbox */

    result = rt_mb_init(&mb,

                        "mbt",                      /* 名称是 mbt */

                        &mb_pool[0],              

                        sizeof(mb_pool) / 4,      

                        RT_IPC_FLAG_FIFO);         

    if (result != RT_EOK)

    {

        rt_kprintf("init mailbox failed.\n");

        return -1;

    }



    rt_thread_init(&thread1,

                   "thread1",

                   thread1_entry,

                   RT_NULL,

                   &thread1_stack[0],

                   sizeof(thread1_stack),

                   THREAD_PRIORITY, THREAD_TIMESLICE);

    rt_thread_startup(&thread1);



    rt_thread_init(&thread2,

                   "thread2",

                   thread2_entry,

                   RT_NULL,

                   &thread2_stack[0],

                   sizeof(thread2_stack),

                   THREAD_PRIORITY, THREAD_TIMESLICE);

    rt_thread_startup(&thread2);

    return 0;

}
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:03 | 显示全部楼层
再在main函数里写入这些函数 9158066a8660c6b142.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:03 | 显示全部楼层
想要修改卡里的内容需要在main函数里初始化之后进行如下函数操作
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:03 | 显示全部楼层
写操作 如下面的MFRC522_Write(1, idData)一样 把已经定义好的idData写入块1
     for(z=0;z<1;z++)

       {

               uint8_t k=0,p=0;

               uint8_t serNum[5];

               status = MFRC522_Request(PICC_REQALL, g_ucTempbuf1);

                            if (status != MI_OK)     continue;

                             status = MFRC522_Anticoll(serNum);

                             if (status != MI_OK) continue;         

                             status = MFRC522_Select(serNum);

                             if (status != MI_OK) continue;         

                             status= MFRC522_AuthState(PICC_AUTHENT1A, k, defaultKeyA,serNum);

                             if (status != MI_OK) continue;

                            status = MFRC522_Write(1, idData);

                            if (status == MI_OK)

                            {

                                   printf("aaaaaaaaaaaa");                                                               

                            }                          

                            MFRC522_Halt();  

       }
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:04 | 显示全部楼层
读操作 把对应区块1的数据读出来 MFRC522_Read第一个参数可以改成其他数字 对应其他区块
uint8_t  readdata[5];

       for(h=0;h<1;h++)

       {

   uint8_t k=0,p=0;

uint8_t serNum[5];

status = MFRC522_Request(PICC_REQALL, g_ucTempbuf2);

    if (status != MI_OK)     continue;

               status = MFRC522_Anticoll(serNum);

         if (status != MI_OK) continue;

         status = MFRC522_Select(serNum);

         if (status != MI_OK) continue;

         status = MFRC522_AuthState(PICC_AUTHENT1A, k, defaultKeyA,serNum);

         if (status != MI_OK) continue;

               status = MFRC522_Read(1, readdata);

                if (status == MI_OK)

                {

                            printf("hex= ");

                  for(p=0; p<5; p++)

                  {                 

                         printf("%x ",readdata[p]);

                  }

                  printf("\r\n\r\n");                                                                     

                  MFRC522_Halt();

                                      }

                    MFRC522_Halt();      

                                          }

            printf("\n =%x:%x:%x:%x\r\n",readdata[0],readdata[1],readdata[2],readdata[3] );

               
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:04 | 显示全部楼层
之后在main函数里的while(1)函数里加上     rt_thread_mdelay(1000);

为了方便检测IC卡的数据,可以在手机里下载这个软件 2734366a86668c47f2.png
 楼主| 花间一壶酒sd 发表于 2024-7-30 12:05 | 显示全部楼层
设备接线:

将RC522与STM32F407的连接,对应引脚如下

SDA——PA2

SCK——PA5

MOSI——PA7

MISO——PA6

RST——PA3

之后接上串口线与电脑连接,打开串口助手

下载代码进单片机后运行后 将IC卡贴近RC522 可以发现串口打印出
7755566a866808efe9.png
可以看出我们定义的idData已经被写入卡中 且IC卡ID为32 fe 7b e7
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

1217

帖子

2

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