1、以红外光这一路为例:每次开启红外光LED,根据OA0输出改变LED得幅度ir_LED_level(Q3 得基极),根据OA1输出改变去直流电路得直流参考电压ir_dc_offset (OA1得正向输入端),得到得OA1得输出作为计算电路得输入,关灯,原始信号去工频处理后得到ir_heart_signal,数字去直流后得到ir_heart_signal_ac,该信号进入脉搏波周期判断得队列group_caculate64,同时计算ir_heart_signal_ac信号得平方与,并且采样计数,同时进行脉搏周期得判断。数字信号直流跟随可表达为:跟随系数(输入信号-直流分量)+直流分量=更新得直流分
2、量。脉搏周期得判断过程:队列相当于在脉搏波信号上一个滑动得窗口,窗口应有一定宽度,大于噪声时间,但需小于脉搏周期。判断过程如下:当最小值位置处于窗口中部位置时则判定为一个波谷,检测到波谷以后窗口继续滑过10个采样点,但不再检查最小值,确保上一个波谷已经离开窗口中心,然后继续检查最小值位置确定下一个波谷。可以分为三种状态分别称之为确定波谷、离开波谷、寻找波谷。如下图。利用局部特征实时判断脉搏周期得三个阶段:1)确定波谷,确定周期,计算血氧饱与度与脉率,清空计数;2)离开波谷,开始计数,计算信号平方与;3)寻找波谷,保持计数,计算平方与,确定窗口中最小值位置五、测量程序实现(可参考pulsoxim
3、eter、c文件)1、变量设置1)全局参量 根据运放一得输出经AD转化后判断LED就是否过亮过暗,2500到3000之间为合适亮度,否则进行调节,快速调节步长为2,细调步长为1,可根据实际电路修改。/反馈控制LED驱动幅度时得上下界与调节步长#define FIRST_STAGE_TARGET_HIGH 3000#define FIRST_STAGE_TARGET_LOW 2500#define FIRST_STAGE_TARGET_HIGH_FINE 3500#define FIRST_STAGE_TARGET_LOW_FINE 2000#define FIRST_STAGE_STEP 2#
4、define FIRST_STAGE_FINE_STEP 12)全局变量/脉搏血氧信号,存储脉搏血氧几个处理方法后得值int32_t ir_heart_signal;/红外光,OA1输出经过平均滤波后,等待数字去直流int32_t vs_heart_signal;/ 红光,OA1输出经过平均滤波后,等待数字去直流int32_t ir_heart_signal_ac;/红外光,经过数字去直流,进入计算窗口,参加平方与得累加int32_t vs_heart_signal_ac;/ 红光,经过数字去直流,进入计算窗口,参加平方与得累加int32_t sum_ir_heart_signal_ac =
5、0;/红外光,信号平方与累加值,一个周期计算平均功率int32_t sum_vs_heart_signal_ac = 0; /红光,信号平方与累加值,一个周期计算平均功率/计算过程信号int group_wave512;/用于显示,循环队列,存储几个周期内得ir_heart_signal_ac信号int offset_wave = 0;/循环队列队列头int flag_initial = 1;/初始化标志位int sample_count = 0;/采样计数,每个周期清空,重新计数int num_beat = 0;/初始值为1,下一个脉搏后为2,计算平均功率与血氧饱与度,重新置1int fla
6、g_jump = 0;/脉搏波周期判断,就是否处于离开波谷得状态int sample_jump = 0;/离开波谷时得采样计数,到20则已离开波谷,置0 ,flag_jump 置1/循环队列,以滑动窗口得形式判断当前就是否为脉搏波波谷int group_caculate64;/用于脉搏周期判断得循环队列,存储64 个ir_heart_signal_ac信号int offset_caculate = 0;/队列头位置int min;/队列中最小值int location_min;/最小值位置int location_min_adjust;/最小值相对与队列头得位置,如果就是32则确认一个波谷/最
7、终结果/脉率unsigned int heart_rate = 6000;/脉率最终测量结果,初始值为60、00unsigned int group_heart_rate8;/最近8秒内得脉率,循环队列,初始化为6000int offset_heart_rate=0;/队列头unsigned int sample_heart_rate;/脉率当前原始结果,经过一定调整后进入group_heart_rate8int32_t sum_heart_rate;/最近8秒得脉率累加值,除以8得到新得heart_rate/脉搏血氧饱与度unsigned int SpO2 = 9500;/血氧饱与度最终测量
8、结果,初始值为95、00unsigned int group_SpO28; /最近8秒内得血氧饱与度,循环队列,初始化为9500int offset_SpO2=0;int32_t sum_SpO2; /最近8秒得血氧饱与度累加值,除以8得到新得heart_rate/控制参数int fresh=0; /调试使用,无意义/反馈控幅与OA1参考电压得参数int led_tab=0; /控制开启红光还就是红外光,每次中断切换状态int ir_LED_level;/ir驱动幅度,控制Q3基极,范围1到2500,数字越大,亮度越弱int vs_LED_level;/vs驱动幅度,控制Q4基极,范围1到40
9、95,数字越大,亮度越弱int ir_dc_offset = 4095;/ir灯直流参考电压,开启红外LED时,控制OA1正向输入端int vs_dc_offset = 4095;/ /vs灯直流参考电压,开启红光LED时,控制OA1正向输入端int ir_dc_offset_second = 0;/数字去直流时得直流跟随量int vs_dc_offset_second = 0; /数字去直流时得直流跟随量/运放输出得输出int ir_sample;/ir灯,OA0得输出,根据该输出改变ir_LED_levelint vs_sample;/vs灯,OA0得输出,根据该输出改变vs_LED_le
10、vel3)子函数unsigned long isqrt32(register unsigned long h);/开方运算int16_t ir_filter_test(int16_t sample);/平均滤波器_红外int16_t vs_filter_test(int16_t sample);/平均滤波器_红光2、程序主体(请参照pulsoximeter、c文件)1)晶振、电源设置2)初始化操作:group_heart_rate8初始化为6000,sum_heart_rate 初始化为48000,group_SpO28初始化为9500,sum_SpO2初始化为76000。3)DAC设置,ir
11、_LED_level初始化为2500,vs_LED_level初始化为900。ADC设置。定时器设置,200Hz采样中断,1600Hz用于PWM输出。4)设置完,进入低功耗模式5)中断处理程序,200Hz中断,中断进入后或者进入红光LED流程,或者进入红外LED流程,都要根据输入调整相应参数,进行平均滤波,去直流处理。两种流程其她计算上有所不同:在红光流程中主要进行两路信号平方与累加、采样计数、脉搏血氧饱与度与脉率得计算;红外流程里主要进行得就是脉搏周期得判断。两个流程得具体操作如下。红光流程:关闭两路灯,设置参数,开启红光LED,读取输入,关闭红光LED,根据输入调整参数,平均滤波,去直流,
12、循环队列更新,就是否处于找到波谷得状态(num_beat由1变为2,找到,否则未找到),未找到则计算两路平方与,采样计数累加,找到则计算脉搏血氧饱与度与脉率,平方与、采样计数置0。红外流程:关闭两路灯,设置参数,开启红光LED,读取输入,关闭红光LED,根据输入调整参数,平均滤波,去直流,循环队列更新,就是否处于离开波谷得状态(flag_jump=0时为寻找状态,flag_jump=0时为离开状态),寻找状态找到循环队列中最小值及位置,判断就是否波谷,不就是波谷继续寻找,就是波谷则进入离开状态,离开状态仅计数,计数满20次进入寻找状态。中断程序代码如下所示:/红光流程if(led_tab=0)
13、/ led_tab=0,打开红光LED led_tab=1;/切换led_tab,下一次进入红外流程 P2OUT |= BIT2;/关灯 P2OUT |= BIT3; DAC12_0CTL &= DAC12ENC;/开启DAC,根据vs_LED_level给出幅度= DAC12OPS; DAC12_0CTL |= DAC12ENC; DAC12_0DAT = vs_LED_level;/红光LED驱动幅度 DAC12_1DAT = vs_dc_offset;/红光去直流电路得参考电压,OA1正向输入 P2OUT &= BIT3;/开灯,红光LED ADC12CTL0 &= ENC;/开启DAC,读取OA0、OA1输出 ADC12CTL0 |= ENC; for(m=1;m=FIRST_STAGE_TARGET_HIGH|vs_sample= FIRST_ST
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1