当前位置:网站首页>基于STM32+RFID设计的宿舍检修管理系统
基于STM32+RFID设计的宿舍检修管理系统
2022-06-29 09:33:00 【DS小龙哥】
1. 需求
需求: 一个寝室一个标签,设备端扫描标签,通过显示屏键入维修成功与否之类的的信息提交到平台
系统构架: 一个设备端 + 一个上位机
硬件选型:
(1)STM32F103RCT6作为设备端的主控MCU
(2)RC522作为设备端的射频刷卡设备,读写IC卡
(3)多张IC卡,模拟代表每个宿舍
实现思路:
设计一个上位机,用来管理查看维修检修信息,当维修寝室的设备或者检修完成时,通过STM32上的RC522刷一下这个寝室的IC卡,识别这是哪个寝室,识别成功后在软件上弹出一个对话框,填写本次维修或者检修的事件,填写完毕点击提交即可。
软件分为两个功能:
(1)注册功能:每个寝室都有一张IC卡,这张卡第一次使用需要在维检系统里进行注册,填写这个IC卡对应的这个寝室的信息。
(2)维修、检修报告提交:当完成检修、检修之后,填写报告。
(3)查看历史记录,可以查看维修,检修的所有详细报告信息,可以导出execl表格,方便公布出去公众查看。
(4)注册、维修、检修记录都存放在数据库里,方便管理。
硬件的具体功能:
STM32上有两个按键,一个LCD屏,一个RC522模块,当终端刷卡后,LCD显示屏会弹出一个询问提示? “当前是维修还是检修”,按下按键1或者按键2之后,就会将卡号上传到上位机。 上位机与下位机通过串口进行通信。
2. 演示效果


3. 上位机软件设计
3.1 通信说明
上位机与设备之间通过串口进行通信,上位机里使用SQLITE数据库存放所有关键信息,数据库里创建了3张表,一张表存放维检信息,一张表是账号信息,一张表是意见反馈记录。
A,F39A471B, 注册
B,F39A471B, 检修
C,F39A471B, 维修
3.2 搭建开发环境
上位机软件采用Qt框架设计,Qt是一个跨平台的C++图形用户界面应用程序框架。Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单来说,QT可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。
QT官网:https://www.qt.io/

QT学习入门实战专栏文章: https://blog.csdn.net/xiaolong1126626497/category_11400392.html
QT5.12.6的下载地址:
https://download.qt.io/archive/qt/5.12/5.12.6/
打开下载链接后选择下面的版本进行下载:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
软件安装时断网安装,否则会提示输入账户。
安装的时候,第一个复选框里勾选一个mingw 32编译器即可,其他的不管默认就行,直接点击下一步继续安装。

选择MinGW 32-bit 编译器:

选择MinGW 32-bit 编译器:

安装好之后,将源码工程复制到英文路径下,双击工程文件打开。

工程打开之后,点击左下角的绿色三角形按钮即可编译运行。

运行效果如下:

3.3 效果







3.4 数据库的插入代码示例
//在数据库创建维检信息表
void Widget::CreateStudentSurface()
{
//数据库:建表,如果存在就不创建,不存在就创建
QSqlQuery sql_query(database);
//下面语句查询指定的表是否存在.
sql_query.exec(QString("select count(*) from sqlite_master where type='table' and name='%1'").arg("student"));
if(sql_query.next())
{
if(sql_query.value(0).toInt()==0)
{
qDebug("维检记录数据库表是不存在的.准备创建.\n");
//创建表格 创建表格语句:create table <table_name> (f1 type1, f2 type2,…);
/* CREATE TABLE 是告诉数据库系统创建一个新表的关键字。 * CREATE TABLE 语句后跟着表的唯一的名称 * 或标识*/
/*下面的语句: 创建一个名称为student的表,字段分别是ID、编号、地点名称、类型、事件*/
QString create_sql = "create table student(id int primary key, number varchar(100),name varchar(100),type varchar(100),enevt varchar(1024))";
sql_query.prepare(create_sql);
if(!sql_query.exec())
{
Log_Text_Display("维检记录数据库表创建失败.\n");
}
else
{
Log_Text_Display("维检记录数据库表创建成功.\n");
}
}
else
{
Log_Text_Display("维检记录数据库表是存在的.不需要创建.\n");
}
}
}
//添加信息
void Widget::on_pushButton_add_student_clicked()
{
QString number=ui->lineEdit_student_number->text();
QString name=ui->lineEdit_student_name->text();
if(number.isEmpty()||name.isEmpty())
{
QMessageBox::information(this,"提示","请认真填写数据后再添加.",
QMessageBox::Ok,QMessageBox::Ok);
return;
}
//添加维检地点信息
LuRu_data(number,name);
}
//录入数据 传入设备编号和地点名称
void Widget::LuRu_data(QString number,QString name)
{
//没有表就先创建
CreateStudentSurface();
//添加数据到表
//保存数据到数据库
QSqlQuery sql_query(database);
//查询原数据库表里有没有重复数据
//查询全部数据
sql_query.prepare("select * from student");
if(!sql_query.exec())
{
Log_Text_Display("维检记录数据库查询错误.\n");
}
else
{
while(sql_query.next())
{
//ID、编号、地点名称、类型、事件
// int id = sql_query.value(0).toInt(); //ID
QString find_number = sql_query.value(1).toString(); //编号
QString find_name = sql_query.value(2).toString(); //地点名称
QString find_type = sql_query.value(3).toString(); //类型
QString find_event = sql_query.value(4).toString(); //事件
//判断编号有没有冲突的
if(number==find_number)
{
QMessageBox::information(this,"提示","你输入的编号在数据库已经存在!\n请认真填写.",
QMessageBox::Ok,QMessageBox::Ok);
return;
}
}
}
//准备插入数据
//查询最大ID
QString select_max_sql = "select max(id) from student";
int max_id = 0;
sql_query.prepare(select_max_sql);
if(!sql_query.exec())
{
Log_Text_Display("维检信息表最大ID查找失败.\n");
}
else
{
while(sql_query.next())
{
max_id = sql_query.value(0).toInt();
}
Log_Text_Display(QString("data base max id:%1\n").arg(max_id));
//添加数据
//插入数据 插入语句:insert into <table_name> values (value1, value2,…);
QString insert_sql = tr("insert into student values(?,?,?,?,?)");
sql_query.prepare(insert_sql);
//ID、编号、地点名称、类型、事件
sql_query.addBindValue(max_id+1); //id
sql_query.addBindValue(number);
sql_query.addBindValue(name);
sql_query.addBindValue("----");
sql_query.addBindValue("----");
if(!sql_query.exec())
{
Log_Text_Display("维检信息表数据插入失败.\n");
return;
}
else //插入成功
{
//插入成功就清除页面
ui->lineEdit_student_name->clear();
// ui->lineEdit_student_type->clear();
ui->lineEdit_student_number->clear();
}
}
//更新维检信息表格数据显示
on_pushButton_update_student_clicked();
}
4. STM32设备端设计
如果需要全部工程源码、上位机的源码可以在这里下载即可:
https://download.csdn.net/download/xiaolong1126626497/85682742
如果需要看项目视频演示,可以看这里:
基于STM32+RFID设计的宿舍维检管理系统
4.1 汉字取模

4.2 keil工程

4.3 硬件连线
RC522射频模块外部的接口:
*1--SDA <----->PB5--片选脚
*2--SCK <----->PB4--时钟线
*3--MOSI<----->PA12--输出
*4--MISO<----->PA11--输入
*5--悬空
*6--GND <----->GND
*7--RST <----->PA8--复位脚
*8--VCC <----->VCC
4.4 main.c代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "RFID_RC522.h"
#include "key.h"
#include "beep.h"
unsigned char SN[4]={
88,88,88,88}; //默认卡号
u8 SendBuff[50];
/* 函数功能: 打印卡号 */
void print_info(unsigned char *p,int cnt)
{
int i;
for(i=0;i<cnt;i++)
{
printf("0x%X ",p[i]);
}
printf("\r\n");
}
/* 函数功能: 读卡号--电子标签的卡号 返回值: 1成功 0失败 */
int ReadCardNumber(void)
{
unsigned char CT[2];//卡类型
u8 status=1;
status=RC522_PcdRequest(PICC_REQIDL ,CT);//(寻卡模式,卡类型),成功返回0
if(status==MI_OK)//寻卡成功
{
status=MI_ERR;
status=RC522_PcdAnticoll(SN); //防冲撞,成功返回0,SN是读到卡号的地址
printf("卡类型:");
print_info(CT,2);//打印类型
printf("卡号:");
print_info(SN,4);//打印卡号
return 1;
}
return 0;
}
int main(void)
{
u32 cnt=0;
u8 key=0;
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
KEY_Init();
BEEP_Init();
POINT_COLOR=RED;
RC522_Init(); //RC522
//LCD_DisplayData(24*1,0,24,24,font_data[0]);
//LCD_DisplayData(24*2,0,24,24,1);
//LCD_DisplayData(24*3,0,24,24,2);
DisplayData(24*0,0,24,24,(u8*)font_data[0],WHITE,BLACK);
DisplayData(24*1,0,24,24,(u8*)font_data[1],WHITE,BLACK);
DisplayData(24*2,0,24,24,(u8*)font_data[2],WHITE,BLACK);
DisplayData(24*3,0,24,24,(u8*)font_data[3],WHITE,BLACK);
DisplayData(24*4,0,24,24,(u8*)font_data[4],WHITE,BLACK);
DisplayData(24*5,0,24,24,(u8*)font_data[5],WHITE,BLACK);
DisplayData(24*6,0,24,24,(u8*)font_data[6],WHITE,BLACK);
DisplayData(24*7,0,24,24,(u8*)font_data[7],WHITE,BLACK);
DisplayData(24*8,0,24,24,(u8*)font_data[8],WHITE,BLACK);
DisplayData(24*9,0,24,24,(u8*)font_data[9],WHITE,BLACK);
delay_ms(100);
while(1)
{
//读取卡号
if(ReadCardNumber())
{
DisplayData(0,100,24,24,(u8*)font_data[16],WHITE,BLACK);
DisplayData(24,100,24,24,(u8*)font_data[17],WHITE,BLACK);
sprintf((char*)SendBuff,"%X%X%X%X",SN[0],SN[1],SN[2],SN[3]);
LCD_ShowString(24*3,105,300,300,16," ");
LCD_ShowString(24*3,105,300,300,16,SendBuff);
BEEP=1;
delay_ms(100);
BEEP=0;
//注册
DisplayData(0,200,24,24,(u8*)font_data[10],WHITE,BLACK);
DisplayData(24*1,200,24,24,(u8*)font_data[11],WHITE,BLACK);
//检修
DisplayData(24*2+24*3,200,24,24,(u8*)font_data[12],WHITE,BLACK);
DisplayData(24*3+24*3,200,24,24,(u8*)font_data[13],WHITE,BLACK);
//维修
DisplayData(24*4+24*6,200,24,24,(u8*)font_data[14],WHITE,BLACK);
DisplayData(24*5+24*6,200,24,24,(u8*)font_data[15],WHITE,BLACK);
while(1)
{
key=KEY_Scan(0);
if(key)
{
printf("key=%d\r\n",key);
//注册
if(key==3)
{
sprintf((char*)SendBuff,"A,%X%X%X%X,",SN[0],SN[1],SN[2],SN[3]);
printf("%s\r\n",SendBuff);
}
//检修
else if(key==2)
{
sprintf((char*)SendBuff,"B,%X%X%X%X,",SN[0],SN[1],SN[2],SN[3]);
printf("%s\r\n",SendBuff);
}
//维修
else if(key==1)
{
sprintf((char*)SendBuff,"C,%X%X%X%X,",SN[0],SN[1],SN[2],SN[3]);
printf("%s\r\n",SendBuff);
}
break;
}
delay_ms(50);
LED0=!LED0;
}
LCD_Clear(WHITE);
DisplayData(24*0,0,24,24,(u8*)font_data[0],WHITE,BLACK);
DisplayData(24*1,0,24,24,(u8*)font_data[1],WHITE,BLACK);
DisplayData(24*2,0,24,24,(u8*)font_data[2],WHITE,BLACK);
DisplayData(24*3,0,24,24,(u8*)font_data[3],WHITE,BLACK);
DisplayData(24*4,0,24,24,(u8*)font_data[4],WHITE,BLACK);
DisplayData(24*5,0,24,24,(u8*)font_data[5],WHITE,BLACK);
DisplayData(24*6,0,24,24,(u8*)font_data[6],WHITE,BLACK);
DisplayData(24*7,0,24,24,(u8*)font_data[7],WHITE,BLACK);
DisplayData(24*8,0,24,24,(u8*)font_data[8],WHITE,BLACK);
DisplayData(24*9,0,24,24,(u8*)font_data[9],WHITE,BLACK);
}
cnt++;
delay_ms(10);
if(cnt>=20)
{
cnt=0;
LED1=!LED1;
LED0=!LED0;
}
}
}
边栏推荐
- 2020-09-18 referer authentication URL escape
- Bug的描述、定级、生命周期
- 如何快速完成磁盤分區
- 在实践中学习Spark计算框架(00)
- F5 big IP Icontrol rest command execution (cve-2022-1388)
- MySQL中innodb_page_cleaners详解
- Talk about threads and concurrency
- stream流(Collectors)用法
- 2019.10.6 training summary
- Analysis on the specific execution process of an insert statement in MySQL 8.0 (2)
猜你喜欢

October 17, 2020: question brushing 1

Beautiful ruins around Kiev -- a safe guide to Chernobyl!

Installing and configuring wmware esxi 6.5.0 in VMware Workstation

软件测试模型(V模型和W模型)

在VMware workstation中安装WMware ESXi 6.5.0并进行配置

Linux下Redis安装及集群搭建

AQS之ReentrantLock源码解析

IIS server related error

Comment terminer rapidement une partition de disque

Bug的描述、定级、生命周期
随机推荐
September 17, 2020 gateway business process has two tasks: referer certification and non commodity Templating
查看CSDN的博客排名
打印1000~2000年之间的闰年(C语言)
C#使用WinExec调用exe程序
《CLR via C#》读书笔记-单实例应用程序
2020-10-17:刷题1
Voir le classement des blogs pour csdn
SQL Server 数据库的连接查询
Is it safe to open a stock account with the QR code given by the manager of a securities firm? I want to open an account
打印9*9乘法口诀表(C语言)
Maze walking BFS medium + -- the last programming challenge
Download control 1 of custom control (downloadview1)
解决zxing的QR码包含中文时乱码的问题
Alibaba cloud server is installed and configured with redis. Remote access is unavailable
Ora-01950 does not have permission on tablespace
Graphics learned from jigsaw puzzles h
SQL Server 数据库增删改查语句
Analysis of liferayportal jsonws deserialization vulnerability (cve-2020-7961)
Hystrix fuse: Service fusing and service degradation
Common usage of LINQ in C #