资源简介

基于STM32F407对加速度进行频域二次积分,需要用到F4的DSP库。本文件参考了王济《matlab在振动信号处理中的应用》一书中频域二次积分的matlab代码。该文件测量的位移为振动位移(总位移为0),单次非零位移的测量不适用。

资源截图

代码片段和文件信息

/**
 ******************************************************************** 
 *  @filename 频域一次/二次积分
 *  @author   L-KAYA
 *  @date     27-July-2018
 *  @brief    该文件主要用于实现加速度在频域的一次或二次积分
 *            得到速度或位移,有带通滤波功能,积分后漂移较小
 *   建议采样频率1kHz以上,效果较为理想
 ********************************************************************
 */

#include “double_integral.h“
#include “arm_const_structs.h“

//结构体指针
dou_integ_t* integ = NULL;

/** 
 *  @name 频域一次/二次积分初始化函数
 *  @brief  初始化用于存储函数的结构体,下方可更改部分根据实际情况更改
 *  @pram len 用于二次积分的数组长度,建议大于16小于4096,2的幂次
 *  @retval 0 成功
 *   else失败
 */
int integ_init(uint16_t len)
{
integ = (dou_integ_t*)MALLOC(sizeof(dou_integ_t));
if(integ == NULL)
return -1;//内存申请失败

// 设置频域二次积分的参数(可更改)
integ->smple_frq  = SMPLE_FRQ; //采样频率
integ->gravity    = GRAVITY; //单位变化系数(最后积分结果乘上该系数,根据重力加速度得到)
integ->integ_time = INTEG_TIME; //积分次数
integ->frq_min    = FRQ_MIN; //高通滤波截止频率
integ->frq_max    = FRQ_MAX; //低通滤波截止频率(应小于采样频率)
if(integ->frq_max>=integ->smple_frq)
return -2;

// 根据输入数组长度,计算FFT数组长度
uint8_t i;
for(i=4; i<13; i++){ //数组长度范围为2^4=16 ~ 2^12=4096
if(POW(2i)>=len){
integ->fft_len = POW(2i); //大于并接近n的2的幂次方的FFT长度
break;
}
}
if(i == 13)
return -3;//数据长度太大,范围为16~4096

//为fft_buf临时数组分配内存
integ->fft_buf = (float*)MALLOC(integ->fft_len*2*(sizeof(float)));
if(integ->fft_buf == NULL)
return -4;//内存申请失败

switch(integ->fft_len)
{
case 16:{
integ->S = arm_cfft_sR_f32_len16;
break;
}
case 32:{
integ->S = arm_cfft_sR_f32_len32;
break;
}
case 64:{
integ->S = arm_cfft_sR_f32_len64;
break;
}
case 128:{
integ->S = arm_cfft_sR_f32_len128;
break;
}
case 256:{
integ->S = arm_cfft_sR_f32_len256;
break;
}
case 512:{
integ->S = arm_cfft_sR_f32_len512;
break;
}
case 1024:{
integ->S = arm_cfft_sR_f32_len1024;
break;
}
case 2048:{
integ->S = arm_cfft_sR_f32_len2048;
break;
}
case 4096:{
integ->S = arm_cfft_sR_f32_len4096;
break;
}
default:{
integ->S = arm_cfft_sR_f32_len1024;
}
}

float df = (float)integ->smple_frq / (float)integ->fft_len; //计算频率间隔(Hz/s)
integ->high_pass = round(integ->frq_min/df); //高通频率截止点
integ->low_pass  = round(integ->frq_max/df);   //低通频率截止点

float dw = 2*PI*df; //圆频率间隔(rad/s)
integ->w_vec = (float*)MALLOC((integ->fft_len-1)*(sizeof(float)));
for(int i=0; i<(integ->fft_len/2); i++){
integ->w_vec[i] = dw*i; //正离散圆频率向量
integ->w_vec[i] = POW(integ->w_vec[i]integ->integ_time); //以积分次数为指数,建立圆频率变量向量
}
for(int i=integ->fft_len/2; i<(integ->fft_len-1); i++){
integ->w_vec[i] = -dw*(integ->fft_len/2-1) + dw*(i - integ->fft_len/2); //负离散圆频率向量
integ->w_vec[i] = POW(integ->w_vec[i]integ->integ_time); //以积分次数为指数,建立圆频率变量向量
}

return 0;
}

/** 
 *  @name 频域一次/二次积分去初始化函数
 *  @brief 不需要用到频域积分后可去初始化,释放内

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件        6116  2018-08-02 10:02  频域二次积分_振动位移\double_integral.c
     文件        3409  2018-08-02 10:06  频域二次积分_振动位移\double_integral.h
     目录           0  2018-08-02 09:59  频域二次积分_振动位移\

评论

共有 条评论