打印
[STM32F4]

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

[复制链接]
533|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CubeMX的配置

RCC、SYS的配置



配置SPI1如下



使用特权

评论回复
沙发
花间一壶酒sd|  楼主 | 2024-7-30 11:55 | 只看该作者
配置串口

使用特权

评论回复
板凳
花间一壶酒sd|  楼主 | 2024-7-30 11:56 | 只看该作者
配置RTThread(用的是3.1.3版本内核)

使用特权

评论回复
地板
花间一壶酒sd|  楼主 | 2024-7-30 11:56 | 只看该作者
配置片选 置位引脚

使用特权

评论回复
5
花间一壶酒sd|  楼主 | 2024-7-30 11:56 | 只看该作者
配置NVIC

使用特权

评论回复
6
花间一壶酒sd|  楼主 | 2024-7-30 11:57 | 只看该作者
配置时钟树


之后生成工程文件

使用特权

评论回复
7
花间一壶酒sd|  楼主 | 2024-7-30 11:57 | 只看该作者
keil配置
①修改context_rvds.S的文件类型 避免keil识别不出

使用特权

评论回复
8
花间一壶酒sd|  楼主 | 2024-7-30 11:57 | 只看该作者
注释掉shell文件里第182行处的

  extern char rt_hw_console_getchar(void);

  return rt_hw_console_getchar();

使用特权

评论回复
9
花间一壶酒sd|  楼主 | 2024-7-30 11:59 | 只看该作者
代码添加与修改
打开下面的百度网盘链接,里面包含rc522的配置文件,加入工程里

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

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

#include "mfrc522.h"

#include <rtthread.h>

使用特权

评论回复
10
花间一壶酒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;

使用特权

评论回复
11
花间一壶酒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";

使用特权

评论回复
12
花间一壶酒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 打印到终端。

使用特权

评论回复
13
花间一壶酒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);
}

使用特权

评论回复
14
花间一壶酒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;

}

使用特权

评论回复
15
花间一壶酒sd|  楼主 | 2024-7-30 12:03 | 只看该作者
再在main函数里写入这些函数

使用特权

评论回复
16
花间一壶酒sd|  楼主 | 2024-7-30 12:03 | 只看该作者
想要修改卡里的内容需要在main函数里初始化之后进行如下函数操作

使用特权

评论回复
17
花间一壶酒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();  

       }

使用特权

评论回复
18
花间一壶酒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] );

               

使用特权

评论回复
19
花间一壶酒sd|  楼主 | 2024-7-30 12:04 | 只看该作者
之后在main函数里的while(1)函数里加上     rt_thread_mdelay(1000);

为了方便检测IC卡的数据,可以在手机里下载这个软件

使用特权

评论回复
20
花间一壶酒sd|  楼主 | 2024-7-30 12:05 | 只看该作者
设备接线:

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

SDA——PA2

SCK——PA5

MOSI——PA7

MISO——PA6

RST——PA3

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

下载代码进单片机后运行后 将IC卡贴近RC522 可以发现串口打印出

可以看出我们定义的idData已经被写入卡中 且IC卡ID为32 fe 7b e7

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

1138

帖子

2

粉丝