0 前言

🔥
这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 毕业设计 Stm32云平台的智能病房监控系统(源码+硬件+论文)

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 项目分享:

https://gitee.com/sinonfin/sharing

在这里插入图片描述

1 主要功能

  • 1.使用STM32F103C8T6单片机、MAX30102心率传感器模块、LMT70温度传感器、DHT11温湿度传感器模块、烟雾传感器模块、光敏电阻传感器模块,阿里云物联网平台组成。

  • 2.通过温湿度传感器、烟雾传感器模块、光敏电阻传感器模块采集病房空气环境中的温度、湿度、烟雾浓度、光照强度。数据超过阈值产生报警提示。

  • 3.通过MAX30102心率传感器模块、LMT70温度传感器,检测病人的心率及体温。数据超过阈值时产生报警提醒。

  • 4.单片机将数据通过MQTT协议和阿里云物联网平台交互。

  • 5.手机端APP查看数据,实现远程监控、数据内容显示。

在这里插入图片描述

本次设计的系统主要由微控制器、心率传感器模块、体温传感器模块、温湿度传感器模块、烟雾传感器模块、光敏传感器模块、按键模块、液晶显示模块、电源模块、电机驱动模块、继电器模块、灯光模块、WiFi模块和阿里云物联网平台互联组成。智慧病房系统框图,如上图。

2 硬件设计(原理图)

在这里插入图片描述

3 核心软件设计

在这里插入图片描述

关键代码

int main(void)
{

    /*********************************/
    /***********系统初始化************/
    /*********************************/
    SystemInit();
    Delay_Init();        //延时功能初始化
    Usart1_Init(9600); //串口1功能初始化,波特率9600
    Usart2_Init(115200);
    Usart3_Init(9600); //串口3功能初始化,波特率9600
    TIM1_Init(3, 72);

    TIM4_Init(300, 7200); //TIM4初始化,定时时间 300*7200*1000/72000000 = 30ms

    LCD_Init();      //LCD初始化
    LED_Init();      //LED初始化
    KEY_Exti_Init(); //按键初始化

    IIC_Init(); //I2C初始化
    DHT11_Init();
    Adc_Init();        //AD初始化
    STEP_MOTOR_Init(); //step接口初始化

    LCD_Ref = 0xF1;

    EVRMT.Work_Mode = 0;
    Over_Init();

    AT24C02_Write(16, PASS_M, 32);
    AT24C02_Write(0, SSID_M, 15);
    //
    AT24C02_Read(0, SSID, 15);
    AT24C02_Read(16, PASS, 32);
    

    while (EVRMT.FSM == 0x00)Start_Menu();

    WiFi_ResetIO_Init();     //初始化WiFi的复位IO
    MQTT_Buff_Init();        //初始化接收,发送,命令数据的 缓冲区 以及各状态参数
    AliIoT_Parameter_Init(); //初始化连接阿里云IoT平台MQTT服务器的参数

    /*********************************/
    /************工作模式*************/
    /*********************************/
    while (1)
    {
        /*--------------------------------------------------------------------*/
        /*   Connect_flag=1同服务器建立了连接,我们可以发布数据和接收推送了    */
        /*--------------------------------------------------------------------*/
        if (Connect_flag == 1)
        {
            /*-------------------------------------------------------------*/
            /*                     处理发送缓冲区数据                      */
            /*-------------------------------------------------------------*/
            if (MQTT_TxDataOutPtr != MQTT_TxDataInPtr)
            { //if成立的话,说明发送缓冲区有数据了
                //3种情况可进入if
                //第1种:0x10 连接报文
                //第2种:0x82 订阅报文,且ConnectPack_flag置位,表示连接报文成功
                //第3种:SubcribePack_flag置位,说明连接和订阅均成功,其他报文可发
                if ((MQTT_TxDataOutPtr[2] == 0x10) || ((MQTT_TxDataOutPtr[2] == 0x82) && (ConnectPack_flag == 1)) || (SubcribePack_flag == 1))
                {
                    u1_printf("发送数据:0x%x\r\n", MQTT_TxDataOutPtr[2]); //串口提示信息
                    MQTT_TxData(MQTT_TxDataOutPtr);                       //发送数据
                    MQTT_TxDataOutPtr += BUFF_UNIT;                       //指针下移
                    if (MQTT_TxDataOutPtr == MQTT_TxDataEndPtr)           //如果指针到缓冲区尾部了
                        MQTT_TxDataOutPtr = MQTT_TxDataBuf[0];            //指针归位到缓冲区开头
                }
            } //处理发送缓冲区数据的else if分支结尾
            /*-------------------------------------------------------------*/
            /*                     处理接收缓冲区数据                      */
            /*-------------------------------------------------------------*/
            if (MQTT_RxDataOutPtr != MQTT_RxDataInPtr)
            { //if成立的话,说明接收缓冲区有数据了
                u1_printf("接收到数据:");
                /*-----------------------------------------------------*/
                /*                    处理CONNACK报文                  */
                /*-----------------------------------------------------*/
                //if判断,如果第一个字节是0x20,表示收到的是CONNACK报文
                //接着我们要判断第4个字节,看看CONNECT报文是否成功
                if (MQTT_RxDataOutPtr[2] == 0x20)
                {
                    switch (MQTT_RxDataOutPtr[5])
                    {
                    case 0x00:
                        u1_printf("CONNECT报文成功\r\n"); //串口输出信息
                        ConnectPack_flag = 1;             //CONNECT报文成功,订阅报文可发
                        break;                            //跳出分支case 0x00
                    case 0x01:
                        u1_printf("连接已拒绝,不支持的协议版本,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case 0x01
                    case 0x02:
                        u1_printf("连接已拒绝,不合格的客户端标识符,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case 0x02
                    case 0x03:
                        u1_printf("连接已拒绝,服务端不可用,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case 0x03
                    case 0x04:
                        u1_printf("连接已拒绝,无效的用户名或密码,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case 0x04
                    case 0x05:
                        u1_printf("连接已拒绝,未授权,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case 0x05
                    default:
                        u1_printf("连接已拒绝,未知状态,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支case default
                    }
                }
                //if判断,第一个字节是0x90,表示收到的是SUBACK报文
                //接着我们要判断订阅回复,看看是不是成功
                else if (MQTT_RxDataOutPtr[2] == 0x90)
                {
                    switch (MQTT_RxDataOutPtr[6])
                    {
                    case 0x00:
                    case 0x01:
                        u1_printf("订阅成功\r\n");
                        SubcribePack_flag = 1; //SubcribePack_flag置1,表示订阅报文成功,其他报文可发送
                        Ping_flag = 0;         //Ping_flag清零
                        TIM3_ENABLE_30S();     //启动30s的PING定时器
                        TIM2_ENABLE_30S();     //启动30s的上传数据的定时器

                        Over_Value_State();
                        Check_Mode_State();

                        HR_OX_State();
                        break;
                    //跳出分支
                    default:
                        u1_printf("订阅失败,准备重启\r\n");
                        Connect_flag = 0; //Connect_flag置零,重启连接
                        break;            //跳出分支
                    }
                }
                //if判断,第一个字节是0xD0,表示收到的是PINGRESP报文
                else if (MQTT_RxDataOutPtr[2] == 0xD0)
                {
                    u1_printf("PING报文回复\r\n");
                    if (Ping_flag == 1)
                    {                  //如果Ping_flag=1,表示第一次发送
                        Ping_flag = 0; //要清除Ping_flag标志
                    }
                    else if (Ping_flag > 1)
                    {                      //如果Ping_flag>1,表示是多次发送了,而且是2s间隔的快速发送
                        Ping_flag = 0;     //要清除Ping_flag标志
                        TIM3_ENABLE_30S(); //PING定时器重回30s的时间
                    }
                }
                //if判断,如果第一个字节是0x30,表示收到的是服务器发来的推送数据
                //我们要提取控制命令
                else if ((MQTT_RxDataOutPtr[2] == 0x30))
                {
                    u1_printf("服务器等级0推送\r\n");
                    MQTT_DealPushdata_Qs0(MQTT_RxDataOutPtr); //处理等级0推送数据
                }

                MQTT_RxDataOutPtr += BUFF_UNIT;             //指针下移
                if (MQTT_RxDataOutPtr == MQTT_RxDataEndPtr) //如果指针到缓冲区尾部了
                    MQTT_RxDataOutPtr = MQTT_RxDataBuf[0];  //指针归位到缓冲区开头
            }                                               //处理接收缓冲区数据的else if分支结尾

            /*-------------------------------------------------------------*/
            /*                     处理命令缓冲区数据                      */
            /*-------------------------------------------------------------*/
            if (MQTT_CMDOutPtr != MQTT_CMDInPtr)
            { //if成立的话,说明命令缓冲区有数据了

                u1_printf("命令:%s\r\n", &MQTT_CMDOutPtr[2]);
                if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Work_Mode\":0}"))
                {
                    EVRMT.Work_Mode = 0;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Work_Mode\":1}"))
                {
                    EVRMT.Work_Mode = 1;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"curtainConrtol\":1}"))
                {
                    EVRMT.Curtain_En = EVRMT.Curtain_En == 0 ? 1 : 0;
                    EVRMT.Curtain_ON = 1;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"curtainConrtol\":0}"))
                {
                    EVRMT.Curtain_En = EVRMT.Curtain_En == 0 ? 1 : 0;
                    EVRMT.Curtain_ON = 1;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"LockSwitch\":1}"))
                {
                    LOCK_ON;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"LockSwitch\":0}"))
                {
                    LOCK_OFF;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"LightSwith\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "LightSwith", &EVRMT.Value_Temp))
                        EVRMT.PWM_Data = EVRMT.Value_Temp * 2;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Temperature_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Temperature_H", &EVRMT.Value_Temp))
                        EVRMT.Temperature_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Temperature_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Temperature_L", &EVRMT.Value_Temp))
                        EVRMT.Temperature_L = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Humidity_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Humidity_H", &EVRMT.Value_Temp))
                        EVRMT.Humidity_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Humidity_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Humidity_L", &EVRMT.Value_Temp))
                        EVRMT.Humidity_L = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Smoke_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Smoke_H", &EVRMT.Value_Temp))
                        EVRMT.Smoke_H = EVRMT.Value_Temp;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Smoke_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Smoke_L", &EVRMT.Value_Temp))
                        EVRMT.Smoke_L = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"TW_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "TW_H", &EVRMT.Value_Temp))
                        EVRMT.TW_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"TW_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "TW_L", &EVRMT.Value_Temp))
                        EVRMT.TW_L = EVRMT.Value_Temp;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Light_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Light_H", &EVRMT.Value_Temp))
                        EVRMT.Light_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"Light_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "Light_L", &EVRMT.Value_Temp))
                        EVRMT.Light_L = EVRMT.Value_Temp;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"HR_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "HR_H", &EVRMT.Value_Temp))
                        EVRMT.HR_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"HR_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "HR_L", &EVRMT.Value_Temp))
                        EVRMT.HR_L = EVRMT.Value_Temp;
                }

                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"OX_H\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "OX_H", &EVRMT.Value_Temp))
                        EVRMT.OX_H = EVRMT.Value_Temp;
                }
                else if (strstr((char *)MQTT_CMDOutPtr + 56, "\"params\":{\"OX_L\""))
                {
                    if (Get_Key_Value(&MQTT_CMDOutPtr[65], "OX_L", &EVRMT.Value_Temp))
                        EVRMT.OX_L = EVRMT.Value_Temp;
                    
                }

                MQTT_CMDOutPtr += BUFF_UNIT;          //指针下移
                if (MQTT_CMDOutPtr == MQTT_CMDEndPtr) //如果指针到缓冲区尾部了
                    MQTT_CMDOutPtr = MQTT_CMDBuf[0];  //指针归位到缓冲区开头

            } //处理命令缓冲区数据的else if分支结尾
              //Connect_flag=1的if分支的结尾

            APP_System();
        }
        /*--------------------------------------------------------------------*/
        /*      Connect_flag=0同服务器断开了连接,我们要重启连接服务器         */
        /*--------------------------------------------------------------------*/
        else
        {
            u1_printf("需要连接服务器\r\n");         //串口输出信息
            TIM_Cmd(TIM4, DISABLE);                   //关闭TIM4
            TIM_Cmd(TIM3, DISABLE);                   //关闭TIM3
            WiFi_RxCounter = 0;                       //WiFi接收数据量变量清零
            memset(WiFi_RX_BUF, 0, WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
            if (WiFi_Connect_IoTServer() == 0)
            {                                             //如果WiFi连接云服务器函数返回0,表示正确,进入if
                u1_printf("建立TCP连接成功\r\n");       //串口输出信息
                Connect_flag = 1;                         //Connect_flag置1,表示连接成功
                WiFi_RxCounter = 0;                       //WiFi接收数据量变量清零
                memset(WiFi_RX_BUF, 0, WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
                MQTT_Buff_ReInit();                       //重新初始化发送缓冲区
                LCD_Clear(BLACK);                         //清屏,进入下一个界面
            }
        }
    }
}

4 实现效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5 最后

包含内容

在这里插入图片描述

🧿 项目分享:

https://gitee.com/sinonfin/sharing

Logo

鸿蒙生态一站式服务平台。

更多推荐