STM32RCT6+RC522+OLED,刷卡显示卡号
暂时只做了这么多,后续会继续更新
完整版讲解链接
RFID课程设计–基于STM32F103RCT6的智能门禁系统
完整版工程文件下载链接
RFID课程设计工程文件,基于STM32F103RCT6的智能门禁系统
文章目录
准备工作
准备左图的.c文件
提示:以下是本篇文章正文内容,下面案例可供参考
一、RC522
二、OLED
三、主函数
关键代码的解释
u8 UID_str[10] = {'0','0','0','0','0','0','0','0','\0',0};
UID_str[0] = ((g_ucTempbuf[0]>>4)>9) ?(g_ucTempbuf[0]>>4)-10+'a' :(g_ucTempbuf[0]>>4)+'0';
UID_str[1] = ((g_ucTempbuf[0]&0x0f)>9)?(g_ucTempbuf[0]&0x0f)-10+'a':(g_ucTempbuf[0]&0x0f)+'0';
UID_str[2] = ((g_ucTempbuf[1]>>4)>9) ?(g_ucTempbuf[1]>>4)-10+'a' :(g_ucTempbuf[1]>>4)+'0';
UID_str[3] = ((g_ucTempbuf[1]&0x0f)>9)?(g_ucTempbuf[1]&0x0f)-10+'a':(g_ucTempbuf[1]&0x0f)+'0';
UID_str[4] = ((g_ucTempbuf[2]>>4)>9) ?(g_ucTempbuf[2]>>4)-10+'a' :(g_ucTempbuf[2]>>4)+'0';
UID_str[5] = ((g_ucTempbuf[2]&0x0f)>9)?(g_ucTempbuf[2]&0x0f)-10+'a':(g_ucTempbuf[2]&0x0f)+'0';
UID_str[6] = ((g_ucTempbuf[3]>>4)>9) ?(g_ucTempbuf[3]>>4)-10+'a' :(g_ucTempbuf[3]>>4)+'0';
UID_str[7] = ((g_ucTempbuf[3]&0x0f)>9)?(g_ucTempbuf[3]&0x0f)-10+'a':(g_ucTempbuf[3]&0x0f)+'0';
UID_str[9] = 1;
主要介绍这一块
因为我们的UID是4字节(比如:07 87 E8 76
)
我们主要用到OLED中的 void OLED_ShowChar(u8 x,u8 y,u8 chr); void OLED_ShowString(u8 x,u8 y, u8 *p);
两个函数
但两位16进制数是两个字符,我们需要分开显示在OLED屏幕上
这个时候我们就需要分为高位
和 低位
来显示
我们知道,MCU中只存储二进制
数据
所以 0xE8
对应 二进制数 1110 1000
想得到高位我们需要把0xE8
右移4位得到0x0E
想得到低位我们把0xE8
和0x0f
做与(&)
运算,得到0x08
然后将四字节数据每字节的高低位放在UID_str
数组中
UID_str
数组的第九位为停止位,在OLED_ShowString
函数中可以看到,继续打印字符串内容的前提是当前读到的地方不是'\0'
UID_str
数组的第十位为标志位,当标志为0
时不打印数组的内容,当标志为1
时打印
if(UID_str[9] != 0)
OLED_ShowString(32,2,UID_str);
然后我们通过三目运算符运算,将数值转换成ASCII,当打印a、b、c......f
时需要做一些变动
我们得到的数字可以当作偏移量,我们想输出8,就是用字符0的ASCII加上8
但我们输出b时,此时的偏移量为11,所以我们要先将偏移量减去10,在加上字符a的ASCII值,从而实现输出字符b
的效果
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "rc522.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "bmp.h"
#include "oled.h"
#include "pwm.h"
/**
* 连线说明:
* 1--SDA <----->PA4
* 2--SCK <----->PA5
* 3--MOSI <----->PA7
* 4--MISO <----->PA6
* 5--悬空
* 6--GND <----->GND
* 7--RST <----->PB0
* 8--VCC <----->VCC
**/
unsigned char g_ucTempbuf[20];
int main(void)
{
unsigned char status,i,j=0;
unsigned int temp;
u8 num = 0;
u8 KEY_A[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
u8 data[16] = {0};
u8 UID[4]= {0x49, 0xe0, 0x05, 0x98};
u8 UID_str[10] = {'0','0','0','0','0','0','0','0','\0',0};
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
LED_Init();
RC522_Init(); //初始化射频卡模块
//KEY_Init(); //初始化与按键连接的硬件接口
EXTIX_Init(); //外部中断初始化
//NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 LED_Init(); //LED端口初始化
OLED_Init(); //初始化OLED
OLED_Clear() ;
LED0=0; //点亮LED
// TIM4_PWM_Init(199,7199);//不分频。PWM频率=72000/(899+1)=80Khz
delay_ms(3000);
// UID为你要修改的卡的UID key_type:0为KEYA,非0为KEYB KEY为密钥 RW:1是读,0是写 data_addr为修改的地址 data为数据内容
IC_RW ( UID, 0, KEY_A, 1, 0x10, data );
while(1)
{
printf("\r\n开始 ");
//寻卡中
OLED_ShowString(0,0,"please put card ");
OLED_ShowString(0,2,"UID:");
if(UID_str[9] != 0)
OLED_ShowString(32,2,UID_str);
status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡
printf(" %X ",status);
if (status != MI_OK)
{
PcdReset();
PcdAntennaOff();
PcdAntennaOn();
continue;
}
printf("\r\n卡的类型:");
for(i=0;i<2;i++)
{
temp=g_ucTempbuf[i];
printf("%X",temp);
}
status = PcdAnticoll(g_ucTempbuf);//防冲撞
if(status != MI_OK)
{ continue; }
printf("\r\n卡序列号:"); //终端显示
for(i=0;i<4;i++)
{
temp=g_ucTempbuf[i];
printf("%X ",temp);
}
UID_str[0] = ((g_ucTempbuf[0]>>4)>9) ?(g_ucTempbuf[0]>>4)-10+'a' :(g_ucTempbuf[0]>>4)+'0';
UID_str[1] = ((g_ucTempbuf[0]&0x0f)>9)?(g_ucTempbuf[0]&0x0f)-10+'a':(g_ucTempbuf[0]&0x0f)+'0';
UID_str[2] = ((g_ucTempbuf[1]>>4)>9) ?(g_ucTempbuf[1]>>4)-10+'a' :(g_ucTempbuf[1]>>4)+'0';
UID_str[3] = ((g_ucTempbuf[1]&0x0f)>9)?(g_ucTempbuf[1]&0x0f)-10+'a':(g_ucTempbuf[1]&0x0f)+'0';
UID_str[4] = ((g_ucTempbuf[2]>>4)>9) ?(g_ucTempbuf[2]>>4)-10+'a' :(g_ucTempbuf[2]>>4)+'0';
UID_str[5] = ((g_ucTempbuf[2]&0x0f)>9)?(g_ucTempbuf[2]&0x0f)-10+'a':(g_ucTempbuf[2]&0x0f)+'0';
UID_str[6] = ((g_ucTempbuf[3]>>4)>9) ?(g_ucTempbuf[3]>>4)-10+'a' :(g_ucTempbuf[3]>>4)+'0';
UID_str[7] = ((g_ucTempbuf[3]&0x0f)>9)?(g_ucTempbuf[3]&0x0f)-10+'a':(g_ucTempbuf[3]&0x0f)+'0';
UID_str[9] = 1;
//OLED_ShowString(0,2,UID_str);
RC522_Handle();
/* if(g_ucTempbuf[0]==0x07&&g_ucTempbuf[1]==0x87&&g_ucTempbuf[2]==0xE8&&g_ucTempbuf[3]==0x76) //0787E876,4396C597,83B062C9
{
printf("\r\nDoor Opened.\r\n");
delay_ms(2000);
}
else
{
printf("\r\nThe illegal card!\r\n");
delay_ms(2000);
}
*/
// 重要提醒,写卡操作有风险,请勿随意尝试,不能保证程序安全性,本人对任何程序问题概不负责,不限于由任何程序错误导致的任何损失或损害
// 测试程序0,完成addr读写读
// RC522_Handle();
// 谨慎使用 测试程序1,完成0x0F块 验证KEY_A、KEY_B 读 写RFID1 验证KEY_A1、KEY_B1 读 写RFID2
// RC522_Handle1();
if(num % 20 == 0)
LED0 = !LED0;
num++;
}
}
最终效果
刷卡之后显示卡的UID
完整版讲解链接
RFID课程设计–基于STM32F103RCT6的智能门禁系统