项目介绍:
这个项目主要是从亚健康的角度出发,结合可穿戴设备,实时监测血氧饱和度、脉搏和体温是人体非常关键的生理指标。
STM32人体亚健康检测系统的基本构成
系统分为主要七个模块有单片机系统、温度检测模块、血氧和心率检测模块、键盘模块、报警模块、显示模块和电源模块,本设计系统总的设计思路框架如下图所示。
温度检测模块和血氧/心率检测模块采集到信号传输到STM32单片机模块,同时电源模块通过单片机模块供电整个系统,采集到的三个信号在经过单片机的一系列复杂操作之后,输出到报警模块和显示模块,当显示模块显示脉搏和血氧、体温超出正常范围之外蜂鸣器报警。单片机系统控制器通过控制扩展的I / O信号来进行扫描键盘,便于能够更加方便控制整个系统。
硬件设计 单片机最小系统
采用STM32F103c8t6最小系统,它包括MCU、电源稳压 电路、电源滤波电路、BOOT选择、指示灯电路、程序烧录接口、 晶振电路、复位电路、外接IO、电源输入电路。
检测部分
数据检测分为心率血氧传感器和温度检测两部分。
MAX30100心率血氧传感器
这一款传感器的原理是通过光电容积法进行脉搏信号的测量。 传感器设有红光二极管和红外光二极管,在传感器另一侧安装有一 个光电检测器,将检测到的透过手指或者耳垂的光转化为电信号。
利用ADI的AD620ARZ-REEL芯片主要完成脉搏传感器和滤波电路的连接,对采集的小信号进行放大。
Maxim的芯片Max30100是一款集成的脉搏血氧和心率检测传感器。它使用了两个LED灯,一个用来优化光学的光电探测器,和低噪声模拟信号处理器,用来检测脉搏的血氧和心率信号。Max30100的运行电压在1.8V到3.3V之间,并且可以通过软件来控制,待机电流极小,可以忽略不计,这样可以使电源在如何时候都能保持连接状态。
DS18B20温度传感器
DS18B20 数字温度计提供 9-12 位摄氏温度测量而且有一个由高低电平触发的可编程的不因电源消失而改变的报警功能。DS18B20 通过一个单线接口发送或接受信息,因此在中央处理器和 DS18B20 之间仅需一条连接线(加上地线)。它的测温范围为-55~+125℃,并且在-10~+85℃精度为±5℃。除此之外,DS18B20能直接从单线通讯线上汲取能量,除去了对外部电源的需求。每个 DS18B20 都有一个独特的 64 位序列号,从而允许多只 DS18B20 同时连在 一根单线总线上;因此,很简单就可以用一个微控制器去控制很多覆盖在一大片区域的 DS18B20。这一特性在 HVAC 环境控制、探测建筑物、仪器或机器的温度以及过程监测和控制等方面非常有用。
数据显示部分
数据显示电路选择使用了LED数码管。由于LED功耗小,使用期限长,成本低,发光高等优点,再加上驱动简单,因此易于使用微控制器来控制和编程LED表明。发光数码管其原理所使用的材料主要是半导体发光器件,它的基本单元是发光二极管。根据段数将数码管分为七段数码管和八段数码管。八段数码管比七段数码管多了一个LED单元。按能显示多少个“8”,分为2位数,4位数等。
键盘部分
这个方案所使用的独立键盘式:实现独立键盘的基本方法是利用单片机的读取端口的I / O端口电平来判断系统是否有接有按键。将不用关的按钮的一端连接到地,另一端就连接到I / O端口。在程序开始时,将此I / O端口设置为高电平。在一般情况下,当硬件电路不按任何按键的时候,I / O端口将会被系统保护为高电平。当按下其中一个按键时,此I / O端口与地面之间的短路将I / O端口置于低电平。 松开按键后,在微控制器内部的上拉电阻将会使I / O端口继续依旧保持高电平。最后需要处理的就是检查一下程序中此I / O端口的电平状态,以了解此设计中是否有关键动作。
结合本设计的设计操作要求,实现3个按键的功能都必须使用独立式键盘。3X3 的矩阵式键盘以及中断工作方式被采用在本设计中,当有键按下时,中断请求会被发送到 CPU,中断服务程序会在 CPU 响应后执行,键盘才会被扫描。
检测报警部分
当检测到的温度值超过设定范围和血氧脉搏异常值时,单片机会接收到传感器所传来的超温信号,然后就会发送控制信号去激活蜂鸣器使其发出警报声。蜂鸣器由单个I / O端口控制,并由简单的晶体管放大器电路驱动。 设计软件后,只要在需要的时候给此I/O脚发相应的脉冲即可。
电源串口模块
如图所示,电源座是供电电路, 下载串口是程序输入端,供电电压为 DC 5v。
软件设计
脉搏血氧饱和度测量仪的软件部分主要包括:硬件初始化和系统自检,红光和红外光的时序控制,A/D采样和数据的操作,数码显示等模块。以下是流程图:
关键性代码说明:
我们可以通过软件来控制Maxim的芯片Max30100进行脉搏血氧和心率的检测,其主要代码如下:
#include "adc.h"
#include "led.h"
#include "oled.h"
#include "uart.h"
#include "math.h"
#include "delay.h"
#include "stdio.h"
#include "myiic.h"
#include "timer3.h"
#include "stdlib.h"
#include "MAX30100.h"
#include "stm32f10x.h"
#include "MAX30100_Filters.h"
#include "MAX30100_PulseOximeter.h"
#include "MAX30100_SpO2Calculator.h"
#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
u32 TimingDelay = 0;
u16 led_count = 0;
float Tempertaure_val=0; //体温变量
signed short HeartRate_val=0; //心跳速率
u8 SPO2_val = 0; //血氧浓度
u8 str[20]; //字符串缓存
_Bool send_flag = 0; //发送标志位
u8 mpu_flag = 0;
_Bool mpu_1_flag = 0;
_Bool mpu_2_flag = 0;
int SVM; //人体加速度向量幅值SVM和微分加速度幅值的绝对平均值DSVM是区分人体运动状态的重要参量。SVM通过计算加速度幅度表征人体运动的剧烈程度,其值越大表明运动越剧烈。
u8 t=0,i=10;
int main(void)
{
float pitch,roll,yaw; //欧拉角
short aacx,aacy,aacz;
SysTick_Config(SystemCoreClock/1000); //系统定时器初始化 1MHz 每1ms执行一次中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
Delay_Ms(100); //等待配置稳定
/***************第一部分:初始化部分*************/
LED_Init(); //板载显示初始化
UART1_Init(); //打印调试信息
LCD_Init(); //初始化LCD模块
ADC1_Init(); //初始化ADC用于温度获取-----获取 “A0”ADC值
IIC_Init(); //血氧浓度模块IIC-----SCLK接到“B8”脚 SDIN接到“B9”脚
TIM3_Init(); //每1ms执行一次中断, RunTime 每1ms加 1
SPO2_Init();
MPU_Init(); //初始化
Delay_Ms(1000); //等待初始化稳定
while(mpu_dmp_init())
{
//printf("MPU6050 Error");
Delay_Ms(200);
}
show_interface(); //显示主界面
/***************第二部分:数据显示更新部分*************/
while(1)
{
//====心跳血氧====
POupdate(); //更新FIFO数据 血氧数据 心率数据
//====温度获取====
Tempertaure_val = get_temp(); //获取人体温度
show_temp(Tempertaure_val); //屏幕显示温度
//=== Max30100数据获取====
if((t%10)==0)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
MPU_Get_Accelerometer(&aacx,&aacy,&aacz); SVM = sqrt(pow(aacx,2)+ pow(aacy,2) + pow(aacz,2));
//printf("pitch:%0.1f roll:%0.1f yaw:%0.1f SVM:%u\r\n",fabs(pitch),fabs(roll),fabs(yaw),SVM);
//分析x、y、z角度的异常判断
if( fabs(pitch)>40 || fabs(roll)>40 || fabs(yaw)>40 )//倾斜角度的 【绝对值】 大于40°SVM大于设定的阈值时,即认为摔倒
mpu_1_flag = 1;
else
mpu_1_flag = 0;
//分析加速度SVM的异常判断
if( SVM>23000 || SVM<12000 )i = 0;
i++;
if( i<=10 )mpu_2_flag = 1;
else
{
i = 10;
mpu_2_flag = 0;
}
//综合欧拉角、SVM异常判断异常
if( mpu_2_flag || mpu_1_flag )mpu_flag = 1;
else mpu_flag = 0;
show_mpu(mpu_flag);
}
t=0;
}
t++;
//==== Max30100发送数据====
if(send_flag)//SysTick_Handler()设置1s发送一次数据
{
printf("%0.2f %d %u %u\r\n",Tempertaure_val,HeartRate_val,SPO2_val,mpu_flag);
send_flag=!send_flag;
}
Delay_Ms(10);
}
}
/***************系统定时器中断函数*************/
void SysTick_Handler(void)
{
TimingDelay--; //延时函数所需的变量
led_count++; //每1s发送一次数据
if(led_count>=1000)
{
led_count=0;
send_flag=!send_flag;
}
}
系统实现和调试 设计初始开机状态
系统刚刚开机,系统状态灯亮,HR为脉搏,SpO2为血氧状态,Temp为温度值,初始状态如图5所示。
三个功能实现状态
体温检测功能和脉搏检测、血氧检测功能,这三个数值都可调控,设计接通电源开机状态血氧检测范围为80%到100%,脉搏为120值以下,体温为38.00度以下,超过数值设定范围就会触发报警。三个数值范围可以通过按键设定调控,本设计带有断电自动复位功能,当切断电源后,重新接通电源后,系统复位设定数值也会重新复位。
结论:
本文主要是设计出了系统的印刷电路板,并且进行了简单的仿真,利用了单片机技术和集成好的心率血氧传感器模块设计出了基 于 STM32 单片机的检测心率血氧的系统,实现了对心率和血氧的 实时检测,对本文系统的硬件和软件部分都进行了阐述。
本文所展示的系统有下面三个优点:
(1) 采用的心率血氧检测方式是无创的方法,不会对人体造成创伤和疼痛。
(2) 本文采用的元件价格低廉,制造成本低。
(3) 系统总体积相对较小,可以随身携带或放置在家中以便 随时检测,在这个老龄化和繁忙的社会中未来有很大的应用空间和发展空间。
心得体会: