基于STM32+RFID设计的宿舍检修管理系统

发布者:oplkjjj最新更新时间:2022-09-15 来源: csdn关键字:STM32  RFID 手机看文章 扫描二维码
随时随地手机看文章

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. 演示效果

image-20220501230852154

image-20220501230839452

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/


image-20220314143105032

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编译器即可,其他的不管默认就行,直接点击下一步继续安装。

image-20220417145923643

选择MinGW 32-bit 编译器:

image-20220417150002770

选择MinGW 32-bit 编译器:


image-20220417150031913

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

image-20220503002536986

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

image-20220503002719440

运行效果如下:

image-20220503002923034

3.3 效果

image-20220502084605933

image-20220502084630720

image-20220502085054445

image-20220502085111189

image-20220503002304800

image-20220503002321178

image-20220503002338426

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 (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:%1n").arg(max_id));


        //添加数据

        //插入数据 插入语句:insert into 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 汉字取模

image-20220501230518200

4.2 keil工程

image-20220501230544234

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 {

printf("0x%X ",p[i]);

}

printf("rn");

}



/*

函数功能: 读卡号--电子标签的卡号

返回值: 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);

[1] [2]
关键字:STM32  RFID 引用地址:基于STM32+RFID设计的宿舍检修管理系统

上一篇:基于STM32单片机设计的红外测温仪(带人脸检测)
下一篇:基于STM32设计的蓝牙健康管理设备

推荐阅读最新更新时间:2024-11-13 10:17

STM32实战五 板载LED显示数据
写到第五章,终于有可以看见的结果了。不过磨刀不误砍柴功。正因为前面的基础,才有今天的成果,而且有一定的实用价值。封装一个BoardLED类,主要功能是利用板载LED显示数据,类似于 Morse code 电报码,以点亮时间的长短表示二进制数据的0和1,最多4位二进制,十进制15,可以扩展到更多。下面的程序显示主循环周期时间,单位1us,实际上可以用来显示设置运行状态。购买或开发不同的开发板,LED对应的脚号不同,修改程序对应的IO号即可。 BoardLED.h 代码中用到了前几章的封装类,需要前面的原程序,全部做完以后做一个总的封包,上传到资源库中。 #ifndef __BOARDLED__ #define __BOARD
[单片机]
<font color='red'>STM32</font>实战五 板载LED显示数据
STM32的JTAG下载模式
SWJ:串行线JTAG配置 (Serial wire JTAG configuration) SWJ(串行线JTAG)支持JTAG或SWD访问Cortex的调试端口。 系统复位后的默认状态是启用SWJ但没有跟踪功能,这种状态下可以通过JTMS/JTCK脚上的特定信号选择JTAG或SW(串行线)模式。
[单片机]
RT-Thread学习笔记【stm32】(二):线程的创建中的一些问题
本文作者在实现对RTT的线程创建的过程中,发现了一些问题。 首先,我初始化了三个线程a,b,c。 但是在start 的过程中,我发现了一个神奇的现象,那就是,我只能初始化前两个线程, 第三个线程总是初始化失败。 而后我想到可能是,优先级的设置出现问题,于是我更换各种优先级之后发现,问题并没有得到解决。 再后来,我想到了一个重要的问题,那就是我用的是最小板STM,那么会不会是32的ram不够大,而 我的任务堆栈设置的过大,到导致任务无法初始化。 而后,我降低了任务的堆栈,发现,成功开始了线程。
[单片机]
STM32定时器输出比较(PWM)
前言: 1.本博文基于ARM Cortex-M3内核的STM32F103ZET6处理器芯片和标准3.5.0库函数; 2.不介绍PWM的基础概念,但是需要知道一点的是,PWM是输出比较的一种特例; 3.如有不足指出,还望前辈多多指教; 4.要想学会这个知识点,必须要掌握下面这位博友写的博客里的几个概念,不然后来很有可能会懵逼; http://blog.sina.com.cn/s/blog_3ba262a10101esd1.html Ⅰ 定时器和PWM (1)8个定时器中,除了TIM6和TIM7,其他定时器都可以产生PWM输出; (2)高级定时器TIM1和TIM8可以同时输出7路PWM(CH1~7,共7个通道),通用定时器同时可产
[单片机]
<font color='red'>STM32</font>定时器输出比较(PWM)
USB二:深入解析STM32_USB-FS-Device_Lib 库
USB事务处理: 在 USB 协议中,USB 的数据传输由信息包组成,这些信息包组合 起来可以构成完整的事务处理。USB 事务处理是 USB 主机和 USB 功能 设备之间数据传输的基本单位。USB 的信息包和事务处理具有特定的 格式。 Packet buff的使用 每个双向EP对应两个packet buffer,分别 用于发送和接收软件通过packet buffer • 软件通过packet buffer interface来访问它们 • 这些packet buffer的位置和大小都可配置,由buffer描述表指定 • Buffer描述表本身也在这块memory里,它自己的地址是由USB_BTABLE寄
[单片机]
USB二:深入解析STM32_USB-FS-Device_Lib 库
stm32 芯片与Cat的对应分类
最近在使用stm32l151cbu6开发一个项目,在查询datasheet关于DMA使用的时候,发现不同的cat分类,对应的功能还有些区别, 例如上面这个就是针对Cat.1和Cat.2。 这上面这个对应的就是Cat.3。 那么问题来了,怎么知道我的stm32l151cbu6是属于Cat.x呢,再慢慢翻datasheet,发现还真有。在P40页, 可以看到Cat分类是与flash大小直接相关的,这里面有个坑,表格里面的符号是“x”与“-”,‘x’反而表示flash大小与芯片型号的对应。往下看,我们还能看到更细致的芯片分类, 我项目的stm32l151cbu6属于STM32L 15XXB分类,对应的就是Cat.1分
[单片机]
<font color='red'>stm32</font> 芯片与Cat的对应分类
stm32的RTC
两个分离的时钟:用于APB1接口的PCLK1和RTC时钟的(RTC时钟的频率必须小于PCLK1时钟频率的四分之一); RTC的时钟源的配置可以使用函数库中的函数进行配置; RTC的中断也是使用函数库中的额函数进行配置的; void RTC_Configuration(void) {//RTC的时钟为两个分离的时钟:用于APB1的PCLK1和RTC时钟(RTC的时钟的频率必须小于PCLK1时钟频率的四分之一以上 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE); //PWR和BKP时钟使能 PWR_BackupAccessCmd(ENAB
[单片机]
<font color='red'>stm32</font>的RTC
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved