手环项目嵌入式软件需求说明书.docx
- 文档编号:5906799
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:23
- 大小:225.87KB
手环项目嵌入式软件需求说明书.docx
《手环项目嵌入式软件需求说明书.docx》由会员分享,可在线阅读,更多相关《手环项目嵌入式软件需求说明书.docx(23页珍藏版)》请在冰豆网上搜索。
手环项目嵌入式软件需求说明书
项目名称:
手环系统
嵌入式软件实现方案说明书
慧创科技(北京)有限公司
有关该文档:
此文档的内容包括手环系统嵌入式软件实现方案说明书。
文档所有者:
慧创科技(北京)有限公司
文档版本记录:
版本号
负责人
完成时间
备注
1.0
石聪
2014-12-8
1.1
石聪
2014-12-16
1.系统功能框架
2.系统分模块功能实现方案
2.1计步功能实现方案
功能:
1.能对用户运动时所走的路程进行计步。
算法:
(1)算法流程图
(2)算法的具体实现方案
代码中需要用到的变量定义与初始化:
定义一个数组accVals[6]用来存储从传感器上得到的原始16位加速度值,具体定义如下:
externunsignedcharaccVals[6];
定义一个结构体StepCtrl用来存储代码中需要用到的变量,具体定义如下:
typedefstruct
{
unsignedintaccAll_pf;//XYZ方向加速度的平方和
unsignedcharstate0;
unsignedintstate;//state0、state用于计步数的显示
unsignedintmin;//波形分析中的极小值
unsignedintmax;//波形分析中的极大值
unsignedintaccValShort[3];//用来存放滤波后的相邻三个数据
unsignedintaccAll_pf_pj;//相邻三个accAll_pf的平均值
unsignedintaccAll_pf_ys[3];//用来存放未滤波前相邻三个加速度平方的值
unsignedintaccAll_pf_lb[11];//用来存放滤波后的值
unsignedcharuTemp1;//uTemp、uTemp1用于16位数据转换为无符号的8位数据
unsignedcharbCurFall;
unsignedshortnCurMovingPer;//当前的运动百分比
}StepCtrl;
定义一个结构体变量g_StepCtrl用于管理算法中用到的变量
externStepCtrlg_StepCtrl;
变量初始化函数:
将g_StepCtrl.min初始为20000,其余变量初始为0。
具体初始化代码如下:
voidg_Ctrl_Init()
{
bg_memset((unsignedchar*)(&g_StepCtrl),0,sizeof(g_StepCtrl));
g_StepCtrl.min=20000;
}
加速度数据处理函数具体初始化代码如下:
增加一帧加速度数据函数voidUpdate_StepFallByAcc(),具体代码如下
voidUpdate_StepFallByAcc()
{
先通过I2c从mma加速度芯片中获取当前的16位加速度数据代码如下:
I2c_readBytes(MMA_I2C_ADDR,1,6,accVals);
由于加速度传感器传来的16位数据精度太高,我们在实际应用时没必要那么高的精度,并且16位的数据将带来很大的计算量,因此我们将采集来的16位原始数据简化为无符号的8位数据。
采集来的16位原始数据简化为无符号的8位数据的代码如下:
for(uTemp=0;uTemp<3;uTemp++)
{
g_StepCtrl.uTemp1=uTemp*2;
if((accVals[g_StepCtrl.uTemp1+1]>=0X80)&&(accVals[g_StepCtrl.uTemp1]!
=0X7F))
{
accVals[g_StepCtrl.uTemp1]++;
}
g_StepCtrl.accValShort[uTemp]=accVals[g_StepCtrl.uTemp1];
if(g_StepCtrl.accValShort[uTemp]>=0X80)
{
g_StepCtrl.accValShort[uTemp]-=256;
}
}
为了减小计算量,又能准确可靠的计步和判断用户是否跌倒,程序中采用了XYZ三个方向加速度平方和这个特征值,计算X、Y、Z方向加速度的平方和的代码如下:
g_StepCtrl.accAll_pf=g_StepCtrl.accValShort[0]*g_StepCtrl.accValShort[0]+
g_StepCtrl.accValShort[1]*g_StepCtrl.accValShort[1]+
g_StepCtrl.accValShort[2]*g_StepCtrl.accValShort[2];
滤波算法采用的是平均值滤波算法,平均值滤波算法如下:
g_StepCtrl.accAll_pf_pj=0;
for(uTemp=0;uTemp<2;uTemp++)
{
g_StepCtrl.accAll_pf_ys[uTemp]=g_StepCtrl.accAll_pf_ys[uTemp+1];
g_StepCtrl.accAll_pf_pj+=g_StepCtrl.accAll_pf_ys[uTemp];
}
g_StepCtrl.accAll_pf_ys[2]=g_StepCtrl.accAll_pf;
g_StepCtrl.accAll_pf_pj+=g_StepCtrl.accAll_pf;
for(uTemp=0;uTemp<10;uTemp++)
{
g_StepCtrl.accAll_pf_lb[uTemp]=g_StepCtrl.accAll_pf_lb[uTemp+1];
}
g_StepCtrl.accAll_pf_lb[10]=g_StepCtrl.accAll_pf_pj/3;
经分析,当特征值出现一个波峰且这个波峰与其前面最近的一个波谷数据的差值大于500的时候,即可以认为用户走了一步,计步判断代码:
g_StepCtrl.state0=0;
极小值存储在g_StepCtrl.min,得到极小值代码如下:
if(g_StepCtrl.accAll_pf_lb[5] { g_StepCtrl.min=g_StepCtrl.accAll_pf_lb[5]; } 极大值存储在g_StepCtrl.accAll_pf_lb[5],得到极大值代码如下: if((g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[4])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[3])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[2])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[1])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[0])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[6])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[7])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[8])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[9])&& (g_StepCtrl.accAll_pf_lb[5]>=g_StepCtrl.accAll_pf_lb[10])) { g_StepCtrl.max=g_StepCtrl.accAll_pf_lb[5] 波峰与其前面最近的一个波谷数据的差值大于500的情况的检测代码如下: if((g_StepCtrl.max-g_StepCtrl.min)>=500) { g_StepCtrl.state0++; g_StepCtrl.state++; g_StepCtrl.min=g_StepCtrl.accAll_pf_lb[5]; 发送计步数增加信息代码如下: #ifdefUART_OUT_DEBUG_DATA Uart_SendByte(0XBB); Uart_SendBytes((unsignedchar*)&g_StepCtrl.state,2); #endif } } 2.2跌倒功能实现方案 功能: 1.能对用户运动时所发生的跌倒事件进行实时监测。 算法: (1)算法流程图 (2)算法的具体实现方案 代码中需要用到的变量定义与初始化: 定义一个数组accVals[6]用来存储从传感器上得到的原始16位加速度值,具体定义如下: externunsignedcharaccVals[6]; 定义三个无符号的字符型静态变量,用于存储相应的状态信息.具体定义如下 staticunsignedcharnCurInFallingTimes=0;//失重状态的持续时间值存放该改变量中 staticunsignedcharnCurNormalTimes=0;//未发生跌倒的正常状态的持续时间值存放在该变量staticunsignedcharnCurHittingTimes=0;//撞击状态的持续时间值存放在该变量中 定义一个结构体StepCtrl用来存储代码中需要用到的变量,具体定义如下: typedefstruct { unsignedintaccAll_pf;//XYZ方向加速度的平方和 unsignedcharstate0; unsignedintstate;//state0、state用于计步数的显示 unsignedintmin;//波形分析中的极小值 unsignedintmax;//波形分析中的极大值 unsignedintaccValShort[3];//用来存放滤波后的相邻三个数据 unsignedintaccAll_pf_pj;//相邻三个accAll_pf的平均值 unsignedintaccAll_pf_ys[3];//用来存放未滤波前相邻三个加速度平方的值 unsignedintaccAll_pf_lb[11];//用来存放滤波后的值 unsignedcharuTemp1;//uTemp、uTemp1用于16位数据转换为无符号的8位数据 unsignedcharbCurFall;//该变量用于存放跌倒的次数 unsignedshortnCurMovingPer;//当前的运动百分比 }StepCtrl; 定义一个结构体变量g_StepCtrl用于管理算法中用到的变量 externStepCtrlg_StepCtrl; 变量初始化函数: 将g_StepCtrl.min初始为20000,其余变量初始为0.具体初始化代码如下: voidg_Ctrl_Init() { bg_memset((unsignedchar*)(&g_StepCtrl),0,sizeof(g_StepCtrl)); g_StepCtrl.min=20000; } 加速度数据处理函数具体初始化代码如下: 增加一帧加速度数据函数voidUpdate_StepFallByAcc(),具体代码如下 voidUpdate_StepFallByAcc() { 先通过I2c从mma加速度芯片中获取当前的16位加速度数据代码如下: I2c_readBytes(MMA_I2C_ADDR,1,6,accVals); 由于加速度传感器传来的16位数据精度太高,我们在实际应用时没必要那么高的精度,并且16位的数据将带来很大的计算量,因此我们将采集来的16位原始数据简化为无符号的8位数据。 采集来的16位原始数据简化为无符号的8位数据的代码如下: for(uTemp=0;uTemp<3;uTemp++) { g_StepCtrl.uTemp1=uTemp*2; if((accVals[g_StepCtrl.uTemp1+1]>=0X80)&&(accVals[g_StepCtrl.uTemp1]! =0X7F)) { accVals[g_StepCtrl.uTemp1]++; } g_StepCtrl.accValShort[uTemp]=accVals[g_StepCtrl.uTemp1]; if(g_StepCtrl.accValShort[uTemp]>=0X80) { g_StepCtrl.accValShort[uTemp]-=256; } } 为了减小计算量,又能准确可靠的计步和判断用户是否跌倒,程序中采用了XYZ三个方向加速度平方和这个特征值,计算X、Y、Z方向加速度的平方和的代码如下: g_StepCtrl.accAll_pf=g_StepCtrl.accValShort[0]*g_StepCtrl.accValShort[0]+ g_StepCtrl.accValShort[1]*g_StepCtrl.accValShort[1]+ g_StepCtrl.accValShort[2]*g_StepCtrl.accValShort[2]; 滤波算法采用的是平均值滤波算法,平均值滤波算法如下: g_StepCtrl.accAll_pf_pj=0; for(uTemp=0;uTemp<2;uTemp++) { g_StepCtrl.accAll_pf_ys[uTemp]=g_StepCtrl.accAll_pf_ys[uTemp+1]; g_StepCtrl.accAll_pf_pj+=g_StepCtrl.accAll_pf_ys[uTemp]; } g_StepCtrl.accAll_pf_ys[2]=g_StepCtrl.accAll_pf; g_StepCtrl.accAll_pf_pj+=g_StepCtrl.accAll_pf; for(uTemp=0;uTemp<10;uTemp++) { g_StepCtrl.accAll_pf_lb[uTemp]=g_StepCtrl.accAll_pf_lb[uTemp+1]; } g_StepCtrl.accAll_pf_lb[10]=g_StepCtrl.accAll_pf_pj/3; 跌倒检测函数IsCurFallByAccs()(首先出现失重状态,然后在短时间内又出现撞击状态,此时判断用户发生了跌倒事件。 )具体代码如下: voidIsCurFallByAccs() { 当加速度平方和值小于200时认为用户处于失重状态,当判断出用户处于失重状态时,将nCurInFallingTimes(用户处于跌倒状态的时间)加1,将nCurNormalTimes(用户处于未跌倒状态的时间)清0.相应的代码如下: if(g_StepCtrl.accAll_pf<200) { nCurInFallingTimes++; nCurNormalTimes=0; } 当加速度平方和值大于200且小于2000时认为用户处于未跌倒的正常状态,当判用户处于未跌倒的正常状态时,接着判断用户处于未跌倒状态的时间,如果nCurNormalTimes(用户处于未跌倒的正常状态的时间)小于10,将nCurNormalTimes(用户处于未跌倒的正常状态的时间)加1,然后再判断nCurNormalTimes(用户处于未跌倒的正常状态的时间)是不是10,如果是10则将nCurInFallingTimes=0(用户处于失重状态的时间)清0,nCurHittingTimes=0(用户处于撞击状态的时间)清0.相应的代码如下: elseif(g_StepCtrl.accAll_pf<2000) { if(nCurNormalTimes<10) { nCurNormalTimes++; if(nCurNormalTimes==10) { nCurInFallingTimes=0; nCurHittingTimes=0; } } } 处于撞击状态时加速度值特别大,我们这里把特征值大于2000时,认为用户处于撞击状态,当判断出系统处于撞击状态时,将nCurHittingTimes(用户处于撞击状态的时间)加1,当判断出用户处于撞击状态时,判断用户是不是在短时间内同时出现失重事件、撞击事件,如果用户在短时间内出现失重、撞击事件,此时即判断用户发生了跌倒事件,此时将nCurInFallingTimes(用户处于失重状态的时间值)清0.将nCurHittingTimes(用户处于撞击状态的时间值)清0.将g_StepCtrl.bCurFall(用户跌倒的次数)加1,并向主机发送消息,告诉主机用户已跌倒。 相应的代码如下; else { nCurHittingTimes++; if((nCurHittingTimes>=2)&&(nCurInFallingTimes>=2)&&(nCurNormalTimes<=3)) { nCurInFallingTimes=0; nCurHittingTimes=0; g_StepCtrl.bCurFall++; sys_AddFunOper(Deal_FallCatch); } } } 当判断出用户发生跌倒事件后,告诉主机已经跌倒了相应的代码如下: voidDeal_FallCatch() { Uart_SendByte(0XCC); Uart_SendByte(g_StepCtrl.bCurFall); } 2.3心率功能实现方案 功能: 1.能对用户的心率值进行监测。 算法: (1)算法流程图 (2)算法的具体实现方案 初始化 IO口配置初始化(绿灯、J1控制管脚分配和ADC数据采集管脚)相应的代码如下: voidInit_HeartMeas_IOs(void) { //PB0绿灯控制PB2->J1控制 GPIO_Init(GPIOB,GPIO_Pin_0|GPIO_Pin_2,GPIO_Mode_Out_PP_Low_Fast); } ADC相关初始化代码如下: voidHeart_ADC_Config(void) { CLK_PeripheralClockConfig(CLK_Peripheral_ADC1,ENABLE);//开启时钟 ADC_Init(ADC1,ADC_ConversionMode_Single,ADC_Resolution_12Bit,ADC_Prescaler_2);ADC_SamplingTimeConfig(ADC1,ADC_Group_SlowChannels,ADC_SamplingTime_384Cycles); ADC_Cmd(ADC1,ENABLE); ADC_ChannelCmd(ADC1,ADC_Channel_2,ENABLE); } 定义算法中用到的一些变量并初始化,相应的代码如下: typedefstruct{ unsignedchargl_state;//测量灯当前的状态 unsignedcharn_StableTime;//判断稳定需要判断持续一段时间,因此不能直接进行 unsignedshortnGL_HoldTime;//测试灯亮的时间数量 unsignedcharbufRateAnaly[HEART_BUF_ANALY_LEN];//心率分析的数据缓冲区 unsignedcharanaly_min_pos;//分析过程中一个波形的最小值,需要最小值与最大值进行对比 unsignedcharn_RateAnalyData;//分析的数据个数 unsignedchars_RateAnaly;//数据分析的状态。 unsignedcharbufHeartPero[HEART_BUF_PERO_MAX_LEN];//需要检测多个峰值 unsignedcharnHeartPeroCnt; unsignedcharnMaxPosTimes;//极大值点到当前位置的时间长度 unsignedcharv_heartrate;//测试出来的心率值未测试值0X00无心率0XFF其他为正常心率数据 }HeartMeasCtrl; externHeartMeasCtrlgHeartCtrl; 滤波开关J1打开,测试绿灯关闭,然后等待输出稳定,稳定后打开测试灯开关或者超时结束测试过程,并直接关闭并认为测试值为0XFF 相应的代码如下: voidheart_update_wait_nog_stable() { HeartMeas_J1_PASS();//确保j1打开,判断是否稳定。 gHeartCtrl.nGL_HoldTime++; Heart_ADC_St
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 项目 嵌入式 软件 需求 说明书
![提示](https://static.bdocx.com/images/bang_tan.gif)