STM32 DSP 库 FIR 滤波 函数fir_16by16_stm32计算好像不准啊
目前工程中要用到FIR 滤波,先验证一下该函数的正确性。我自己生成一个正弦波,调用STM32 DSP函数库中的FIR 滤波函数fir_16by16_stm32,进行8阶滤波 发现该函数的输出数组与输入数组 值相差很大,有100多倍,与matlab仿真结果也相差很大。不知什么原因,有没有人用过或验证过这个滤波函数啊?现粘贴部分代码,麻烦大家帮我看看啊!
#define M 9 /*number of coefficients*/
#define N NPT+1-M /*number of output samples*/
int out;/*filter output vector*/
short fY;/*filter input vector*/
float freq;
float fFs=100;//生成的正弦波100个点 一个周期
u16 hx={16,47,124,205,240,205,124,47,16};/*filter coefficients vector*/;
//FIR滤波系数由matlab 生成,由于系数要求是unsigned shor型的,所以系数都乘以了1024
for (freq=0,i=0; freq <1024; freq++,i++)
{
fY=2048+(short)1024*sin(PI2*((float)freq/(float)fFs));//生成正弦波
}
fir_coefs.nh = M; /* Number of Coefficients for FIR*/
fir_coefs.h = hx; /*Pointer on FIR coefficient vector*/
fir_16by16_stm32(out,fY,&fir_coefs,NPT+1-M);/*performs the FIR filtering*/
//由于系数乘以了1024,所以我们将结果 除以1024,这点已在matlab上验证过了
for(i=0;i<NPT+1-M;i++)
{
out=out/1024;
}
通过设断点 ,查看watch对比fY和out 数组中的内容发现值相差很大,有100多倍。而用matlab 则不会现张贴 matlab m文件的内容
clear
%编写
fs=5000
N=1024
n=0:N-1;
t=n/fs;
t=0:1:1024;
x=2048+1024*sin(2*pi*t/100);
figure;
plot(x);
%得出滤波器的阶数n=8,beta=3.4
fc1=200
w1=2*fc1/fs; %将模拟滤波器的技术指标转换为数字滤波器的技术指标
%b=fir1(8,w1); %使用标准频率响应的加窗设计函数fir1
%b=b*1024 %滤波系数的生产,现已注释掉了
b=;
x = filter(b,1,x);%对信号s进行滤波
x=x/1024
figure;
plot(x);
title('f1(100Hz)\f2(300Hz)的正弦信号,初相0')
xlabel('序列(n)')
grid on 问题解决啦!自己 顶一下,上午错在哪了啊------8阶滤波,设M为滤波系数个数,则滤波阶数为M-1.但是 STM32 的fir_16by16_stm32函数要求
滤波系数个数 必须为4的整数倍,详见fir_stm32.s文件(这一点在DSP库PDF文档中没有说明)
#define N R3/* Assigned to number of outputs (a multiple of 4) */
#define M R4/* Assigned number of coefficients (a multiple of 4)*/
我要做8阶滤波,系数个数为9 当然会出错啦!!!改用7阶滤波,#define M 8
就OK啦,同时 它还要求 输出数组个数 N也要为4的整数倍,还要求输入数组个数 为M+N-1 ,用的时候要注意了 请教楼主,FIR滤波一般有那些应用?有哪些意义?我看到过一些DSP在对正余弦信号AD采集后,进行FIR滤波,还要抽取,搞不懂为什么要这样.方便留下个联系方式吗.QQ或EMAIL,我的QQ:627564161,谢谢! MARK 楼主怎么不来了. 好象不是这个原因吧,我试了7阶滤波,结果还是一样的,很大很大。。。。 楼上能告诉我:
FIR滤波一般有那些应用?有哪些意义?我看到过一些DSP在对正余弦信号AD采集后,进行FIR滤波,还要抽取,搞不懂为什么要这样.
非常感谢! 不用想得太复杂。。。
它就是用来滤波,滤波。。。
低通,高通,带通。。。等等。。。和模拟滤波器一样
只是数字滤波器相对模拟滤波器可以很轻松的做到很高的阶数,得到更好的效果
我也就清楚那么多,呵呵 记号,1楼,你说的4的整数倍那个问题文档中好像有吧 通过串口输出 滤波前后数据,利用matlab 画图 比较,发现曲线毛刺少了,平滑性也会好多 回复 hetao7241:
不好意思啊,最近比较忙。AD 采集的数据 会叠加一部分噪声进来,如果直接对这些数据 进行运算的话会引入很大误差,所以要用 滤波处理。你可以通过串口输出 滤波前后数据,利用matlab或LABVIEW 画图 比较,可以很直观的看到滤波结果。发现曲线毛刺少了,曲线平滑性也会好多。
数字滤波的好处是 可以做的接近理想滤波器,实际 模拟滤波电路,可能会 由于器件(电阻,电容)的值有误差而不是太准,效果可能会差些。
为什么要用FIR 滤波呢,大家可以baidu,google 一下FIR 滤波的定义,优点,算法原理,我就不在这罗嗦了。其实 我上学学的 数字信号系统与信号处理 早就还给老师了。现在才明白 原来这玩意还是挺有用的。 回复 xinfa190 :
4的整数倍 问题,文档中或许有,我又看了 一遍还是没看到,呵呵,不去管它啦。 老实说 ST提供的DSP库还是 很好用的,又是用汇编实现,针对STM32优化过的。
记得参数 类型要符合要求。 http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_475533.jpg
滤波前 (原文件名:0.jpg)
http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_475534.jpg
滤波后 (原文件名:1.jpg) 谢谢10楼 oursstm32 .过段时间,我也准备来做那个FIR滤波,到时有些问题再请教你哟. 请教下楼主:STM32的DSP库中的一个C源码的8阶IIR滤波器函数 iir_biquad_stm32采用的是二阶四级级联的模式,假如系数事先放大1024倍的话调用此函数后输出值是不是应该除以 4096
原函数如下:
/**
* @briefCanonique Form of 8th order IIR filter, factorized in
* 4 biquads sections in series.
* @param y: Output array .
* @param x: Input array
* @param IIRCoeff: IIR Filter Coefficients, an array of 20 shorts
* @param ny: the number of output samples
* @retval : None
*/
void iir_biquad_stm32(uint16_t *y, uint16_t *x, int16_t *IIRCoeff, uint16_t ny)
{
uint32_t i;
uint32_t w1_2 = 0, w1_1 = 0, w1;
uint32_t w2_2 = 0, w2_1 = 0, w2;
uint32_t w3_2 = 0, w3_1 = 0, w3;
uint32_t w4_2 = 0, w4_1 = 0, w4;
/** Canonic form **/
/* 1st section */
for (i=0; i<ny-2; i++)
{
w1 = x - IIRCoeff*w1_1 - IIRCoeff*w1_2;
y = (IIRCoeff*w1 + IIRCoeff*w1_1 + IIRCoeff*w1_2);
w1_2 = w1_1;
w1_1 = w1;
}
/* 2nd section */
for (i=0; i<ny-2; i++)
{
w2 = y - IIRCoeff*w2_1 - IIRCoeff*w2_2;
y = (IIRCoeff*w2 + IIRCoeff*w2_1 + IIRCoeff*w2_2);
w2_2 = w2_1;
w2_1 = w2;
}
/* 3rd section */
for (i=0; i<ny-2; i++)
{
w3 = y - IIRCoeff*w3_1 - IIRCoeff*w3_2;
y = (IIRCoeff*w3 + IIRCoeff*w3_1 + IIRCoeff*w3_2);
w3_2 = w3_1;
w3_1 = w3;
}
/* 4th section */
for (i=0; i<ny-2; i++)
{
w4 = y - IIRCoeff*w4_1 - IIRCoeff*w4_2;
y = (IIRCoeff*w4 + IIRCoeff*w4_1 + IIRCoeff*w4_2);
w4_2 = w4_1;
w4_1 = w4;
}
} 这个IIR 滤波,没用过还真不太清楚,只用过FIR 滤波--假如系数事先放大1024倍的话调用此函数后输出值是应该除以 1024的,这一点在matlab 上验证过。IIR具体是个什么情况,还真不太清楚,建议你 也可以在 matlab上 验证一把。^--^ 楼主能不能说说FIR的系数是怎么算的??? FIR的系数是通过matlab 计算的,,matlab语句如下:
%7阶滤波
%得出滤波器的阶数n=7
fs=5000 %采样率5K
fc1=200
w1=2*fc1/fs; %将模拟滤波器的技术指标转换为数字滤波器的技术指标
b=fir1(7,w1); %使用标准频率响应的加窗设计函数fir1,7阶滤波
b=b*1024 %将系数放大1024 倍,
输出系数b 的值即可 楼上的能不能告诉怎么去学习matlab这一部分,比如怎么计算FIR的系数.谢谢! 怎么学?上网查吧!看书也行! FIR 系数的计算如上18楼的贴 ^--^ mark mark up oursstm32兄,能否留一下联系方式,有FIR滤波的问题请教一下。我的邮箱:northeast1@163.com 标记,只玩了FFT,找时间把FIR学习一下。 很有用! mark 我用楼主的方式试了试,貌似没有滤波的效果啊 请问楼主在使用该函数的时候需要设置什么嘛 Mark。。。 如果我的滤波器系数不是4的倍数该怎么办啊?有什么解决的好方法吗? STM32 DSP 包里面的FIR貌似有问题,我以100Hz的采样率做的数据X[],它处理完了,滤波效果是有的,但是输出的A[]中的数据频率只有50Hz了。。。 mark mark 请教楼主:
我按照楼主所说做了一个测试,7阶带通滤波,4k~80k带通
为了便于对应,使用楼主的变量名
fs=195804
fc1=4000
fc2=80000
w1=2*fc1/fs
w2=2*fc2/fs
wn=
b=fir1(7,wn,'bandpass')
结果是:
b =
-0.0001 -0.0061 -0.1195 0.5657 0.5657 -0.1195 -0.0061 -0.0001
这些系数该如何转换才可以在STM32的DSP库中使用呢 mark mark 大家帮我看看,我是按LZ的修改的,为什么我用matlab仿真滤波根本没有效果,代码如下;
采样率为50K,截至频率是100Hz,7阶
上图是滤波前,下图是滤波后
clear all;
clc;
N = 1024; %显示数据的个数
Fs = 50000; %采样率
dt = (1:N)/Fs; %时间间隔
f1 = 200; %输入信号的频率1
f2 = 2000; %输入信号的频率2
x = 2048 + 512*sin(2*pi*f1*dt) + 512*sin(2*pi*f2*dt);%产生混合输入信号
figure(1);
subplot(2,1,1);
plot(x);
grid on
Fc = 100; % 滤波器的截至频率
Wp = 2*Fc/Fs; %将模拟滤波器的技术指标转换为数字滤波器的技术指标
b=fir1(7,Wp); %使用标准频率响应的加窗设计函数fir1
b=b*1024; %滤波系数的生产
x = filter(b,1,x);%对信号s进行滤波
x=x/1024;
figure(1);
subplot(2,1,2);
plot(x);
grid on
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_621168ACCYGM.PNG
(原文件名:未命名.PNG) mark 建议使用matlab的fdatool设计fir滤波器,方便直观 mark 楼主确实厉害,好好交流交流…… LZ的M和N最大能到多少啊我的到了32就不能再上了 否则STM32就跑不起了 MARK mark mark MARK Mark! 楼主的FIR程序可不可以共享一下啊,好难搞 回复【楼主位】oursstm32
---------------------------------------------------------------
楼主求救,能不能把代码再详细点啊,为什么输入数组元素个数是输出的2倍,这不会有问题么 mark 楼主好人啊! mark{:biggrin:}{:biggrin:} 太复杂了,为什么又那么难搞的东西! 学习学习,最近研究IIR和FIR滤波 好东西标记下 谢谢楼主啦。我要做交流量采样计数电流有效值,设想是AD采样,fir滤波后,再均方根计算。正要使用stm32_dsp 库的fir函数,以及如何产生系数! lou0908 发表于 2011-3-9 17:26
大家帮我看看,我是按LZ的修改的,为什么我用matlab仿真滤波根本没有效果,代码如下;
采样率为50K,截至频 ...
你的问题后来怎么解决的呀?
页:
[1]