CubeMX的配置
RCC、SYS的配置
配置SPI1如下
配置串口
配置RTThread(用的是3.1.3版本内核)
配置片选 置位引脚
配置NVIC
配置时钟树
之后生成工程文件
keil配置
①修改context_rvds.S的文件类型 避免keil识别不出
②注释掉shell文件里第182行处的
extern char rt_hw_console_getchar(void);
return rt_hw_console_getchar();
代码添加与修改
打开下面的百度网盘链接,里面包含rc522的配置文件,加入工程里
链接:https://pan.baidu.com/s/1JAcmRkJxuOb12wdRRySGXg?pwd=lch6
提取码:lch6
在main.c文件里原有的头文件后面再加上下面的头文件
#include "mfrc522.h"
#include <rtthread.h>
加上一些参数、变量的定义
#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;
加上邮箱控制块的代码
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";
加上两个线程事件的代码
/* 邮箱控制块 */
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);
}
加上线程初始化配置代码
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;
}
再在main函数里写入这些函数
想要修改卡里的内容需要在main函数里初始化之后进行如下函数操作
写操作 如下面的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();
}
读操作 把对应区块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] );
之后在main函数里的while(1)函数里加上 rt_thread_mdelay(1000);
为了方便检测IC卡的数据,可以在手机里下载这个软件
设备接线:
将RC522与STM32F407的连接,对应引脚如下
SDA——PA2
SCK——PA5
MOSI——PA7
MISO——PA6
RST——PA3
之后接上串口线与电脑连接,打开串口助手
下载代码进单片机后运行后 将IC卡贴近RC522 可以发现串口打印出
可以看出我们定义的idData已经被写入卡中 且IC卡ID为32 fe 7b e7
用手机软件检测IC卡也可见