Matlab中fdatool结合STM32F4设计滤波器

数字滤波器的原理

1.从功能上分;低通、带通、高通、带阻。滤波器口诀:低通滤高频;高通滤低频;带通滤两边;带阻阻中间;

2.从实现方法上分:FIR、IIR

3.从设计方法上来分:Chebyshev(切比雪夫),Butterworth(巴特沃斯)

4.从处理信号分:经典滤波器、现代滤波器

经典滤波器从功能上分又可分为:

低通滤波器(LPAF/LPDF):Low pass analog filter

带通滤波器(BPAF/BPDF):Bandpass analog filter

高通滤波器(HPAF/HPDF):High pass analog filter

带阻滤波器(BSAF/BSDF):Bandstop analog filter

IIR滤波器和FIR滤波器

数字信号处理里面的滤波器分两种:一种是IIR滤波器,另一种是FIR滤波器,本质区别就是IIR滤波器的当前输出与以前的输出和输入有关,FIR滤波器只与输入有关,看一下差分方程就一目了然了。

更多对比参考:

细说IIR滤波器和FIR滤波器的区别_iir和fir的区别_Gordennizaicunzai的博客-CSDN博客

Matlab用指令实现滤波器

以下以IIR巴特沃斯带通滤波器设计为例。

fs=1000; %设置采样频率 1k

N=1024; %采样点数

n=0:N-1;

t=0:1/fs:1-1/fs; %时间序列

f=n*fs/N; %频率序列

x1=sin(2*pi*50*t); %噪声

x2=sin(2*pi*200*t); %信号

x=x1+x2; %信号混合

subplot(311);

plot(t,x); %绘制原始信号

xlabel('时间');

ylabel('幅值');

title('原始信号');

subplot(312);

y=fft(x,N); %绘制原始信号的幅频响应

plot(f,abs(y));

xlabel('频率/Hz');

ylabel('振幅');

title('原始信号 FFT');

subplot(313);

Wn=[125*2 300*2]/fs; %设置通带 125Hz 到 300Hz

[b,a]=butter(1,Wn); %注意第一个参数虽然是 1,但生成的却是 2 阶 IIR 滤波器系数

y2=filtfilt(b,a,x); %计算滤波后的波形 y2

y3=fft(y2,N); %滤波后波形的幅频响应

plot(f,abs(y3));

xlabel('频率/Hz');

ylabel('振幅');

title('滤波后信号 FFT');

Fdatool工具的使用

如果要对数据进行滤波,可以使用matlab提供的工具fdatool来进行滤波器的设计,我们可以设计出一系列的滤波器,并且可以实时看到滤波器的效果图,滤波器设计好之后,我们还可以对目标数据进行滤波,然后根据滤波的效果去调整滤波器的参数。

我们可以在matlab的命令行处输入fdatool命令来调出fdatool工具。

该界面内容较多,我们这里仅对较常使用的地方进行说明。

响应类型和设计方式

这里是滤波器的选择,从上到下依次是:

低通、高通、带通、带阻,接着是其他的一些特殊滤波器,这里面有个Notching陷波滤波器,常常用来滤除特定频率的信号比如工频干扰及其谐波。

再下方的就是IIR和FIR滤波器选择,这个根据需要去选择即可,具体滤波器的应用场景可以查阅相关资料。IIR里常用的就是巴特沃斯滤波器,FIR里常用的就是加窗方式window

后面还有一些参数,我们就分别在滤波器的类型设计中去讲解吧。

这里先说一下几个问题:

第一个就是,FIR的阶数和IIR的阶数选择,基于FIR和IIR滤波器的特点,同样的效果,FIR需要比IIR有更多的阶数。通常,FIR的阶数都是几十几十的,甚至几百的,比如50阶、60阶、100阶、150阶等等,具体根据滤波效果来设定,总之,不能小,一小就效果差;相反,IIR设定的阶数不能大,一般不会超过6阶,常用的就是2阶或者4阶,如果大了,反而会溢出产生漂移等问题,初学者很容易看到IIR低阶效果不好,就加大阶数,这会适得其反。

第二个就是,我们可以通过参数图看下各参数是啥意思,通过幅频图直观地看到滤波器的效果,就是这个:

参数图

幅频图

可以直观地看到滤波器的效果。

接下来,依次介绍几个有代表性的滤波器,其他滤波器都是类似的。

IIR巴特沃斯低通滤波器

都比较好理解。

这里展示了当前滤波器的信息

有个地方需要注意,那就是Minimum order,虽然说是最小的阶数,但选中之后其实阶数很大,不知道是不是bug。

一般,我们手动指定阶数即可。

FIR加窗window低通滤波器

高通滤波器同理,不再赘述。

IIR巴特沃斯带通滤波器

带阻滤波器同理

单频率陷波滤波器

多频率陷波滤波器

这种滤波器被称作梳状滤波器,像一把梳子,可以滤去某个频率及其谐波成分,也就是某频率的所有整数倍频率,最常见的就是滤掉50Hz的工频干扰及其谐波。

这里需要注意的是,这里的阶数不能随便设,是有固定的数值的,=Fs/目标频率,比如,要滤掉50Hz及其谐波部分,采样率2000,那么这里的阶数就要填2000/50=40。

其他滤波器的参数补充

另外,还有一些其他滤波器,可能有一些不一样的参数,比如FIR默认的低通滤波器,截止频率填入时就不只是填入截止频率,而是填入一个范围

这里表示从Fpass开始截止,然后到Fstop时衰减到最低,看上面的幅频图就很明白了。

Wpass/Wstop/Apass/Astop这些意思都是差不多,分别调节衰减开始处和衰减结束出的频率范围精度,比如目标频率是50,如果这些值比较小,可能从49.5才开始衰减,但是值太大了,可能从45就开始衰减,这样的话,本来只想滤掉50Hz的频率,结果把45—55的频率都滤掉了。

再通俗点,就跟带阻滤波器两侧的范围误差差不多。

以上,就是设计滤波器时需要知道的一些参数设置。

这里总结一下,如何调节滤波器的效果?一般可以通过调节以下这些参数达到最适合的效果:

1、调节阶数,fir增大阶数,iir适当增加阶数;

2、陷波滤波器时提高品质;

3、调节Wpass/Wstop/Apass/Astop这些参数;

4、如果以上调节没什么改进的话,那就直接更换滤波器类型,比如,如果用IIR滤波器做带通,怎么调节效果都不好,那就直接换成FIR滤波器,再比如,如果陷波滤波器效果不好的话,就直接换成带阻滤波器。

……

总之,虽然需要一些经验,但也需要多多调试。

注意:设计滤波器时,所使用的阶数 n 应为偶数。

matlab验证滤波器效果

我们使用fdatool设置好滤波器参数之后,点击最下方的按钮Design Filter

此时,滤波器就设计好了。

接着,可以将设计好的滤波器导出成一个matlab对象。

fdatool工具界面上面,点击File——Export

这里的意思就是,将当前滤波器导出到matlab的变量空间Workspace,导出为对象,并且命名为Hd_bp,如果变量名已存在则覆盖,然后确定导出。

此时,在matlab的工作空间就会出现这个滤波器对象

接下来,我们准备好原始数据,然后对原始数据进行滤波

Fs = 2000;
%带通滤波器,Fir滤波
sig1 = filter(Hd_bp, VarName1);
%带阻滤波器,iir滤波
sig2 = filter(Hd_bs_50, sig1);
sig3 = filter(Hd_bs_100, sig2);
sig4 = filter(Hd_bs_150, sig3);%奇次谐波
sig5 = filter(Hd_bs_200, sig4);
sig6 = filter(Hd_bs_250, sig5);%奇次谐波
sig7 = filter(Hd_bs_300, sig6);
sig8 = filter(Hd_bs_350, sig7);%奇次谐波
sig9 = filter(Hd_bs_400, sig8);
sig10 = filter(Hd_bs_450, sig9);%奇次谐波
sig11 = filter(Hd_bs_500, sig10);
%频谱图
Y = fft(sig11);
L = length(Y);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
plot(f,P1);
%axis([0,Fs/2,0,2000]);
title('frequency-domain');
xlabel('f(Hz)');
ylabel('频率成分的幅值');

以上代码中,filter就是滤波函数,这里面放入两个参数,第一个就是刚才设计并导出的滤波器对象,第二个就是原始数据。

我们可以对滤波前后的数据分别绘制幅频图,以此来验证滤波效果。

上面的代码做了20~500的带通和工频干扰的带阻滤波,效果如下:

效果还是可以的。

STM32F4实现滤波器

我们在matlab设计好滤波器之后,如果把这个滤波器用到STM32里呢?因为F4有FPU,所以最好在F4上使用,要不速度会是个大问题。

其实也比较简单

如果是FIR滤波器,在滤波器设计好之后,导出头文件

Targets——Generate C header

生成并保存后,我们可以到目标路径去找到头文件并打开查看

这里面关键的就是个系数,系数的个数是设定的阶数+1,这是算法要求,不用管太多,直接拿到C里面使用即可。

如果是IIR滤波器

默认生成的IIR滤波器是II型

导出之前,我们先将滤波器转换成直接1型

Edit——Convert Struct

选择第一项并确定

然后File——Export导出为系数

系数中的关键信息就是系数和缩放系数

因为是4阶,由两个二阶滤波器组成,所以二阶滤波器系数有两组。

这里,系数分别为b0 b1 b2 a0 a1 a2,其中a0这个系数是固定的,所以不必使用。

同时,要注意的是,在STM32F4中用DSP调用时,需要将每组的a1和a2取反,即正的改成负的,负的改成正的。

这个看公式就知道了。

比如 matlab 就是使用上面的公式实现的,所以在使用 fdatool 工具箱生成的 a 系数需要取反才能用于直接 I 型 IIR 滤波器的函数中。
其实,各类滤波器本质上就是计算公式不同,各有各的系数,各有各的算法。
我们得到系数之后,在F4中初始化,写滤波函数,然后调用即可。
附上代码:
#include "IIR.h"
#include "arm_const_structs.h"
#include "stm32f4xx.h"#define NUM_PER_CALL                1               //调用一次滤波函数所处理的采样点个数//FIR带通滤波器
#define FIR_EFFICIENT_NUM           151             //fir滤波器系数个数arm_fir_instance_f32 S_BP;                          //fir滤波器实例
static float32_t firStateF32[NUM_PER_CALL + FIR_EFFICIENT_NUM - 1]; //FIR状态缓存,大小FIR_EFFICIENT_NUM + NUM_PER_CALL - 1
const float32_t firCoeffs32BP[FIR_EFFICIENT_NUM] =  //fir滤波器系数数组
{0,6.783468507e-07,5.500670341e-06,6.206928447e-06,-3.594570046e-07,1.734129728e-05,5.174893886e-05,3.377356188e-05,-6.174600458e-06,5.468466406e-05,0.0001484536479,7.860602636e-05,-3.384135198e-05,0.0001032602231,0.0002951264905,0.0001253946684,-0.0001162498447,0.0001406262745,0.0004820130707,0.0001433174912,-0.0003082125622,0.0001265054452,0.0006859251298,8.190450171e-05,-0.0006903739995,-5.077828102e-19,0.0008687517256,-0.0001297538547,-0.001369225443,-0.0003186257964,0.000981297344,-0.000578189909, -0.00247148145,-0.0009198086918,0.0009743300034,-0.001354034874,-0.004132688046,-0.001889958396,0.0008173419628, -0.00253453129,-0.006482330617,-0.003291910049,0.0005241415929,-0.004162855446,-0.009630653076,-0.005144232418,0.0001840474579,-0.006228647195, -0.01366603095, -0.00740425894,-1.092867096e-18,-0.008654787205,  -0.0186777208,-0.009959736839,0.0003446365299,-0.01129483711, -0.02483416907, -0.01263269503,  0.00187640998,   -0.013943634,-0.03260042891, -0.01519669406, 0.005871396046, -0.01636073925, -0.04341268912,-0.01740563288,  0.01548426691, -0.01830341667, -0.06258355826, -0.01902942732,0.04320411757, -0.01956332289,  -0.1251707077, -0.01988991722,   0.2981061041,0.4799961746,   0.2981061041, -0.01988991722,  -0.1251707077, -0.01956332289,0.04320411757, -0.01902942732, -0.06258355826, -0.01830341667,  0.01548426691,-0.01740563288, -0.04341268912, -0.01636073925, 0.005871396046, -0.01519669406,-0.03260042891,   -0.013943634,  0.00187640998, -0.01263269503, -0.02483416907,-0.01129483711,0.0003446365299,-0.009959736839,  -0.0186777208,-0.008654787205,-1.092867096e-18, -0.00740425894, -0.01366603095,-0.006228647195,0.0001840474579,-0.005144232418,-0.009630653076,-0.004162855446,0.0005241415929,-0.003291910049,-0.006482330617, -0.00253453129,0.0008173419628,-0.001889958396,-0.004132688046,-0.001354034874,0.0009743300034,-0.0009198086918, -0.00247148145,-0.000578189909,0.000981297344,-0.0003186257964,-0.001369225443,-0.0001297538547,0.0008687517256,-5.077828102e-19,-0.0006903739995,8.190450171e-05,0.0006859251298,0.0001265054452,-0.0003082125622,0.0001433174912,0.0004820130707,0.0001406262745,-0.0001162498447,0.0001253946684,0.0002951264905,0.0001032602231,-3.384135198e-05,7.860602636e-05,0.0001484536479,5.468466406e-05,-6.174600458e-06,3.377356188e-05,5.174893886e-05,1.734129728e-05,-3.594570046e-07,6.206928447e-06,5.500670341e-06,6.783468507e-07,0
};//IIR带阻滤波器-50Hz
#define numStages_50Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_50Hz;
static float32_t IIRStateF32_50Hz[4*numStages_50Hz];
static float32_t ScaleValue_50Hz = 0.99335783101529118 * 0.99335783101529118;//放缩系数const float32_t IIRCoeffs32BP_50Hz[5*numStages_50Hz] =
{1,-1.9754644172762135,1,1.9596811054397389,-0.98620549853243988,1,-1.9754644172762135,1,1.9649189860762641,-0.98731438166310681
};//IIR带阻滤波器-100Hz
#define numStages_100Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_100Hz;
static float32_t IIRStateF32_100Hz[4*numStages_100Hz];
static float32_t ScaleValue_100Hz = 0.99335783101529107 * 0.99335783101529107;//放缩系数const float32_t IIRCoeffs32BP_100Hz[5*numStages_100Hz] =
{1,-1.9021975146812826,1,1.8851730633310202,-0.98648991967768052,1,-1.9021975146812826,1,1.8938697151225545,-0.98702972281202106
};//IIR带阻滤波器-150Hz
#define numStages_150Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_150Hz;
static float32_t IIRStateF32_150Hz[4*numStages_150Hz];
static float32_t ScaleValue_150Hz = 0.99335783101529107 * 0.99335783101529107;//放缩系数const float32_t IIRCoeffs32BP_150Hz[5*numStages_150Hz] =
{1,-1.782092196243289,1,1.7640519295652939,-0.98658772855718069,1,-1.782092196243289,1,1.7763809606964005,-0.98693187011384975
};//IIR带阻滤波器-200Hz
#define numStages_200Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_200Hz;
static float32_t IIRStateF32_200Hz[4*numStages_200Hz];
static float32_t ScaleValue_200Hz = 0.99335783101529118 * 0.99335783101529118;//放缩系数const float32_t IIRCoeffs32BP_200Hz[5*numStages_200Hz] =
{1,-1.6181058535088741,1,1.5994425294189876,-0.98663912868667558,1,-1.6181058535088741,1,1.6152032648694865,-0.98688045473364316
};//IIR带阻滤波器-250Hz
#define numStages_250Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_250Hz;
static float32_t IIRStateF32_250Hz[4*numStages_250Hz];
static float32_t ScaleValue_250Hz = 0.99335783101529118 * 0.99335783101529118;//放缩系数const float32_t IIRCoeffs32BP_250Hz[5*numStages_250Hz] =
{1,-1.4142763744756295,1,1.3954270755132026,-0.98667212489138056,1,-1.4142763744756295,1,1.4142763745489406,-0.98684745156199472
};//IIR带阻滤波器-300Hz
#define numStages_300Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_300Hz;
static float32_t IIRStateF32_300Hz[4*numStages_300Hz];
static float32_t ScaleValue_300Hz = 0.99335783101529096 * 0.99335783101529096;//放缩系数const float32_t IIRCoeffs32BP_300Hz[5*numStages_300Hz] =
{1,-1.17562271738861,1,1.1570389697979899,-0.98669609658241275,1,-1.17562271738861,1,1.1785379122261563,-0.98682347619380328
};//IIR带阻滤波器-350Hz
#define numStages_350Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_350Hz;
static float32_t IIRStateF32_350Hz[4*numStages_350Hz];
static float32_t ScaleValue_350Hz = 0.99335783101529118 * 0.99335783101529118;//放缩系数const float32_t IIRCoeffs32BP_350Hz[5*numStages_350Hz] =
{1,-0.90802132733137575,1,0.91378825004392716,-0.98680445057512212,1,-0.90802132733137575,1,0.8901524097715261,-0.98671512011202733
};//IIR带阻滤波器-400Hz
#define numStages_400Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_400Hz;
static float32_t IIRStateF32_400Hz[4*numStages_400Hz];
static float32_t ScaleValue_400Hz = 0.99335783101529096 * 0.99335783101529096;//放缩系数const float32_t IIRCoeffs32BP_400Hz[5*numStages_400Hz] =
{1,-0.61806143864523178,1,0.62654427006115254,-0.98678826715653045,1,-0.61806143864523178,1,0.60134116156514272,-0.98673130233100281
};//IIR带阻滤波器-450Hz
#define numStages_450Hz          2    //2阶IIR滤波的个数static arm_biquad_casd_df1_inst_f32 S_450Hz;
static float32_t IIRStateF32_450Hz[4*numStages_450Hz];
static float32_t ScaleValue_450Hz = 0.99335783101529096 * 0.99335783101529096;//放缩系数const float32_t IIRCoeffs32BP_450Hz[5*numStages_450Hz] =
{1,-0.31288282611132939,1,0.32387775390876944,-0.98677366833749702,1,-0.31288282611132939,1,0.29771783508361671,-0.98674590052325395
};//滤波后剩余的直流分量
#define DC_AFTER_FILTER     3088//所有滤波器的初始化
void arm_emg_f32_filter_init()
{//带通滤波器初始化arm_fir_init_f32(&S_BP, FIR_EFFICIENT_NUM, (float32_t *)&firCoeffs32BP[0], &firStateF32[0], NUM_PER_CALL);//IIR带阻滤波器-50Hz初始化arm_biquad_cascade_df1_init_f32(&S_50Hz, numStages_50Hz, (float32_t *)&IIRCoeffs32BP_50Hz[0], (float32_t *)&IIRStateF32_50Hz[0]);//IIR带阻滤波器-100Hz初始化arm_biquad_cascade_df1_init_f32(&S_100Hz, numStages_100Hz, (float32_t *)&IIRCoeffs32BP_100Hz[0], (float32_t *)&IIRStateF32_100Hz[0]);//IIR带阻滤波器-150Hz初始化arm_biquad_cascade_df1_init_f32(&S_150Hz, numStages_150Hz, (float32_t *)&IIRCoeffs32BP_150Hz[0], (float32_t *)&IIRStateF32_150Hz[0]);//IIR带阻滤波器-200Hz初始化arm_biquad_cascade_df1_init_f32(&S_200Hz, numStages_200Hz, (float32_t *)&IIRCoeffs32BP_200Hz[0], (float32_t *)&IIRStateF32_200Hz[0]);//IIR带阻滤波器-250Hz初始化arm_biquad_cascade_df1_init_f32(&S_250Hz, numStages_250Hz, (float32_t *)&IIRCoeffs32BP_250Hz[0], (float32_t *)&IIRStateF32_250Hz[0]);//IIR带阻滤波器-300Hz初始化arm_biquad_cascade_df1_init_f32(&S_300Hz, numStages_300Hz, (float32_t *)&IIRCoeffs32BP_300Hz[0], (float32_t *)&IIRStateF32_300Hz[0]);//IIR带阻滤波器-350Hz初始化arm_biquad_cascade_df1_init_f32(&S_350Hz, numStages_350Hz, (float32_t *)&IIRCoeffs32BP_350Hz[0], (float32_t *)&IIRStateF32_350Hz[0]);//IIR带阻滤波器-400Hz初始化arm_biquad_cascade_df1_init_f32(&S_400Hz, numStages_400Hz, (float32_t *)&IIRCoeffs32BP_400Hz[0], (float32_t *)&IIRStateF32_400Hz[0]);//IIR带阻滤波器-450Hz初始化arm_biquad_cascade_df1_init_f32(&S_450Hz, numStages_450Hz, (float32_t *)&IIRCoeffs32BP_450Hz[0], (float32_t *)&IIRStateF32_450Hz[0]);
}//带通滤波和带阻滤波
void arm_emg_f32_filter(float32_t *dataInput, float32_t *dataOutput)
{float32_t dataOutputAfterFirbp = 0;float32_t dataOutputAfterIIRbs_50Hz = 0;float32_t dataOutputAfterIIRbs_100Hz = 0;float32_t dataOutputAfterIIRbs_150Hz = 0;float32_t dataOutputAfterIIRbs_200Hz = 0;float32_t dataOutputAfterIIRbs_250Hz = 0;float32_t dataOutputAfterIIRbs_300Hz = 0;float32_t dataOutputAfterIIRbs_350Hz = 0;float32_t dataOutputAfterIIRbs_400Hz = 0;float32_t dataOutputAfterIIRbs_450Hz = 0;//带通滤波arm_fir_f32(&S_BP, dataInput, &dataOutputAfterFirbp, NUM_PER_CALL);//50Hz带阻arm_biquad_cascade_df1_f32(&S_50Hz, &dataOutputAfterFirbp, &dataOutputAfterIIRbs_50Hz, NUM_PER_CALL);dataOutputAfterIIRbs_50Hz *= ScaleValue_50Hz;//100Hz带阻arm_biquad_cascade_df1_f32(&S_100Hz, &dataOutputAfterIIRbs_50Hz, &dataOutputAfterIIRbs_100Hz, NUM_PER_CALL);dataOutputAfterIIRbs_100Hz *= ScaleValue_100Hz;//150Hz带阻arm_biquad_cascade_df1_f32(&S_150Hz, &dataOutputAfterIIRbs_100Hz, &dataOutputAfterIIRbs_150Hz, NUM_PER_CALL);dataOutputAfterIIRbs_150Hz *= ScaleValue_150Hz;//200Hz带阻arm_biquad_cascade_df1_f32(&S_200Hz, &dataOutputAfterIIRbs_150Hz, &dataOutputAfterIIRbs_200Hz, NUM_PER_CALL);dataOutputAfterIIRbs_200Hz *= ScaleValue_200Hz;//250Hz带阻arm_biquad_cascade_df1_f32(&S_250Hz, &dataOutputAfterIIRbs_200Hz, &dataOutputAfterIIRbs_250Hz, NUM_PER_CALL);dataOutputAfterIIRbs_250Hz *= ScaleValue_250Hz;//300Hz带阻arm_biquad_cascade_df1_f32(&S_300Hz, &dataOutputAfterIIRbs_250Hz, &dataOutputAfterIIRbs_300Hz, NUM_PER_CALL);dataOutputAfterIIRbs_300Hz *= ScaleValue_300Hz;//350Hz带阻arm_biquad_cascade_df1_f32(&S_350Hz, &dataOutputAfterIIRbs_300Hz, &dataOutputAfterIIRbs_350Hz, NUM_PER_CALL);dataOutputAfterIIRbs_350Hz *= ScaleValue_350Hz;//400Hz带阻arm_biquad_cascade_df1_f32(&S_400Hz, &dataOutputAfterIIRbs_350Hz, &dataOutputAfterIIRbs_400Hz, NUM_PER_CALL);dataOutputAfterIIRbs_400Hz *= ScaleValue_400Hz;//450Hz带阻arm_biquad_cascade_df1_f32(&S_450Hz, &dataOutputAfterIIRbs_400Hz, &dataOutputAfterIIRbs_450Hz, NUM_PER_CALL);  dataOutputAfterIIRbs_450Hz *= ScaleValue_450Hz;//返回正数值以计算均方根if(dataOutputAfterIIRbs_450Hz >= DC_AFTER_FILTER){*dataOutput = dataOutputAfterIIRbs_450Hz - DC_AFTER_FILTER;}else{*dataOutput = DC_AFTER_FILTER - dataOutputAfterIIRbs_450Hz;}
}

这里有个需要注意的问题,就是每次调用函数处理的数据个数,可以一个一个地处理,也可以一次处理多个,我这里是一个一个地处理的。其实,各滤波器就是个算法,也就是有个对应的公式,将数据输入进去,再输出即可,具体设计到傅里叶变换的知识,可自行查阅资料。

另外,这个FIR系数里有些是用科学计数法来表示的,不用特别处理,C能识别。在C语言中,我们可以使用科学计数法来表示数字。具体方法是在数字后面加上一个大写或小写的字母E,再加上一个指数。

我的一点想法:时域数据通过fft转成频域,删除特定频率的数据,再ifft转成时域,不就可以删除特定频率的数据了?

这样的话:

低通:就相当于我把高频率的数据删除,只留低频率的数据;

高通:就相当于我把低频率的数据删除,只留高频率的数据;

带通:就相当于我把两侧的数据都删了;

带阻:就相当于我把中间的数据删掉了

补充

直流分量信号的频率是0,高通,带通都会被过滤掉,只有低通可以通过。

更多内容可参考以下系列课程:NO.1 基于matlab中的fdatool进行电生理信号预处理实战演练,以肌电信号为例去除噪声_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/121006.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

准备HarmonyOS开发环境

引言 在开始 HarmonyOS 开发之前,需要准备好开发环境。本章将详细指导你如何安装 HarmonyOS SDK、配置开发环境、创建 HarmonyOS 项目。 目录 安装 HarmonyOS SDK 配置开发环境 创建 HarmonyOS 项目 总结 1. 安装 HarmonyOS SDK HarmonyOS SDK 是开发 Harmo…

Springboot 实践(13)spring boot 整合RabbitMq

前文讲解了RabbitMQ的下载和安装&#xff0c;此文讲解springboot整合RabbitMq实现消息的发送和消费。 1、创建web project项目&#xff0c;名称为“SpringbootAction-RabbitMQ” 2、修改pom.xml文件&#xff0c;添加amqp使用jar包 <!-- RabbitMQ --> <dependency&g…

电压互感器倍频感应耐压试验方法

试验方法 升压设备的容器应足够&#xff0c; 试验前应确认高压升压等设备功能正常&#xff1b; 按上图接好线&#xff0c; 三倍频发生器、 高压器外壳必须可靠接地。 将三倍频电源发生装置的输出线与被试电压互感器的一组二次绕组接线端连接好&#xff08;如 a-n 端&#xff0…

Spring MVC 五 - Spring MVC的配置和DispatcherServlet初始化过程

今天的内容是SpringMVC的初始化过程&#xff0c;其实也就是DispatcherServilet的初始化过程。 Special Bean Types DispatcherServlet委托如下一些特殊的bean来处理请求、并渲染正确的返回。这些特殊的bean是Spring MVC框架管理的bean、按照Spring框架的约定处理相关请求&…

2D项目经验总结

2D项目经验总结 前言地图的绘制Sprite Editor叠层注意点&#xff08;SortingLayer相关知识点&#xff09;Tile Paltette的使用Animated Tiles&#xff08;动起来的图片&#xff08;也称作瓷片或者瓦砖&#xff09;&#xff09; 玩家移动玩家方向的翻转刚体注意点 碰撞器输入系统…

手写Mybatis:第19章-二级缓存

文章目录 一、目标&#xff1a;二级缓存二、设计&#xff1a;二级缓存三、实现&#xff1a;二级缓存3.1 工程结构3.2 二级缓存类图3.3 二级缓存队列3.3.1 FIFI缓存策略3.3.2 事务缓存3.3.3 事务管理3.3.4 修改一级缓存 3.4 缓存执行器3.4.1 执行器接口3.4.2 执行器抽象基类3.4.…

华为OD机试 - 等和子数组最小和 - 深度优先搜索(Java 2022 Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》…

企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

ARM编程模型-指令流水线

流水线技术通过多个功能部件并行工作来缩短程序执行时间&#xff0c;提高处理器核的效率和吞吐率&#xff0c;从而成为微处理器设计中最为重要的技术之一。 1. 3级流水线 到ARM7为止的ARM处理器使用简单的3级流水线&#xff0c;它包括下列流水线级。 &#xff08;1&#xff0…

机器人中的数值优化(五)——信赖域方法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

ubuntu22.04搭建verilator仿真环境

概述 操作系统为 Ubuntu(22.04.2 LTS)&#xff0c;本次安装verilator开源verilog仿真工具&#xff0c;进行RTL功能仿真。下面构建版本为5.008的verilator仿真环境。先看一下我系统的版本&#xff1a; 安装流程 安装依赖 sudo apt-get install git perl python3 make autoc…

肖sir__设计测试用例方法之边界值03_(黑盒测试)

设计测试用例方法之边界值 边界点定义 上点&#xff1a;边界上的点 离点&#xff1a;离上点最近的点&#xff08;即上点左右两边最邻近的点&#xff09; 内点&#xff1a;在域范围内的点 案例&#xff1a;qq号&#xff1a;5-12位 闭区间&#xff1a; 离点&#xff1a;5 位 &…

计算机组成原理学习记录(更新中)

文章目录 仅做个人记录计组的学习中认为容易记错的点或是个人认为的要点&#xff0c;如有错误&#xff0c;请多包涵。 学习资源为b站网课&#xff1a;王道计算机考研 计算机组成原理 大部分图片来自该网课 &#xff08;1&#xff09;冯诺依曼型计算机由五个部分组成&#xff…

ajax day2

1、 2、控制弹框显示和隐藏&#xff1a; 3、右键tr&#xff0c;编辑为html&#xff0c;可直接复制tr部分的代码 4、删除时&#xff0c;点击删除按钮&#xff0c;可以获取图书id&#xff1a; 5、编辑图书 快速赋值表单元素内容&#xff0c;用于回显&#xff1a; 6、hidden …

Spring AOP与静态代理/动态代理

文章目录 一、代理模式静态代理动态代理代理模式与AOP 二、Spring AOPSping AOP用来处理什么场景jdk 动态代理cglib 动态代理面试题&#xff1a;讲讲Spring AOP的原理与执行流程 总结 一、代理模式 代理模式是一种结构型设计模式&#xff0c;它允许对象提供替代品或占位符&…

Android片段

如果你希望应用根据不同的环境有不同的外观和行为&#xff0c;这种情况下就需要片段&#xff0c;片段是可以由不同活动重用的模块化代码组件。 片段&#xff08;Fragment&#xff09;是活动&#xff08;Activity&#xff09;的一种模块化部分&#xff0c;表示活动中的行为或界面…

Gin学习记录2——路由

路由 一. 常规路由二. 动态路由三. 带参数的路由3.1 GET3.2 POST3.3 绑定 四. 简单的路由组五. 文件分组 一. 常规路由 package mainimport ("net/http""github.com/gin-gonic/gin" )func index(ctx *gin.Context) {ctx.String(http.StatusOK, "Hell…

八个针对高级职位的高级 JavaScript 面试题

JavaScript 是一种功能强大的语言&#xff0c;是网络的主要构建块之一。这种强大的语言也有一些怪癖。例如&#xff0c;您是否知道 0 -0 的计算结果为 true&#xff0c;或者 Number("") 的结果为 0&#xff1f; 问题是&#xff0c;有时这些怪癖会让你摸不着头脑&…

Python 操作 Excel

之前看过一篇文章&#xff0c;说一个工作多年的老员工&#xff0c;处理数据时只会用复制粘贴到 Excel &#xff0c;天天加班工作还完不成&#xff0c;后来公司就招了一个会 Python 的新人&#xff0c;结果分分钟就处理完成。所以工作中大家经常会使用 Excel 去处理以及展示数据…

AI工人操作行为流程规范识别算法

AI工人操作行为流程规范识别算法通过yolov7python网络模型框架&#xff0c;AI工人操作行为流程规范识别算法对作业人员的操作行为进行实时分析&#xff0c;根据设定算法规则判断操作行为是否符合作业标准规定的SOP流程。Yolo意思是You Only Look Once&#xff0c;它并没有真正的…