脉搏血氧饱和度_第1页
脉搏血氧饱和度_第2页
脉搏血氧饱和度_第3页
脉搏血氧饱和度_第4页
脉搏血氧饱和度_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

脉搏血氧饱和度的测量一、测量值:脉搏血氧饱和度、脉率二、测量原理:以两路光线(红光vs,红外光ir)高频交替照射被测部位,两路透射光经光电转换得到两路变化的光电流信号,两路光电流信号经过放大、去直流、去工频干扰得到两路信号的交流部分,交流部分的平均功率之比即为动脉血的含氧量,通过线性拟合得到脉搏血氧饱和度;其中任何一路信号交流部分即为脉搏波,测得其周期可计算出脉率。三、测量电路及其参数。电路包括三部分:探头驱动电路、光电流放大和去直流电路、计算电路。探头驱动电路实现两路光线由对称的两组三极管构成,与计算电路的两个IO端口和两个DA端口相连,分别控制两路光线的交替开关和幅值。光电流放大和去直流电路由两级运放构成,一级运放将光电流信号放大为电压信号,这个电压信号包含交流分量和较大的直流分量(分别对应着测量部位的动脉血和其他成分),因此需要二级运放去直流处理。计算电路接受两个运放的输出,作为反馈为探头驱动电路和去直流电路提供参考电压幅值。探头接口说明:1为地线,6、7分别为外屏蔽和内屏蔽线,2为红外光输入正极,红光输入负极,3为红光输入正极,红外光输入负极,9为光电管输出正极,5为光电管输出负极。四、测量流程 基本测量流程如下图。200Hz定时器中断,两路LED交替通断,即1秒内两路光各有100次采样。以红外光这一路为例:每次开启红外光LED,根据OA0输出改变LED的幅度ir_LED_level(Q3的基极),根据OA1输出改变去直流电路的直流参考电压ir_dc_offset(OA1的正向输入端),得到的OA1的输出作为计算电路的输入,关灯,原始信号去工频处理后得到ir_heart_signal,数字去直流后得到ir_heart_signal_ac,该信号进入脉搏波周期判断的队列group_caculate[64],同时计算ir_heart_signal_ac信号的平方和,并且采样计数,同时进行脉搏周期的判断。数字信号直流跟随可表达为:跟随系数×(输入信号-直流分量)+直流分量=更新的直流分量。脉搏周期的判断过程:队列相当于在脉搏波信号上一个滑动的窗口,窗口应有一定宽度,大于噪声时间,但需小于脉搏周期。判断过程如下:当最小值位置处于窗口中部位置时则判定为一个波谷,检测到波谷以后窗口继续滑过10个采样点,但不再检查最小值,确保上一个波谷已经离开窗口中心,然后继续检查最小值位置确定下一个波谷。可以分为三种状态分别称之为确定波谷、离开波谷、寻找波谷。如下图。利用局部特征实时判断脉搏周期的三个阶段:1)确定波谷,确定周期,计算血氧饱和度和脉率,清空计数;2)离开波谷,开始计数,计算信号平方和;3)寻找波谷,保持计数,计算平方和,确定窗口中最小值位置五、测量程序实现(可参考pulsoximeter.c文件)1、变量设置1)全局参量根据运放一的输出经AD转化后判断LED是否过亮过暗,2500到3000之间为合适亮度,否则进行调节,快速调节步长为2,细调步长为1,可根据实际电路修改。//反馈控制LED驱动幅度时的上下界和调节步长#defineFIRST_STAGE_TARGET_HIGH3000#defineFIRST_STAGE_TARGET_LOW2500#defineFIRST_STAGE_TARGET_HIGH_FINE3500#defineFIRST_STAGE_TARGET_LOW_FINE2000#defineFIRST_STAGE_STEP2#defineFIRST_STAGE_FINE_STEP12)全局变量//脉搏血氧信号,存储脉搏血氧几个处理方法后的值int32_tir_heart_signal;//红外光,OA1输出经过平均滤波后,等待数字去直流int32_tvs_heart_signal;//红光,OA1输出经过平均滤波后,等待数字去直流int32_tir_heart_signal_ac;//红外光,经过数字去直流,进入计算窗口,参加平方和的累加int32_tvs_heart_signal_ac;//红光,经过数字去直流,进入计算窗口,参加平方和的累加int32_tsum_ir_heart_signal_ac=0;//红外光,信号平方和累加值,一个周期计算平均功率int32_tsum_vs_heart_signal_ac=0;//红光,信号平方和累加值,一个周期计算平均功率//计算过程信号intgroup_wave[512];//用于显示,循环队列,存储几个周期内的ir_heart_signal_ac信号intoffset_wave=0;//循环队列队列头intflag_initial=1;//初始化标志位intsample_count=0;//采样计数,每个周期清空,重新计数intnum_beat=0;//初始值为1,下一个脉搏后为2,计算平均功率和血氧饱和度,重新置1intflag_jump=0;//脉搏波周期判断,是否处于离开波谷的状态intsample_jump=0;//离开波谷时的采样计数,到20则已离开波谷,置0,flag_jump置1//循环队列,以滑动窗口的形式判断当前是否为脉搏波波谷intgroup_caculate[64];//用于脉搏周期判断的循环队列,存储64个ir_heart_signal_ac信号intoffset_caculate=0;//队列头位置intmin;//队列中最小值intlocation_min;//最小值位置intlocation_min_adjust;//最小值相对与队列头的位置,如果是32则确认一个波谷//最终结果//脉率unsignedintheart_rate=6000;//脉率最终测量结果,初始值为60.00unsignedintgroup_heart_rate[8];//最近8秒内的脉率,循环队列,初始化为6000intoffset_heart_rate=0;//队列头unsignedintsample_heart_rate;//脉率当前原始结果,经过一定调整后进入group_heart_rate[8]int32_tsum_heart_rate;//最近8秒的脉率累加值,除以8得到新的heart_rate//脉搏血氧饱和度unsignedintSpO2=9500;//血氧饱和度最终测量结果,初始值为95.00unsignedintgroup_SpO2[8];//最近8秒内的血氧饱和度,循环队列,初始化为9500intoffset_SpO2=0;//队列头int32_tsum_SpO2;//最近8秒的血氧饱和度累加值,除以8得到新的heart_rate//控制参数intfresh=0;//调试使用,无意义//反馈控幅和OA1参考电压的参数intled_tab=0;//控制开启红光还是红外光,每次中断切换状态intir_LED_level;//ir驱动幅度,控制Q3基极,范围1到2500,数字越大,亮度越弱intvs_LED_level;//vs驱动幅度,控制Q4基极,范围1到4095,数字越大,亮度越弱intir_dc_offset=4095;//ir灯直流参考电压,开启红外LED时,控制OA1正向输入端intvs_dc_offset=4095;///vs灯直流参考电压,开启红光LED时,控制OA1正向输入端intir_dc_offset_second=0;//数字去直流时的直流跟随量intvs_dc_offset_second=0;//数字去直流时的直流跟随量//运放输出的输出intir_sample;//ir灯,OA0的输出,根据该输出改变ir_LED_levelintvs_sample;//vs灯,OA0的输出,根据该输出改变vs_LED_level3)子函数unsignedlongisqrt32(registerunsignedlongh);//开方运算int16_tir_filter_test(int16_tsample);//平均滤波器_红外int16_tvs_filter_test(int16_tsample);//平均滤波器_红光2、程序主体(请参照pulsoximeter.c文件)1)晶振、电源设置2)初始化操作:group_heart_rate[8]初始化为6000,sum_heart_rate初始化为48000,group_SpO2[8]初始化为9500,sum_SpO2初始化为76000。3)DAC设置,ir_LED_level初始化为2500,vs_LED_level初始化为900。ADC设置。定时器设置,200Hz采样中断,1600Hz用于PWM输出。4)设置完,进入低功耗模式5)中断处理程序,200Hz中断,中断进入后或者进入红光LED流程,或者进入红外LED流程,都要根据输入调整相应参数,进行平均滤波,去直流处理。两种流程其他计算上有所不同:在红光流程中主要进行两路信号平方和累加、采样计数、脉搏血氧饱和度和脉率的计算;红外流程里主要进行的是脉搏周期的判断。两个流程的具体操作如下。红光流程:关闭两路灯,设置参数,开启红光LED,读取输入,关闭红光LED,根据输入调整参数,平均滤波,去直流,循环队列更新,是否处于找到波谷的状态(num_beat由1变为2,找到,否则未找到),未找到则计算两路平方和,采样计数累加,找到则计算脉搏血氧饱和度和脉率,平方和、采样计数置0。红外流程:关闭两路灯,设置参数,开启红光LED,读取输入,关闭红光LED,根据输入调整参数,平均滤波,去直流,循环队列更新,是否处于离开波谷的状态(flag_jump==0时为寻找状态,flag_jump==0时为离开状态),寻找状态找到循环队列中最小值及位置,判断是否波谷,不是波谷继续寻找,是波谷则进入离开状态,离开状态仅计数,计数满20次进入寻找状态。中断程序代码如下所示://红光流程if(led_tab==0)//led_tab==0,打开红光LED{led_tab=1;//切换led_tab,下一次进入红外流程P2OUT|=BIT2;//关灯P2OUT|=BIT3;//关灯DAC12_0CTL&=~DAC12ENC;//开启DAC,根据vs_LED_level给出幅度DAC12_0CTL&=~DAC12OPS;DAC12_0CTL|=DAC12ENC;DAC12_0DAT=vs_LED_level;//红光LED驱动幅度DAC12_1DAT=vs_dc_offset;//红光去直流电路的参考电压,OA1正向输入P2OUT&=~BIT3;//开灯,红光LEDADC12CTL0&=~ENC;//开启DAC,读取OA0、OA1输出ADC12CTL0|=ENC;for(m=1;m<=1500;m++)//伪循环提供DAC转换时间,红光LED保持开{}vs_sample=ADC12MEM0;//OA0输出结果i=ADC12MEM1;//OA1输出结果//OA0输出,根据全局参量控制LED的驱动幅度if(vs_sample>=FIRST_STAGE_TARGET_HIGH||vs_sample<=FIRST_STAGE_TARGET_LOW){if(vs_sample>=FIRST_STAGE_TARGET_HIGH){if(vs_sample>=FIRST_STAGE_TARGET_HIGH_FINE)vs_LED_level+=FIRST_STAGE_STEP;elsevs_LED_level+=FIRST_STAGE_FINE_STEP;if(vs_LED_level>=4095)vs_LED_level=4095;}else{if(vs_sample<=FIRST_STAGE_TARGET_LOW_FINE)vs_LED_level-=FIRST_STAGE_STEP;elsevs_LED_level-=FIRST_STAGE_FINE_STEP;if(vs_LED_level<=1)vs_LED_level=1;}}//OA1输出,控制OA1输入的参考电压if(i>=4095){if(vs_dc_offset>0)vs_dc_offset--;}elseif(i<100){if(vs_dc_offset<4095)vs_dc_offset++;}DAC12_0CTL&=~DAC12ENC;//关闭DAC_NOP();_NOP();P2OUT|=BIT2;//关灯P2OUT|=BIT3;//关灯//实时处理vs_heart_signal=vs_filter_test(i);//OA1输出,平均滤波处理vs_dc_offset_second+=((vs_heart_signal-vs_dc_offset_second)>>7);//数字直流跟随vs_heart_signal_ac=vs_heart_signal-vs_dc_offset_second;//去直流group_wave[offset_wave]=ir_heart_signal_ac+4000;//加4000保证脉搏波信号为正offset_wave=(offset_wave+1)&0x1ff;//循环队列更新,用于显示group_caculate[offset_caculate]=ir_heart_signal_ac;//循环队列更新,用于脉搏判断offset_caculate=(offset_caculate+1)&0x3f;if(num_beat>=1)//num_beat是否为1{sample_count++;//采样计数 //两路信号平方和累加sum_vs_heart_signal_ac+=((vs_heart_signal_ac*vs_heart_signal_ac)>>10);sum_ir_heart_signal_ac+=((ir_heart_signal_ac*ir_heart_signal_ac)>>10);}if(num_beat>=2)//num_beat是否为2,为2表示找到一个新的波谷{int32_tx=isqrt32(sum_vs_heart_signal_ac);//平方和开方int32_ty=isqrt32(sum_ir_heart_signal_ac);//平方和开方int32_tw=100*x/y;//平均功率之比R×100sum_SpO2-=group_SpO2[offset_SpO2];//8秒内血氧饱和度之和减去8秒前的值 //计算当先新的脉搏血氧饱和度,拟合公式110-25×R,R为平均功率之比group_SpO2[offset_SpO2]=11000-25*w; //调整新的脉搏血氧饱和度,变化不能超过3个百分点,范围在85到100之间if(group_SpO2[offset_SpO2]>(group_SpO2[(offset_SpO2-1)&0x07]+300)){group_SpO2[offset_SpO2]=group_SpO2[(offset_SpO2-1)&0x07]+300;}elseif(group_SpO2[offset_SpO2]<(group_SpO2[(offset_SpO2-1)&0x07]-300)){group_SpO2[offset_SpO2]=group_SpO2[(offset_SpO2-1)&0x07]-300;}else{}if(group_SpO2[offset_SpO2]>10000){group_SpO2[offset_SpO2]=10000;}elseif(group_SpO2[offset_SpO2]<8500){group_SpO2[offset_SpO2]=8500;}else{}sum_SpO2+=group_SpO2[offset_SpO2];//8秒内血氧饱和度之和加上当前的值offset_SpO2=(offset_SpO2+1)&0x07;SpO2=sum_SpO2/8;//计算平均值,得到最终结果//清空计数和变量重置sum_vs_heart_signal_ac=0;//平方和累加值置零sum_ir_heart_signal_ac=0;//平方和累加值置零//脉率的计算sample_heart_rate=600000/sample_count;//由脉搏周期换算成脉率num_beat=1;//脉搏计数重置成1sample_count=0;//采样计数置0if(sample_heart_rate<1000||sample_heart_rate>18000)//明显错误的结果{}else{//8秒内脉率之和减去8秒前的值sum_heart_rate-=group_heart_rate[offset_heart_rate]; //循环队列更新,得到当前脉率group_heart_rate[offset_heart_rate]=sample_heart_rate;//8秒内脉率之和加上当前值sum_heart_rate+=group_heart_rate[offset_heart_rate];offset_heart_rate=(offset_heart_rate+1)&0x07; //求平均值,为脉率最终结果heart_rate=sum_heart_rate/8;}fresh=1;}}//红外流程else{//前面部分与红光部分一致,关灯,设置参数,开灯,读取运放输出,关灯,平均滤波,去//直流,不再做注释,注释的主要是脉搏周期的判断部分led_tab=0;P2OUT|=BIT2;//关灯P2OUT|=BIT3;//关灯DAC12_0CTL&=~DAC12ENC;DAC12_0CTL|=DAC12OPS;DAC12_0CTL|=DAC12ENC;DAC12_0DAT=ir_LED_level;//红外LED驱动幅度DAC12_1DAT=ir_dc_offset;//OA1输入参考电压P2OUT&=~BIT2;//开灯ADC12CTL0&=~ENC;ADC12CTL0|=ENC;for(m=1;m<=1500;m++){}ir_sample=ADC12MEM0;//OA0输出,用以控制LED驱动幅度i=ADC12MEM1;//OA1输出,初始未处理的信号j=ADC12MEM2;k=ADC12MEM3;//OA0输出,控制LED驱动幅度if(ir_sample>=FIRST_STAGE_TARGET_HIGH||ir_sample<=FIRST_STAGE_TARGET_LOW){if(ir_sample>=FIRST_STAGE_TARGET_HIGH){if(ir_sample>=FIRST_STAGE_TARGET_HIGH_FINE)ir_LED_level+=FIRST_STAGE_STEP;elseir_LED_level+=FIRST_STAGE_FINE_STEP;if(ir_LED_level>=2500)ir_LED_level=2500;}else{if(ir_sample<=FIRST_STAGE_TARGET_LOW_FINE)ir_LED_level-=FIRST_STAGE_STEP;elseir_LED_level-=FIRST_STAGE_FINE_STEP;if(ir_LED_level<=1)ir_LED_level=1;}}//OA1输出,控制OA1输入的参考电压if(i>=4095){if(ir_dc_offset>0)ir_dc_offset--;}elseif(i<100){if(ir_dc_offset<4095)ir_dc_offset++;}DAC12_0CTL&=~DAC12ENC;_NOP();_NOP();P2OUT|=BIT2;//关灯P2OUT|=BIT3;//关灯T_body_signal=j;T_enviroment_signal=k;ir_heart_signal=ir_filter_test(i);//初始信号滤波处理ir_dc_offset_second+=((ir_heart_signal-ir_dc_offset_second)>>7);ir_heart_signal_ac=ir_heart_signal-ir_dc_offset_second;//是否为程序启动状态,此时flag_initial==1if(flag_initial==1){if(offset_wave>=500){flag_initial=0;}}else{//脉搏周期的判断if(flag_jump==0)//flag_jump==0,表示处在寻找波谷状态{sample_jump=0;//离开波谷时的采样计数置0//寻找group_caculate[64]循环队列中的最小值及其位置min=group_caculate[0];location_min=0;for(inti=1;i<64;i++){if(min<group_caculate[i]){min=group_caculate[i];location_min=i;}} //计算最小值位置距离队列头距离if(location_min<=offset_caculate){location_min_adjust=offset_caculate-location_min;}else{location_min_adjust=offset_caculate+64-location_min;} //最小值是否在队列正中if(location_min_adjust==31||location_min_adjust==32){flag_jump=1;//如果是,找到波谷,进入离开波谷状态//脉搏计数增加,如果是程序第一次找到,则由0到1,以后则总是由1到2num_beat++;P1OUT^=BIT0;}}else//flag_jump==1,表示处在离开波谷状态{sample_jum

温馨提示

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

评论

0/150

提交评论