资源简介
基于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 频域二次积分_振动位移\
- 上一篇:最小错误率的贝叶斯分类算法之性别的分类模式识别论文
- 下一篇:遗传算法.cpp
评论
共有 条评论