基于STM32单片机的睡眠质量检测系统设计

摘要

本次设计的是基于STM32单片机的睡眠质量检测系统设计,目前市面上的大多数睡眠质量检测设备大多
都很昂贵并且设备庞大,不适用于家庭中使用,本次设计便是在具备基本睡眠质量检测功能的情况下突出了便捷性
并且拓展了一些功能:人体心率血氧实时检测,人体体温实时检测,翻身次数检测,通过手机上位机可以实时显示
各项数据的数据值并且自动转换成折线统计图,更直观的让佩戴者了解当天的睡眠情况,并且在心率血氧以及体温
超过人体标准时手机终端以及设备会发出报警来提醒佩戴者及时关注睡眠健康问题。
  本次设计报告的硬件部分主要设计了人体心率血氧检测系统,人体体温检测系统,人体翻身次数检测系统,
WiFi远程传输系统,电源电路系统,声音报警系统,显示电路系统,系统软件部份主要是对各个模块的详细设计分
析控制等主要包括:控制主程序,显示子程序,终端报警子程序。本次设计的核心是通过检测睡眠质量的几个重要
指标:心率血氧,体温以及翻身次数来判断人体夜间睡眠的质量好坏,通过手机上位机以及硬件部分的显示器实时显示各项数据,通过手机上位机调节心率血氧以及体温的报警阈值来控制报警系统触发值以提醒佩戴者及家人及时
关注佩戴者身体健康状况。
[关键词] 睡眠质量检测 人体感测 同步显示 异常报警

第1章 绪论

1.1 课题的研究意义
  睡眠是人们健康和幸福的一个重要因素,我国目前有三成以上人群患有睡眠障碍疾病,睡眠问题已经逐渐成为
了影响人们工作和生活的一大因素。许多人不知道,目前已知明确属于睡眠障碍的疾病多达80余种。
  良好的睡眠对于血糖正常有很好的保持作用,根据美国近期一项睡眠质量与血糖状态的关系研究显示,睡眠障
碍与糖尿病之间具有相关性,而根据国内的调查,睡眠障碍较差的确有引发糖尿病等血糖疾病的风险。这些国内外
的医学调查与研究表明,睡眠障碍疾病与糖代谢异常有着密不可分的联系,而良好的睡眠有助于降低血糖,改善睡
眠质量也就成为了人们愈发关注的热点。
  改善睡眠较为重要的一步就是睡眠质量评估。但医学界现今的检测仪器成本高,时间消耗长以及床上环境的干
扰,导致这种睡眠检测方法不能为大众广泛使用。现今人们生活节奏加快,生活方式改变,睡眠问题愈发被人们所
重视,利用一种价格低廉,家用化的睡眠检测手段提前进行睡眠质量检测也成为了当前的研究热点,市场需求性也
越来越高。
1.2 国内外研究现状
  在日本由于科技带来的噪音,辐射以及其他污染。当代人的睡眠质量每况愈下,而睡眠又是人生中一项非常重
要的事,针对这一问题日本公司纷纷推出检测睡眠质量或者改善睡眠质量的产品,日本的通信运营商软银向手机用
户提供健康服务,利用程序向智能手机用户提供健康管理服务产品,产品主要向30到40年龄段的用户推广,以帮助他们改善生活习惯。
  国内现在临床上对于患者的睡眠质量的测量是通过相应的量表来实现的。每一个患者在进行睡眠质量的测试
时,需要填写睡眠质量的测量表,填完之后,医生将对该患者所填写睡眠质量的质量表的内容进行分析,对照着睡
眠质量的测量表的各部分含义及计分标准,得出一个计算结果,然后再对照相应的测量标准来界定患者的睡眠质
量,由此可见医生的工作量是相当大的。若要进行多人次的睡眠质量的测试,那将是一项非常复杂巨大的工作。在
这个背景下,通过睡眠质量检测系统进行分析和设计,从而来解决上述问题是很有必要的。
1.3 课题的研究任务
1.3.1 研究内容
  基于单片机的睡眠质量检测系统的设计与实现:通过主芯片总体控制测试功能,利用心率传感器,体温传感
器,血氧传感器以及三轴传感器协同合作,通过采集这些数据发送到上位机以及屏幕上,如果心率血氧以及体温超
过上限就会向用户发送警报提醒用户及时就医。该系统还可以通过无线传输将检测出来的数据传输到手机上位机
中,并且手机上位机可以通过传输协议将告警阈值进行更新并传回到硬件系统中,利用以上功能来实现对用户的睡
眠质量检测,用户可以通过数据对自己的习惯进行一定程度的改变。
1.3.2 预期达到的目标
(1)上位机显示出人体心率,人体体温以及用户睡眠过程中的翻身次数等信息并在上位机显示出来。
(2)上位机具备显示各项数据实时曲线的功能,可方便管理人员进行数据分析,以及数据库功能记录数据。
1.4 本章小结
  本章主要介绍了本次毕业设计项目的研究目的及意义,以及对国内外相关领域的研究现状进行分析和讨论,从
而初步的确定了研究内容。

第2章 系统总体方案设计

2.1 需求分析
2.1.1 功能需求分析
  睡眠质量检测最主要需要测量的几个重要因素为心率血氧,体温,翻身次数。所以本次设计需要能够实时测量
人体心率血氧,人体体温,如果超出正常阈值时通过蜂鸣器报警告知佩戴者身体出现了异常需要及时关注身体健
康,翻身次数虽然也是睡眠检测的一部分,但翻身次数并不会对人体健康造成严重影响所以在设计时不考虑翻身次
数的阈值告警问题。
  在得到检测数据时为了使佩戴者可以直观的看到自身测量出来的数据,在本次设计中增加了显示系统实时的显
示测量的数据的功能。在此次设计中还增加了无线传输模块用来实现硬件与手机上位机之间的通信,手机上位机可
以更直观的查看佩戴者测量出来的数据,并且上位机可以设置心率血氧以及体温告警触发的阈值。
2.1.2 性能需求分析

  1. 体温传感器,心率传感器以及翻身次数的数据准确率不能低于95%;
  2. 数据传输速率不能低于20KB/s;
  3. 电源电路的输入是5V,输出速率为3.3V;
    2.2 设计任务
      系统通过主控单片机与各个睡眠质量检测需要使用的传感器连接起来进行数据实时采集并处理,在心率血氧以
    及体温过高或过低时通过蜂鸣器进行告警,通过显示屏将处理过后的数据展示出来,通过无线通信技术进行数据的
    实时传输,上位机可以实时接收数据并以折线统计图形式展示睡眠时数据的变化,上位机还可以更新设置告警触发
    阈值,通过以上来实时对睡眠质量进行着检测和预警。
    2.3 设计要求
    1、具备能检测睡眠质量需要的参数的功能。
    2、能正确的在TFT显示屏上显示出所检测到的相关数值。
    3、当检测到的心率以及体温值超过所设定的安全数值,蜂鸣器以及手机APP就会报警。
    4、设计的系统可以通过手机上位机实现更新相应安全数值的阈值。
    5、可以通过手机上位机实时的观察当前检测到的各项数值。
    2.4 系统设计的方案选择
    2.4.1 单片机方案的选择
    方案一
      采用传统的AT89C51单片机,AT89C51是由Atmel公司开发的,它是一种自带4K字节闪烁可编程可擦除只读存储器
    且具有低电压,高性能的8位微处理器,它能够与MCS-51兼容,但是其存储空间较小且保护能力较差容易烧坏芯片,
    最终放弃了此方案。
    方案二
      采用STM32单片机,STM32系列处理器是意法半导体ST公司生产的一种基于ARM 7架构的32位、支持实时仿真和跟
    踪的微控制器。使用ARM最新的、先进架构的Cortex-M3内核,具有优异的实时性能、杰出的功耗控制、出众及创新
    的外设,并且最大程度的集成整合,十分易于开发,可使产品快速将进入市场。
    方案三
      采用单片机芯片控制PIC单片机是Microship的产品,是目前市场份额增长最快的单片机之一。CPU采用RISC结
    构,分别有33、35、58条指令,是一个简化的指令集。同时采用Harvard双总线结构,运行速度快。它可以并行访问
    程序内存和数据内存。这种指令流水线结构在一个周期内完成两部分工作。然而其数据的传送和逻辑运算基本上都
    得通过工作寄存器W来进行,操作不方便且成本太高,故舍弃。
    故选择方案二。
    2.4.2 无线协议方案的选择
    方案一
      采用红外遥控模块系统进行无线控制。红外载波频率:38KHz,其理论遥控范围为8-10米,遥控范围内,电路简
    单,成本极低。但中间若有无障碍物等因素会影响到遥控距离,实际遥控距离可能更短,丧失了遥测的有用性。
    方案二
      采用ZigBee无线通信技术进行无线控制。此技术是为了弥补蓝牙通信协议的高复杂,功耗大,距离近,组网规
    模太小等缺陷所设计的。ZigBee工作频段有三个:868MHz-868.6MHz、902MHz-928MHz和2.4GHz-2.4835GHz,其中最
    后一个频段世界范围内通用,并且该频段为免付费、免申请的无线电频段。三个频段传输速率分别为20kbps,
    40kbps以及250kbps。该技术具有功耗低,网络容量大等优点。但数据传输速率低,有效范围小,抗干扰性差,故舍
    弃。
    方案三
      使用WIFI模块进行本系统数据的无线传输,Wi-Fi是一种可以将个人电脑、手持设备(如PDA、手机)等终端以
    无线方式互相连接的技术。Wi-Fi是一个无线网路通信技术的品牌,由Wi-Fi联盟(Wi-Fi Alliance)所持有。目的是
    改善基于IEEE 802.11标准的无线网路产品之间的互通性。Wi-Fi主要是用于替代工作场所一般局域网接入中使用的
    高速线缆的。这类应用有时也称作无线局域网(WLAN)。其覆盖性强,传输距离远。
    故选择方案三。
    2.4.3 心率传感器的选择
    方案一
      采用压力传感器采集心率信号,压力传感器传出的电信号比较微弱,测量难度大,且容易受外界干扰,在本次
    设计来说这种选择将提高系统的实现难度,是一种极不理想的选择。
    方案二
      采用MAX30102心率传感器采集心率信号,红外模块对采集的心率信号抗干扰能力较强,测量到的心率波形比较
    稳定,波形也很好;对于本次设计而言这将是一个很理想的选择。
    故选择方案二。
    2.4.4 体温传感器的选择
    方案一
      采用MLX90614温度传感器进行人体温度检测,MLX90614系列模块是一组通用的红外测温模块。在出厂前该模块
    已进行校验及线性化,具有非接触、体积小,成本低等优点。被测目标温度和环境温度能通过单通道输出,但由于
    其测温受很多因素影响,包括被测物体反射光谱影响,空气折射影响,准确度较低,误差大,故不考虑。
    方案二
      采用Maxim的 MAX30205 温度传感器进行人体温度检测,MAX30205模块能够精确测量温度,并提供一个超温警报
    /中断/关断输出。其采用高分辨率模数转换器,可准确测量体温并将其转换为数字形式。
    故选择方案二。
    2.4.5 血氧传感器的选择
      采用MAX30102传感器进行人体血氧检测,本次设计理念为在不影响功能的情况下尽可能地减少传感器的使用,
    以此来减小检测系统设备的体积,因在心率检测功能采用的MAX30102传感器同时具有血氧检测的功能,且血氧检测
    同样具有精度高的特点,所以血氧检测同样使用此传感器。
    2.4.6 显示器的选择
      采用TFT-LCD液晶显示屏作为数据显示屏。TFT液晶为每个像素都设有一个半导体开关,每个像素都可以通过点
    脉冲直接控制,因而每个节点都相对独立,并可以连续控制,不仅提高了显示屏的反应速度,同时可以精确控制显
    示色阶,所以TFT液晶的色彩更真。
    2.4.7 告警方式的选择
    方案一
    采用语音集成芯片ISD4004报警,由于ISD4004需要扩充喇叭驱动电路且其本身控制比较繁琐、电路比较复杂,稳定
    性差。基于以上考虑,所以放弃了此方案。
    方案二
    通过蜂鸣器实现报警电路,具有电路简单,性能可靠、稳定等优点,最重要的是低成本
    故选择方案二。
    2.5 本章小结
      本章一开始就确定了系统的总体设计,对本项目当中所运用到的各项先进技术进行了逐一的介绍,确定了具体
    的方案与总体的设计,对比分析了单片机,无线通讯协议,心率传感器,体温传感器,血氧传感器,报警方式以及
    显示器的最佳选择。

第3章 系统的硬件设计

3.1 系统硬件电路总体框图
设计系统在硬件上的选取如图3.1所示,本次设计中的各个模块与硬件的连接与设计会在后边的章节中一一说明,本
小节仅对系统总体框架进行宏观层面概况。在这里插入图片描述

图 3.1 系统硬件电路总体框图
  本次系统采用STM32F103C8T6单片机核心板,STM32单片机核心板用于连接系统的各个元器件,采集各个传感器
的数据以及对传感器的控制通过编写程序来实现;TFT显示屏通过UART通信接口连接到单片机上;MAX30102心率血氧
传感器将检测出来的数据通过内部的ADC进行采集与处理,之后通过I2C通信接口连接到单片机上;MAX30205人体体
温传感器将检测出来的数据进行AD转换之后通过SPI通信接口连接到单片机上;WiFi模块通过UART接口连接单片机,
可以接收单片机的配置指令和数据,以实现和服务器进行数据交互转而和手机APP通信;翻身检测模块通过I2C通信
方式与单片机连接;蜂鸣器等通过单片机的IO引脚连接单片机。
3.2 主控系统设计
STM32核心板的硬件由STM32芯片模块、ASP状态指示灯、主晶振和电源等器件组成,各器件的电路连线方法如图3.2
所示。在这里插入图片描述

图 3.2 STM32核心板电路图
  STM32单片机因为所有引脚对于5V的电压有很好的承受能力所以在作为主控芯片时可以保持高兼容性以及稳定
性,但如果想要保证系统的正常运行还有几点需要注意的地方:
  首先需要一个时钟晶振,它用来为系统提供时间考量标准,如果没有晶振系统运行时容易造成崩溃;另外为了
便于对硬件系统使用以及测试,需要在单片机上增加一个复位按键,在需要复位的时候可以一键复位提高效率;在
复位后程序会根据电路上的BOOT区引脚高低电平组合选择具体的电路启动,一般其引脚通过10K电阻接负极,程序会
在单片机内部Flash中运行。
3.3 心率采集电路
  心率检测电路分为两部分:一部分为模拟信号采集电路,通过RED和IR灯发出特定波长的光,采集人体反射回来
的光,经过PD管将光信号转化为电信号,最终通过18bit ADC转换器转化为数字信号。芯片内部有3.3V-5.0V的LED电
源和1.8V的逻辑电源,所以模块带有两路稳压电路,将5V电源分别转化为3.3V和1.8V;由于LED驱动电源的供电范围
为3.3V-5.0V,3.3V稳压电路可省去。
  第二部分为数字处理电路,将ADC转换出来的原始数据进行滤波处理后放置于缓冲区内;单片机通过IIC接口读
写芯片内部寄存器,读取出相应的数据;将控制引脚配置为上拉模式即可。心率检测电路需要接上5V电源,SDA、
SCL、INT引脚与单片机连接,
在这里插入图片描述

图 3.3 心率电路图
3.4 体温采集模块系统设计
  STM32主控芯片分配PB10及PB11脚用来与MAX30205体温采集电路连接,MAX30205分配引脚建立体温采集电路的硬
件连接,5V正电源接在MAX30205的VCC脚,5V负电源接在GND脚,体温采集电路的硬件连线方法如图3.4所示。在这里插入图片描述

图 3.4 体温采集电路
  采集电路工作时,STM32主控芯片通过PB10引脚与MAX30205连接以保障双方的时钟频率同步,STM32通过PB11引
脚输出MAX30205传感器工作需要的开始工作信号,此时开始工作,在体温检测模块采集到体温数据后将检测出来的
结果通过SDA引脚传输回单片机中,STM32主控芯片通过处理PB11上的输入信号便可确定人体的体温值。
3.5 血氧检测系统设计
  采集电路工作时,首先,红外检测采集电路中D1发射红外线,而Q1则接收相应组织的半透明度,同时转换为电
信号。为了避免在接收正常脉搏红外线时受到强光的干扰,电路中设计使用C2、C3背靠背串联组成的双极性耦合电
容构成一个简单的光电隔离电路,从而实现了对于干扰光线的隔离电路的连接方法如图3.5所示。在这里插入图片描述

图 3.5 血氧检测系统电路图
3.6 翻身感应系统设计
  STM32单片机分配PA5,PA6以及PA7以及三个引脚与MPU6000进行连接通信。通过单片机的PA5引脚与翻身检测系统
时钟线连接确定共同的时钟频率,通过时钟频率同步保障系统运行时不会出现时序错误,通过单片机的PA6,PA7引脚与翻身检测系统数据线连接,将工作信号以及检测出来的数据通过此通道进行实时传输。人体感测电路的连线方法
如图3.5所示。
  人体翻身电路工作时,STM32模块通过PA7检测传感器的输出信号,当PA7脚检测到翻身检测电平变化为5V时,说
明他正在翻身。相反,当PA7脚检测到0V信号时,说明他处于静止状态。
3.7 电源电路系统设计
  电源电路使用5V电池为硬件提供工作电源,利用AM1117-3.3V电压芯片为STM32核心板和心率传感器提供工作电
源。体温传感器传感器、翻身传感器的工作电源由5V电压提供。电路中放置一个LED_PWR指示灯,用于输入电源接通
指示信息。
  变压芯片的输入端放置电容C4和C5,变压芯片的输出端放置电容C6,电容用于确保电源电路输入5V直流电压,
输出3.3V的直流电压。
3.8 显示电路
  STM32核心板分配PA9以及PA10引脚,TFT液晶屏分配USART的TX以及RX引脚建立显示电路的硬件连接,5V正电源
接在TFT液晶屏的VCC脚,5V负电源接在GND脚,显
  显示电路工作时,先向显示屏输出复位信号,复位信号通过STM32模块PA9脚传输出,经由RES脚传递给液晶屏。
接下来向显示屏输出本次操作传输数据的类型,信号通过PA9脚经由DC脚传给液晶屏,当信号为5V时,代表传输显示
数据,当信号为0V时,代表传输操作指令。通过PA9脚将传递的数据,经由D1传输给OLED液晶屏。以上是一个字节数
据写操作的方法,重复执行以上操作,即可控制TFT液晶显示出各个参数的实时检测结果。
3.9 串口通信电路
  串口通信电路中,STM32核心板分配PA0到PA3脚,WiFi无线通讯模块分配RXD和TXD引脚建立通信电路的硬件连
接,5V正电源接在ESP8266模块的VCC脚,5V负电源接在GND脚,通信电路的连线方法如图3.10所示。
  串口电路工作时,STM32单片机通过操作PA2脚将需要发送的数据通过TXD引脚将数据发送给ESP8266WiFi传输系
统,串口通讯通过RXD接收数据后以无线传输的形式发送给上位机。上位机接收到数据后会将数据实时展示到上位机
界面中。在需要改变告警阈值的情况下通过在上位机将阈值更新之后以无线传输的形式传回ESP8266模块,之后通过
TXD引脚传回STM32单片机中更新阈值。
3.10 本章小结
  本章详细介绍了检测终端和远程控制端的硬件电路设计,检测终端硬件主要包括STM32核心板电路,心率采集电
路,体温采集电路,血氧采集电路,翻身次数电路,电源电路,显示电路,串口通信电路,以上介绍的电路是本次设
计的硬件基础。

第4章 系统软件设计

4.1 开发环境介绍
  本次设计的软件部分设计主要由两部分组成,下位机系统主程序通过Keil uVision5软件编写并调试,上位机部
分通过Visual Studio 2017编写并调试。
  下位机检测终端的软件由主程序、心率检测子程序、体温检测程序,血氧检测子程序和翻身次数子程序组成,
上位机远程控制由远程控制主程序,显示子程序,通信子程序组成,本节中将详细介绍各部分程序的具体实现过程。
4.2 系统主程序设计框图
4.2.1 检测终端主程序
本部分系统设计主要由keil uVision5软件编写与调试,程序采用移植性与操作性高的c语言编写,
主程序执行时,有以下几个过程需要处理:
1.初始化心率检测系统,体温检测系统,血氧检测系统,翻身检测系统,WiFi无线传输系统,显示系统以及蜂鸣器告警系统,之后为硬件复用相应的引脚功能,之后各个传感器开始执行各自的检测功能。
2.WiFi模块检测手机上位机的是否连接成功,当检测到连接成功后将数据通过无线传输协议传输到上位机中,之后
确定是否到1s计时时间,如果到达1s之后下位机将检测到的数据传输到上位机中。
3.确定使用期间是否有新用户加入或者用户退出。根据网络的连接状态,更新通信指示灯的工作状态,联网状态
下,指示灯500ms闪烁异常。联网异常状态下,指示灯50ms闪烁一次。
图 4.1 检测终端主程序流程图在这里插入图片描述

4.2.2 心率采集子程序
  心率采集子程序主要负责实时检测人体心率,由于在硬件设计时心率采集系统与单片机是通过I2C实现数据交互
的,属于单总线通讯,也就意味着数据只依靠一条数据线实现数据的接受与发送,具体操作的实现需要依靠高低电
平的时常来决定,通过该程序的执行流程如图4.2所示。
在这里插入图片描述

图 4.2 心率检测程序流程图
  首先进行时钟与引脚的初始化,使心率监测系统处于工作状态,此时检测系统处于等待检测的应答信号电平的
状态,在接收到信号电平之后心率监测系统不断地读取心率各个位的电平变化,在读取完16位数据之后进行数据处
理最终得到的数据就是检测出来的心率值。
4.2.3 体温采集子程序
  体温采集子程序主要负责实时检测人体体温值,由于体温检测电路与心率检测电路同样都是使用I2C进行数据传
输,所以在设计时需要通过SCL总线确定好两种检测电路的执行逻辑问题。该程序的执行流程如图4.3所示。在这里插入图片描述

图 4.3 体温采集子程序流程图
  在人体体温监测程序执行时,首先初始化IO引脚以及时钟门控使能,使体温监测系统处于工作状态,之后首先
将传感器设置为写模式,之后不断检测人体体温,在检测到体温后将数据进行处理整合,之后再传输回单片机中。
4.2.4 血氧采集子程序
  血氧采集程序同样采用I2C进行数据传输,所以同样需要SCL引脚控制血氧工作时机,该程序的执行流程如图4.4
所示。在这里插入图片描述

图 4.4 血氧采集子程序流程图
  血氧检测程序执行时,首先初始化IO引脚并将时钟门控打开,使系统处于可以检测的状态,之后在单位时间内
检测血氧含量,此时检测出来的数据为电信号,需要血氧检测系统通过内部AD进行转换,转换之后将数据通过SDA数
据线传输回单片机中。
4.2.5 睡眠翻身子程序
睡眠翻身子程序通过控制PA5-PA7脚的输入信号建立与单片机的控制关系,并根据返回的信号确定出人体存在状态。
睡眠翻身子程序的执行流程如图4.5所示。
在这里插入图片描述

图 4.5睡眠翻身子程序流程图
  睡眠翻身检测程序执行时,翻身检测模块根据PA5以及PA6脚的输入信号对人体的存在状态进行判断,当PA5脚出
现5V信号,说明佩戴者正在翻身,此时置位翻身标志。当PA5脚出现0V信号,说明在佩戴者翻身完成,此时清除翻身
标志,翻身次数加一。
4.2.6 远程控制端主程序
  远程控制端的主程序实现三个功能,其一是完成对硬件和协议栈的初始配置。其二是完成协议栈接口程序的处
理,实现与检测终端数据通信。其三是处理用户程序,对用户按输入的按键控制命令进行处理,并完成报警事件的
处理、联网状态的指示和系统运行信息的显示。另外,实现与上位机和用户之间的信息交换,以确保上位机和下位
机可以同时显示出系统的运行信息。远程控制终端主程序的执行流程如图4.6所示。在这里插入图片描述

图 4.6远程控制终端主程序流程图
  WiFi模块驱动设计的关键步骤分为两块,首先要根据模块的工作手册说明和模块进行波特率通信数据位以及停
止位等配置,这些参数可以通过配置单片机的UART寄存器即可,配置好这些参数之后,程序底层上就可以和模块连
通了。接下来最重要的就是根据数据协议包的格式编写数据发送和接收中断函数,在函数中接收数据后,进行解析
数据,将数据包中的关键信息读取出来,然后将数据给单片机其他响应程序处理。单片机中断每次只接受一个字符
的数据,所以需要申请一个数组变量用来按顺序存储数据进行组包,当接收到结束符说明一个数据包接收完成。
  通信子程序执行时,先确定是否接收到参数阀值更新数据,接收到数据对各个参数的阀值进行更新。之后将检
测终端上报的数据通过串口转发给上位机,数据上报完成后,软件返回到主程序继续执行。。
4.2.7 显示子程序
  显示子程序通过操作PA9以及PA10脚与TFT液晶屏建立控制关系,显示出检测出的心率,体温,血氧以及翻身次
数。
  显示子程序执行时,先接收需要显示的数据。再确定出起始命令值,并将显示数据通过数据线输出。最后,确
定所有的数据是否显示完成,显示完成返回到主程序。否则继续将显示数据发送到数据线上,直到所有的数据发送
完成位置。显示子程序的执行流程如图4.7所示。在这里插入图片描述

图 4.7 显示子程序执行流程图
4.3 上位机软件设计
  为了直观的显示出人体的心率、体温、睡眠翻身次数和血氧等检测参数的结果,同时实现对系统报警状态的远
程控制。本设计中在Window10开发平台使用C#语言完成了上位机软件的设计,上位机主要实现三个功能,其一是显
示功能,显示出各个参数的检测结果和报警区间阀值。其二是设置功能,接收键盘输入的命令对参数报警阀值的更
新命令。其三是实现与远程控制端设备的数据交换,实现上位机和下位机的信息的实时共享。上位机程序的执行流
如图4.9所示。
在这里插入图片描述

图4.9上位机程序执行流程图
  上位机程序执行时,先对窗体、串口和按钮进行初始化。其次,确实是否接收到串口输入的检测数据,接收到
检测数据,更新各个参数的显示结果。从次,确定是否有按钮事件出现,出现按钮事件对人感报警状态的显示进行
更新。再次,确定是否有阀值设置命令输入,出现阀值设置命令对各个检测参数的阀值进行更新。最后,通过串口
将更新后的参数阀值和报警状态通过串口转发给下位机。执行完成后,软件返回到程序开始处重新执行以上操作。
4.4 本章小结
本章介绍的是软件部分的设计,主要包含了硬件对应模块的软件原理以及上位机的设计。

第5章 系统的调试与运行

5.1 设备安装
5.1.1 STM32模块安装
  STM32模块安装时,芯片的引脚朝下摆放在底板对应焊盘的表面,并用焊锡将模块的引脚和底板上的引脚连接到
一起。焊接完成后,利用万用表顺序测量模块的引脚和底板的引脚是否可靠连接到一起,避免有漏焊和虚焊的现象
出现。STM32模块的安装见图5.1所示。在这里插入图片描述

图 5.1 STM32模块安装图
5.1.2 显示模块安装
  TFT液晶屏安装时,将引脚标识字体朝上摆放在底板对应引脚的正上方,并将液晶屏的排针插入到底板对应的焊
盘上,并用焊将底板和液晶屏连接到一起。焊接完成后,利用万用表顺序测量模块的引脚和底板的引脚是否可靠连
接 TFT液晶屏的安装见图5.2所示。
在这里插入图片描述

图 5.2 TFT液晶屏安装图
5.1.3 MAX30102传感器安装
  MAX30102传感器安装时,将MAX30102传感器朝向内侧,并将传感器的对应的引脚朝下插入到底板对应的焊盘
上,并用焊将底板和液晶屏连接到一起。焊接完成后,利用万用表顺序测量传感器各个引脚和底板焊盘的焊接情
况,确保传感器牢靠焊接在底板上。MAX30102传感器的安装见图5.3所示。在这里插入图片描述

图 5.3 MAX30102传感器组装图
MAX30205传感器和MPU-6000传感器的组装方法和MAX30102相同,文中不在进行介绍。
5.2 硬件调试
硬件组装完成将远程控制端和检测端的程序下载到STM32模块中开始进行初始化测试操作。测试时,先用万用表测量
一次各个器件的供电线是否正常,排除供电故障后,接通实物电源,进行初始化测试。测试结果如图5.4所示。在这里插入图片描述

图 5.4 实物通电测试图
  实物通电后OLED液晶屏上会显示出各个环境的检测结果,并且当各个参数均在设置的范围内时,蜂鸣器和指示
没有输出报警提示信息。此时上位机上也会同步显示出对应的检测结果,上位机的测试结果如图5.5所示。
在这里插入图片描述

图 5.5 正常工作模式上位机运行图
  通电测试结束后,改变环境参数模拟出变化的测试条件,对体温值、心率值报警以及翻身此时等功能进行逐一
测试,通过报警测试可以对系统的检测功能、显示功能和通信功能的运行情况进行综合测试。测试时先对硬件电路
进行排查,排除硬件连接故障和器件不良问题,确保硬件可以正常工作。然后对软件程序进行排查,排除时序故
障、引脚分配错误和检测数据计算错误问题。通过以上方法可以排除采集故障问题;再对蜂鸣器和指示灯下发报警
命令,如果器件不能正常工作,排除硬件连线故障和器件不良问题,同时确保软件下发正确的控制命令。以上测试
完成后,下位机和上位机会同时输出报警信息。下位机的测试结果如图5.6所示。在这里插入图片描述

图 5.6 报警工作模式下位机运行测试图
  在上图中,在报警模式测试时,OLED液晶屏上会显示出各个环境的检测结果,并且蜂鸣器和指示灯在下位机端
输出报警提示信息。上位机上会同步显示出各个参数的检测结果和超标报警提示信息,同时数据库记录并保存历史
数据。上位机的测试结果如图5.7所示。
在这里插入图片描述

图 5.7 报警工作模式上位机运行图
  上位机的运行结果说明系统可以同步显示出各个参数的检测信息,并能显示出超标报警提示信息。以上测试结
果说明系统在报警模式下可以稳定可靠的工作。
5.3 软件调试
首先要下载并安装jlink软件以及下载并安装Keil MDK,再下载调试器的驱动程序,最后利用jlink完成总体程序的
运行,下载调试工具如图5.8所示。在这里插入图片描述

图 5.8调试工具框
  软件调试最重要的就是对数据进行跟踪调试,需要结合JlinkOB下载调试器,连接到STM32单片机的下载调试接
口,然后再Keil5MDK中打开工程程序,进行Debug,将返回数据的变量添加到watch1变量观察窗口,结合断点放置在
采集程序中,每次进入断点后单步执行,观察变量的值,然后对照输入待测的手势,将执行结果和预期计算结果做
对比,依次来调试该部分程序是否达到预期效果。
  软件调试首先需要关注的是单片机,在Keil上建立程序机制,导入初始文件、核程序文件、标准库文件,配置
Keil的环境,在设计中选择一个引起微控制器变化的蜂鸣器,测试微控制器电平的变化,观察下管接口是否都应用
正常,框架是否正常,下一步才可以添加另一个驱动程序。
  其次添加TFT显示驱动程序,是为了在后面的各项数据进行更加方便掌握具体的数值。这方面程序的相对而言比
较简单,加上底层驱动程序后,在程序上一直刷屏看看显示屏的填写是否正常,然后再根据内容确认下中文的底层
程序是否能正常工作。
  接下来是MAX30102人体心率血氧传感器和MAX30205人体体温传感器的误差调查,这部分误差主要是关于ADC采集
的数值,在调试模式下,AD接收引脚连接到3.3V,看第一个数据是否约为4095,连接GND上,观察第一个数据是否约
为0,不存在异常现象后表示AD采集正常,再将起始值在线性计算公式中算出心率和体温值的问题。
  给系统上电前,首先需要为设备开一个热点,热点名设置为“ZNJJ”,热点密码设置为“0123456789”。热点
的开设是为了与设备的WiFi模块进行数据通信,也是设计进行数据无线远程通信的基础。其次给设备上电,等待设
备开启和运行,上电后会TFT屏上会显示“ready”,然后等待连接到提前设好的热点后,屏幕会显示
“connected”。这一过程是不需要认为进行干预的,是设备上电后自动完成的,连接完成后,屏幕上会显示出当前
人体的心率血氧、体温、翻身次数等一系列的环境参数值。这些参数值会通过WiFi远程通信实时传送到手机APP上,
当前环境的相关变量值会同时显示在手机APP中。
  最后打开手机APP调试APP和硬件设备之间的数据通信,查看APP上的连接状态是否显示连接,如果是再查看心率
血氧,体温以及翻身次数数据是否显示。能否切换模块。具体的手机app演示操作界面如图5.6所示。
在这里插入图片描述

图 5.9 手机app截图
5.4 本章小结
本章是对软硬件的测试部分,测试结果十分顺利,能够很好的运行并且达到了预期的效果。

第6章 结论与展望

6.1 主要结论
  本文设计一个基于STM32单片机的睡眠质量检测系统,实现了对人体心率检测,对人体体温检测,对人体血氧检
测以及睡眠者睡眠时的翻身次数检测并实时在显示器以及上位机中显示。通过上位机可以设置告警阈值,当体温,
心率以及血氧超过阈值时触发告警装置,设计对系统的实现及制作过程进行了具体的分析,并制成了系统的实物,
同时完成实物的测试工作。
本文完成的工作,总结如下:
  (1)通过方案的选择和对比,确定以STM32单片机的ARM核心为数据处理及无线数据传输核心,MAX30102传感器、
MAX30205传感器和MPU-6000传感器为检测手段,WiFi作为无线通信途径,液晶显示、蜂鸣器、指示灯及上位机为信
息交换机制的系统实现方案,实践证明该方案是可行的。
  (2)根据实际的应用需求,设计了检测终端和远程控制端的硬件,搭建了下位机的执行平台,为控制软件的工
作,提供了硬件运行基础。
(3)根据实际的应用需求,设计了检测终端和远程控制端的软件,实现了对下位机硬件的有效控制。
  (4)在Window10开发平台利用C#语言设计了上位机程序,实现了检测信息的同步显示及参数设置的远程控制。
  (5)完成了实物的测试工作,对系统环境参数检测功能、同步显示功能、报警功能和参数设置管理工作进行测
试,对设计输出进行了验证。
  测试结果表明实物各项功能均能稳定运行,且满足了开发输入的要求。现如今很多学科都在从事睡眠质量检测
相关产品的研究,试图进一步完善系统的功能和应用范围,以本设计来看,尽管达到预期的目的,但也存在一些不
足,比如不能实现语音告警,不能语音播放检测结果,不能向用户手机发送报警短信等,后续的设计考虑增加语音
模块和GAM短信报警模块等设备加入到系统设计中,以进一步提升系统的应用灵活性和报警的实时性。
6.2 展望
  随着科技日新月异的发展时代在飞速的进步,科技已经走进了千家万户,但是随之也带来了各种睡眠问题,睡
眠不足会导致许多不必要的麻烦,本系统本系统结构简单,可靠性高, 既保证了用户的睡眠质量,也在不影响用户睡眠的情况下对用户进行准确的检测。也使得用户不需要前往大型医院就可以进行准确的测量。
  本项目有很强的实用性,并且应用环境广范,在未来的设计中此项设计不仅可以投放于家庭中,还可以投入大
型市场,这项设计对于试睡员来说更是一个不可或缺的东西,可以让他们减少一定程度的工作量。

谢 辞

时光荏苒,岁月如梭,转眼间发现我已不是当初那个毛头小子了。经过四年时光的打磨,在各位导师,同学的
帮助下,我一次次摔倒又站起来,因为有他们,我才一直不曾轻易放弃。而如今,随着这篇论文的撰写,我才真切
的意识到,我真的面临毕业了,颇多感慨不知从何说起。几个月前我在整理论文,查找资料,整理材料时还在感慨
日子怎么这么难捱,每一个字好像都写的很费力。可是随着这段谢辞的一点点敲定,我才意识到,这好像也没有那
么难捱,日子跑的很快,这段谢辞的完结就意味着我马上就要答辩了。回首这四年的时光,刚到学校到现在一幕幕
在眼前划过,从最初发现大学与高中区别的欣喜,到现在的依依不舍。马上就要毕业了,离开了母校后无限怀念,
其中尤其要感谢我的指导老师。如果说论文给我的大学四年画上了圆满的符号,那么指导老师就像是叫一个牙牙学
语的婴孩般无私无畏的帮助我,论文的写作方向以及构架无一不显示着老师的身影。论文初稿完成时,老师对初稿
逐字逐句的批改,斧正错误。除此之外,老师并不只是我一个人的老师,他不仅仅要帮助我还要帮助其他同学修改
论文,同时还要完成教学任务,任务量可想而知。然而,他并没有敷衍行事 ,而是事无巨细的亲力亲为,让我颇受
其行事作风的影响。在每一次精细到字的回稿中我都深受震撼,同时也明白了不论是做人还是做学问只要开始做了
就要做到最好。
  论文的顺利完成除了有老师帮助外还离不开各位同学和朋友的帮助,每次在我遇到困难的时候总有一两只手挟
带着光影撞进我的一方世界,撕裂黑暗,赶走不良情绪,陪我一起度过大学时光。各位老师,同学和朋友们积极的
帮我寻找论文材料,给予我建设性的建议,将论文一点点填上血肉,我非常感谢你们的存在,在这些帮助下,我的
论文才能一点点完成。另外要感谢所有在大学期间教授过我知识的老师,是你们的悉心教导我才有了良好的专业课
知识,这也是论文得以完成的基础。在这里我谨代表同学们感谢各位老师的辛勤付出,也祝愿所有的老师们桃李满
天下。
  通过这次的论文我学习了很多,在写作过程中,我通过自己查阅资料,搜集有关的文献等培养了极强的自学以
及动手能力,这相对于之前被动的学习是一种巨大的转化。由被动到主动,是一种传统的打破,相信在日后在社会
的闯荡与学习中也会有大用处。并且在这次论文的写作过程中我的心境也有了一定的变化,不再那么浮躁,毫不夸
张的说,甚至有一种洗尽铅华的感觉,这是一种沉淀,似大浪淘沙般。最初我会因为论文各种改动而浮躁不堪大
用,到最后却有我自岿然不动的感觉,比以往的冲动多了一份度属于成年人的稳重,可以耐下心来,一点一点的雕
琢论文的细节,或许这就是论文给毕业生的最后一份考验与礼物吧。总之,通过这次的论文我成长了很多,也学会
了很多,也为我的大学四年做了最后的道别。
  最后,为我的四年时光做一个道别,也再次郑重地表达一次对各位老师同学的感谢。本论文在老师的悉心指导
和严格要求下也已完成了,从课题的选做以及具体的写作中到处都是都是老师的身影。如果没有老师的帮助和指
导,我想我肯定不会这么顺利的完成毕业论文。在临近毕业之际,我想借此机会向各位老师们表达一下感激之情,
四年来第一次如此直白的表示感激之情,竟有些愧疚,这四年无数个日日夜夜有的是机会可以表达,可我却不知珍
惜,偏偏到此时才敢开这个口。感谢各位老师的辛勤栽培,不积跬步无以至千里,各位任课老师尽心尽力的教导让
我掌握了很多知识,能让我在社会上留有一席之地,或许很多老师都已不记得我,或许我不是老师们最惊艳的学
生,但是一日为师终身为父,我会一直感念这四年来的点点滴滴。一别经年,不知何时再见,总说学校就在这里,
可离别了学校后我才知道什么是身不由己。
在此,我再次感谢老师们如此耀眼,却甘做我们进步的阶梯,同时也祝愿各位老师往后余生身体健康,平安喜乐。

附 录

附录A 电路原理图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

附录B部分程序源码

附录B部分程序源码
void beep()
{
GPIO_SetBits(GPIOA,GPIO_Pin_6);
delay_ms(100);
GPIO_ResetBits(GPIOA,GPIO_Pin_6);
delay_ms(100); 
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
25
   GPIO_InitStructure.GPIO_Pin= GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void set_xinlv()
{
b[0]=('X');
b[1]=('0'+xinlv%1000/100);
b[2]=('0'+xinlv%100/10);
b[3]=('0'+xinlv%10);
b[4]=('>');
b[5]=('0'+xin_up%1000/100);
b[6]=('0'+xin_up%100/10);
b[7]=('0'+xin_up%10);
b[8]=('/');
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
for(;;)
{
if(key_2==0)
{
while(key_2==0)
{
xin_up++;
if(xin_up>=255)
xin_up=255;
b[4]=('>');
b[5]=('0'+xin_up%1000/100);
b[6]=('0'+xin_up%100/10);
b[7]=('0'+xin_up%10);
b[8]=('/');
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
26
delay_ms(200);
}
}
if(key_3==0)
{
while(key_3==0)
{
if(xin_up>0)
xin_up--;
b[4]=('>');
b[5]=('0'+xin_up%1000/100);
b[6]=('0'+xin_up%100/10);
b[7]=('0'+xin_up%10);
b[8]=('/');
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
delay_ms(200);
}
}
if(key_4==0)
{
while(key_4==0)
delay_ms(200);
break;
}
}
b[4]=('/');
b[5]=('0'+xin_up%1000/100);
b[6]=('0'+xin_up%100/10);
b[7]=('0'+xin_up%10);
b[8]=('>');
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
delay_ms(200);
for(;;)
{
if(key_2==0)
27
{
while(key_2==0)
{
xin_down++;
if(xin_down>=255)
xin_down=255;
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
delay_ms(200);
}
}
if(key_3==0)
{
while(key_3==0)
{
if(xin_down>0)
xin_down--;
b[9]=('0'+xin_down%1000/100);
b[10]=('0'+xin_down%100/10);
b[11]=('0'+xin_down%10);
b[12]=('n');
b[13]=('/');
b[14]=('m');
OLED_ShowStr(0,2,b,2);
}
}
if(key_4==0)
{
while(key_4==0)
delay_ms(200);
break;
}
} 
}
void Uart2Sends(u8 *str)
{
while(*str!='\0')
{
USART_SendData(USART2,*str); delay_us(1200);
str++;
}
}
28
void send_data()
{
R_flag=0;
for(i=0;i<32;i++)
{
rec[i] = ' ';
}
Uart2Sends("AT+HEART\r\n"); 
}
void USART2_IRQHandler(void)
{
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
Receive =USART_ReceiveData(USART2);
rec[R_flag] = Receive;
R_flag++;
} 
}
void read_xin()
{
send_data();
delay_ms(200);
if(strstr(rec, "NULL"))
{
xinlv = 0;
}
else
{
if(rec[7] <= '2')
{
   xinlv = (rec[7]-'0')*100 + (rec[8]-'0')*10 + (rec[9]-'0');
}
else
{
xinlv = (rec[7]-'0')*10 + (rec[8]-'0');
}
}
}
void send_data_spo2()
{
R_flag=0;
for(i=0;i<32;i++)
{
rec[i] = ' ';
}
Uart2Sends("AT+SPO2\r\n"); 
}
29
void read_spo2()
{
send_data_spo2();
delay_ms(200);
if(strstr(rec, "NULL"))
{
spo2 = 0;
}
else
{
if(rec[6] <= '2')
{
   spo2 = (rec[6]-'0')*100 + (rec[7]-'0')*10 + (rec[8]-'0');
}
else
{
spo2 = (rec[6]-'0')*10 + (rec[7]-'0');
}
}
}
void send_blue()
{
   USART_SendData(USART1,weidu_A);delay_ms(1);delay_us(200);
   USART_SendData(USART1,weidu_B);delay_ms(1);delay_us(200);
   USART_SendData(USART1,weidu_C);delay_ms(1);delay_us(200);
   USART_SendData(USART1,jingdu_A);delay_ms(1);delay_us(200);
   USART_SendData(USART1,jingdu_B);delay_ms(1);delay_us(200);
   USART_SendData(USART1,jingdu_C);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xinlv/100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xinlv%100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xin_up/100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xin_up%100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xin_down/100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,xin_down%100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,temp/10);delay_ms(1);delay_us(200);
   USART_SendData(USART1,temp%10);delay_ms(1);delay_us(200);
   USART_SendData(USART1,temp_up/10);delay_ms(1);delay_us(200);
   USART_SendData(USART1,temp_up%10);delay_ms(1);delay_us(200);
   USART_SendData(USART1,Y_Z/100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,Y_Z%100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,time/100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,time%100);delay_ms(1);delay_us(200);
   USART_SendData(USART1,warn_flag);delay_ms(1);delay_us(200);
}
void warn()
{
   if((xinlv<xin_down)||(xinlv>xin_up)||(time>10)||(temp<temp_up))
30
{
warn_flag = 1;
}
if(warn_flag==1)
{
beep();
}
}
void TIM3_IRQHandler() 
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
Y_Z = GetData(ACCEL_YOUT_H);
if(Y_Z>30000)
{
Y_Z = 65636-Y_Z;
Y_Z = Y_Z/175;
}
else
{
Y_Z = Y_Z/175;
}
count++;
if(count>10)
{
count = 0;
if(Y_Z>30)
{
if(time<999)
time++;
}
else{
time = 0;
}
}
}
int main(void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
I2C_Configuration();
OLED_Init();
OLED_CLS();
GPIO_Configuration();
uart_init_1(9600);
uart_init_2(9600);
delay_ms(100);
GPIO_ResetBits(GPIOA,GPIO_Pin_6);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值