基于stm32的心血管健康监测系统的设计_第1页
基于stm32的心血管健康监测系统的设计_第2页
基于stm32的心血管健康监测系统的设计_第3页
基于stm32的心血管健康监测系统的设计_第4页
基于stm32的心血管健康监测系统的设计_第5页
已阅读5页,还剩55页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

几何驱动的图像颜色编辑方法与应用摘要黄俊翔.便携式动态心电、血氧监护仪研制[D].桂林电子科技大学,2022.DOI:10.27049/ki.ggldc.2022.000643.张琥石,庞庆良,黄代政等.基于STM32的物联网多体征参数监护系统[J].现代电子技术,2023,46(08):79-83.DOI:10.16652/j.issn.1004-373x.2023.08.015.李瑾慧,潘涛,徐奕鸿等.基于脉搏波描记法的血氧饱和度实时监测[J].信息技术与信息化,2022,(11):78-81.赵阳光,信艺阳,张艳等.基于STM32的温室大棚环境远程监控系统设计[J].集成电路应用,2023,40(12):30-32.DOI:10.19339/j.issn.1674-2583.2023.12.011.李勇.基于单片机的医疗设备温湿度实时监测系统设计[J].电子制作,2024,32(03):94-97.DOI:10.16589/11-3571/tn.2024.03.024.申利民,翁桂鹏.基于OneNET云平台的智能粮仓监控系统设计[J].信息技术与信息化,2023,(12):185-188.田静.基于STM32的老年智能手环的设计与实现[D].南京邮电大学,2021.DOI:10.27251/ki.gnjdc.2021.000086.宋玥蓉,吴丽,袁福林等.STM32的智能宿舍烟雾检测器的设计[J].福建电脑,2023,39(10):88-92.DOI:10.16707/ki.fjpc.2023.10.018.AbeUC,MateusM,BrunoB,etal.MAX30102PhotometricBiosensorCoupledtoESP32-WebserverCapabilitiesforContinuousPointofCareOxygenSaturationandHeartrateMonitoring†[J].EngineeringProceedings,2021,16(1):9-9.AlsayaydehJAJ,YusofBFM,HalimABZM,etal.PatientHealthMonitoringSystemDevelopmentusingESP8266andArduinowithIoTPlatform[J].InternationalJournalofAdvancedComputerScienceandApplications(IJACSA),2023,14(4):29-30.MobileCommunications;ResearchersfromJaypeeInstituteofInformationTechnologyDetailFindingsinMobileCommunications(VehiclePollutionMonitoring,ControlandChallanSystemUsingMq2SensorBasedOnInternetofThings)[J].JournalofEngineering,2020,114:5-30.RohmatG,AsepA,MuhammadR.PerformanceComparisonforHearthRateSignalDetectionforDifferentLocationinFingertipandWristUsingSensorMAX30102[J].JournalofBiomimetics,BiomaterialsandBiomedicalEngineering,2023,6748:131-143.名称数量STM32单片机开发板1STM32F103RCT61MAX30102心率血氧模块1DTH11温湿度模块1DAP仿真器10.96英寸OLED屏1MQ2烟雾浓度模块1面包板1杜邦线若干ESP-01S模块1#include"blood.h"#include"usart.h"uint16_theart=0;uint16_tblood=0;uint16_tg_fft_index=0; //fft输入输出下标structcompxs1[FFT_N+16]; //FFT输入和输出:从S[1]开始存放,根据大小自己定义structcompxs2[FFT_N+16]; //FFT输入和输出:从S[1]开始存放,根据大小自己定义struct{ float Hp ; //血红蛋白 float HpO2; //氧合血红蛋白 }g_BloodWave;//血液波形数据BloodDatag_blooddata={0}; //血液数据存储#defineCORRECTED_VALUE 47 //标定血液氧气含量/*funcationstart*///血液检测信息更新voidblood_data_update(void){ //标志位被使能时读取FIFO g_fft_index=0; while(g_fft_index<FFT_N) { while(MAX30102_INTPin_Read()==0) { //读取FIFO max30102_read_fifo();//readfromMAX30102FIFO2 //将数据写入fft输入并清除输出 if(g_fft_index<FFT_N) { //将数据写入fft输入并清除输出 s1[g_fft_index].real=fifo_red; s1[g_fft_index].imag=0; s2[g_fft_index].real=fifo_ir; s2[g_fft_index].imag=0; g_fft_index++; } } }}//血液信息转换voidblood_data_translate(void){ floatn_denom; uint16_ti; //直流滤波 floatdc_red=0; floatdc_ir=0; floatac_red=0; floatac_ir=0; for(i=0;i<FFT_N;i++) { dc_red+=s1[i].real; dc_ir+=s2[i].real; } dc_red=dc_red/FFT_N; dc_ir=dc_ir/FFT_N; for(i=0;i<FFT_N;i++) { s1[i].real=s1[i].real-dc_red; s2[i].real=s2[i].real-dc_ir; } //移动平均滤波 UsartPrintf(USART_DEBUG,"8ptMovingAveragered\r\n");// for(i=1;i<FFT_N-1;i++) { n_denom=(s1[i-1].real+2*s1[i].real+s1[i+1].real); s1[i].real=n_denom/4.00; n_denom=(s2[i-1].real+2*s2[i].real+s2[i+1].real); s2[i].real=n_denom/4.00; } //八点平均滤波 for(i=0;i<FFT_N-8;i++) { n_denom=(s1[i].real+s1[i+1].real+s1[i+2].real+s1[i+3].real+s1[i+4].real+s1[i+5].real+s1[i+6].real+s1[i+7].real); s1[i].real=n_denom/8.00; n_denom=(s2[i].real+s2[i+1].real+s2[i+2].real+s2[i+3].real+s2[i+4].real+s2[i+5].real+s2[i+6].real+s2[i+7].real); s2[i].real=n_denom/8.00; UsartPrintf(USART_DEBUG,"%f\r\n",s1[i].real); } UsartPrintf(USART_DEBUG,"8ptMovingAverageir\r\n"); for(i=0;i<FFT_N;i++) {// UsartPrintf(USART_DEBUG,"%f\r\n",s2[i].real); } UsartPrintf(USART_DEBUG,"\r\n"); //开始变换显示 g_fft_index=0; //快速傅里叶变换 FFT(s1); FFT(s2); //解平方 UsartPrintf(USART_DEBUG,"开始FFT算法\r\n"); for(i=0;i<FFT_N;i++) { s1[i].real=sqrtf(s1[i].real*s1[i].real+s1[i].imag*s1[i].imag); s1[i].real=sqrtf(s2[i].real*s2[i].real+s2[i].imag*s2[i].imag); } //计算交流分量 for(i=1;i<FFT_N;i++) { ac_red+=s1[i].real; ac_ir+=s2[i].real; } for(i=0;i<FFT_N/2;i++) {// UsartPrintf(USART_DEBUG,"%f\r\n",s1[i].real); } UsartPrintf(USART_DEBUG,\r\n"); for(i=0;i<FFT_N/2;i++) {// UsartPrintf(USART_DEBUG,"%f\r\n",s2[i].real); } UsartPrintf(USART_DEBUG,"结束FFT算法\r\n");// for(i=0;i<50;i++)// {// if(s1[i].real<=10)// break;// } //UsartPrintf(USART_DEBUG,"%d\r\n",(int)i); //读取峰值点的横坐标结果的物理意义为 ints1_max_index=find_max_num_index(s1,30); ints2_max_index=find_max_num_index(s2,30); UsartPrintf(USART_DEBUG,"%d\r\n",s1_max_index); UsartPrintf(USART_DEBUG,"%d\r\n",s2_max_index); floatHeart_Rate=60.00*((100.0*s1_max_index)/512.00)+20; g_blooddata.heart=Heart_Rate; floatR=(ac_ir*dc_red)/(ac_red*dc_ir); floatsp02_num=-45.060*R*R+30.354*R+94.845; g_blooddata.SpO2=sp02_num; }voidblood_Loop(void){ USART_Cmd(USART2,DISABLE); //血液信息获取 blood_data_update(); //血液信息转换 blood_data_translate(); //显示血液状态信息 g_blooddata.SpO2=(g_blooddata.SpO2>99.99)?99.99:g_blooddata.SpO2; UsartPrintf(USART_DEBUG,"指令心率%3d",g_blooddata.heart);// OLED_ShowNum(4,7,g_blooddata.heart,3); UsartPrintf(USART_DEBUG,"指令血氧%0.2f",g_blooddata.SpO2);// OLED_ShowNum(3,4,g_blooddata.SpO2,3); heart=g_blooddata.heart; blood=(unsignedint)g_blooddata.SpO2; USART_Cmd(USART2,ENABLE);}voidDHT11_Start(void){ unsignedinttimeout; DHT11_Mode_Out_PP();//将PA7配置为输出模式 DHT11_DATA_OUT(0); //将电平拉低 Delay_us(20000); //保持低电平至少18ms DHT11_DATA_OUT(1); //将电平拉高 Delay_us(30); //保持高电平20~40us DHT11_Mode_IPU(); //DHT11的80us低电平响应信号 timeout=80; while((!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7))&&(timeout>0)) { timeout--; Delay_us(1); } //DHT11的80us高电平响应信号 timeout=80; while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)&&(timeout>0)) { timeout--; Delay_us(1); }}unsignedcharDHT11_Read_Byte(void){ unsignedinti; unsignedchardat=0; unsignedinttimeout; DHT11_Mode_IPU(); for(i=0;i<8;i++) { while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0);//等待50us过去 Delay_us(40);//跨过40us后再去读取信号线上的电平,如果为低电平标识数据为0,如果为高电平表示数据为1 dat<<=1; if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)) dat+=1; timeout=50; while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)&&(timeout>0)) { timeout--; Delay_us(1); } } returndat;}voidDHT11_Read(void){ unsignedcharHum_H_temp,Hum_L_temp,Tem_H_temp,Tem_L_temp,Check_Sum; //启动DHT11 DHT11_Start(); //连续读取5个Byte,共计40bit,内含湿度8位整数位,湿度8位小数位,温度8位整数位,温度8位小数位,校验和 Hum_H_temp=DHT11_Read_Byte(); Hum_L_temp=DHT11_Read_Byte(); Tem_H_temp=DHT11_Read_Byte(); Tem_L_temp=DHT11_Read_Byte(); Check_Sum=DHT11_Read_Byte(); //发送结束标志 DHT11_Mode_Out_PP(); DHT11_DATA_OUT(1); //将电平拉高 //判断读取的40bit数据是否有效,及检查校验和是否正确 if((Hum_H_temp+Hum_L_temp+Tem_H_temp+Tem_L_temp)==Check_Sum) { Hum_H=Hum_H_temp-80; Hum_L=Hum_L_temp; Tem_H=Tem_H_temp; Tem_L=Tem_L_temp;voidADC1_Init(void){ ADC1_GPIO_Config(); ADC1_Mode_Config(); } //传感器校准函数voidMQ2_PPM_Calibration(floatRS){R0=RS/pow(CAL_PPM/613.9f,1/-2.074f);}//MQ2传感器数据处理floatMQ2_GetPPM(void){floatVrl=(float)ADC_ConvertedValue/4096*3.3;floatRS=(3.3f-Vrl)/Vrl*RL;if(Vrl>1&&floag1==0)//获取系R0{ MQ2_PPM_Calibration(RS); floag1=1;}ppm=613.9f*pow(RS/R0,-2.074f);returnppm;}#include"stm32f10x.h"//网络设备驱动#include"esp8266.h"//硬件驱动#include"delay.h"#include"usart.h"//C库#include<string.h>#include<stdio.h>#defineWIFI_SSID "X" // WIFI的名称必须用2.4G的wifi不能用5G的,且不能用中文、空格#defineWIFI_PSWD "55332211" // WIFI密码#defineSERVER_HOST "mqtt.2gclmqtt.fun" // MQTT服务器域名或IP#defineSERVER_PORT "1883" // MQTT服务器端口(一般为1883不用改)#defineESP8266_WIFI_INFO "AT+CWJAP=\""WIFI_SSID"\",\""WIFI_PSWD"\"\r\n"#defineESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\""SERVER_HOST"\","SERVER_PORT"\r\n"unsignedcharesp8266_buf[128];unsignedshortesp8266_cnt=0,esp8266_cntPre=0;externu8ESP8266_INIT_OK;voidESP8266_Clear(void){ memset(esp8266_buf,0,sizeof(esp8266_buf)); esp8266_cnt=0;}_BoolESP8266_WaitRecive(void){ if(esp8266_cnt==0) //如果接收计数为0则说明没有处于接收数据中,所以直接跳出,结束函数 returnREV_WAIT; if(esp8266_cnt==esp8266_cntPre) //如果上一次的值和这次相同,则说明接收完毕 { esp8266_cnt=0; //清0接收计数 returnREV_OK; //返回接收完成标志 } esp8266_cntPre=esp8266_cnt; //置为相同 returnREV_WAIT; //返回接收未完成标志}_BoolESP8266_SendCmd(char*cmd,char*res){ unsignedchartimeOut=200; Usart_SendString(USART2,(unsignedchar*)cmd,strlen((constchar*)cmd)); while(timeOut--) { if(ESP8266_WaitRecive()==REV_OK) //如果收到数据 { if(strstr((constchar*)esp8266_buf,res)!=NULL) //如果检索到关键词 { ESP8266_Clear(); //清空缓存 return0; } } Delay_ms(10); } return1;}voidESP8266_SendData(unsignedchar*data,unsignedshortlen){ charcmdBuf[32]; ESP8266_Clear(); //清空接收缓存 sprintf(cmdBuf,"AT+CIPSEND=%d\r\n",len); //发送命令 if(!ESP8266_SendCmd(cmdBuf,">")) //收到‘>’时可以发送数据 { Usart_SendString(USART2,data,len); //发送设备连接请求数据 }}unsignedchar*ESP8266_GetIPD(unsignedshorttimeOut){ char*ptrIPD=NULL; do { if(ESP8266_WaitRecive()==REV_OK) //如果接收完成 { ptrIPD=strstr((char*)esp8266_buf,"IPD,"); //搜索“IPD”头 if(ptrIPD==NULL) //如果没找到,可能是IPD头的延迟,还是需要等待一会,但不会超过设定的时间 { //DEBUG_LOG("\"IPD\"notfound\r\n"); } else { ptrIPD=strchr(ptrIPD,':'); //找到':' if(ptrIPD!=NULL) { ptrIPD++; return(unsignedchar*)(ptrIPD); } else returnNULL; } } Delay_ms(5); timeOut--; //延时等待 }while(timeOut>0); returnNULL; //超时还未找到,返回空指针}voidESP8266_Init(void){ while(ESP8266_SendCmd("AT\r\n","OK")) //测试AT通讯 Delay_ms(200); while(ESP8266_SendCmd("AT+RST\r\n","OK")) //软复位,重置esp01s Delay_ms(200); ESP8266_SendCmd("AT+CIPCLOSE\r\n",""); Delay_ms(200); while(ESP8266_SendCmd("AT+CWMODE=1\r\n","OK")) //设置esp01s为ap模式,用于链接WiFi Delay_ms(200); while(ESP8266_SendCmd(ESP8266_WIFI_INFO,"GOTIP")) //发送wifi账号密码,让esp01s链接wifi Delay_ms(200); ESP8266_SendCmd("AT+CIPSNTPCFG=1,8,\"\"\r\n","OK"); //配置阿里云服务器域名 Delay_ms(200); UsartPrintf(USART_DEBUG,"wifiok\r\n"); ESP8266_SendCmd("AT+MQTTUSER

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论