DSP的FIR设计(低通滤波)C语言编写

合集下载

DSP的FIR设计(低通滤波)C语言编写

DSP的FIR设计(低通滤波)C语言编写

一、设计目的低通滤波器设计。

本设计中使用的信号为信息信号: signal=sin(2*pi*sl*n*T)高频噪声1:noise1=0.7*sin(2*pi*ns1*n*T) 高频噪声2:noise2=0.4*sin(2*pi*ns2*n*T) 混合信号: x=(signal+noise1+noise2)其中sl=500Hz ,ns1=3000Hz ,ns2=8000Hz ,T=1/20000。

混合信号波形为滤波器输入信号波形,信息信号波形为输出信号波形,滤波器的效果为滤除两个高频噪声。

二、FIR 滤波器基本理论(1)FIR 滤波器的特点数字滤波器的功能,就是把输入序列通过一定的运算变换成输出序列。

它的实现方法有很多,其中比较常用到的是无限长脉冲响应滤波器 IIR 和有限长脉冲响应滤波器FIR 两种。

在计算量相等的情况下,IIR 数字滤波器比FIR 滤波器的幅频特性优越,频率选择性也好。

但是,它有着致命的缺点,其相位特性不好控制。

它的相位特性)argH( )f(ωωj e =是使频率产生严重的非线性的原因。

但是在图像处理、数据传输等波形传递系统中都越来越多的要求信道具有线性的相位特性。

在这方面 FIR 滤波器具有它独特的优点,设FIR 滤波器单位脉冲响应h(n)长度为N ,其系统函数H(z)为∑-=-=10)()(N n n z n h z HH(z)是1-z 的(N-1)次多项式,它在z 平面上有(N-1)个零点,原点z=0是(N-1)阶重极点。

因此,H(z)永远稳定,它可以在幅度特性随意设计的同时,保证精确、严格的线性相位。

(2)FIR 滤波器的基本结构数字滤波是将输入的信号序列,按规定的算法进行处理,从而得到所期望的输出序列,FIR 滤波器的差分方程为:∑-=-=1)()(N k k k n x a n y对上式进行Z 变换得到FIR 滤波器的传递函数为:()()()∑-=-==10N i kk z b z X z Y z H由上式可以看出,H(z)是1-z 的N-1次多项式,它在z 平面内有N-1个零点,同时在原点处有N-1个重极点。

c语言写的fir低通滤波器

c语言写的fir低通滤波器

根据fir滤波器的公式y(n)=∑h(m)x(n-m);(m: 0~(N-1)).利用MATLAB产生滤波器系数(h(n))并归一化,下面为一个LP滤波算法void filter(void){uint16 i,j;fp32 sum;int16 x1[2030];fp32 h[19]={ -0.0027, -0.0025, 0.0050, 0.0157, -0.0000, -0.0471, -0.0482, 0.0838, 0.2953, 0.4013,0.2953, 0.0838, -0.0482, -0.0471, -0.0000,0.0157, 0.0050, -0.0025, -0.0027};for(i=0;i<2020;i++)x1[i] = data0[i];for(i=0;i<2020;i++){sum=0.0;for(j=0;j<19;j++){if(i >= j)sum+=h[j]*x1[i-j];else;}data0[i]=(int16)sum;}for(i=0;i<2000;i++){data0[i] = data0[i+20];}}考虑到前19个点为不完全累加和,故抛去前19个点。

(应该是前后各18个点都是不完全累加和,都应该去掉,对于数据分段进入滤波器的情况,应该把前一段的后面数据放到下一段的前面,这段时间我在解调FSK时遇到了这个问题,通过滤波器的数据的分段处理。

)设输入数据x[N],输出数据y[N],滤波器系数h[n]1.直接法(由y(m)=h(0)*x(m)+h(1)*x(m-1)+...+h(N-1)*x(m-n-1));void fir(short x[], short h[], short y[]){int i,j;long long sum;for (j = 0; j < N; j++){sum = 0;for (i = 0; i < n; i++)sum += x[j-i] * h[i];y[j] = sum >> 15;}}乘法器使用次数:N*n2.逆推法:void fir(short x[], short h[], short y[]){int i,j;long sum;for (j = 0; j < n; j++){for (i = 0; i < N; i++){sum = 0;sum = h[j] * x[i]y[i] += sum >> 15;}}}乘法器使用次数:N*n3.倒序法:(输入输出可以是同一量)void fir(short x[], short h[], short y[]) {int i,j;long long sum;for (j = N; j > 0; j--){sum = 0;for (i = n; i > 0; i--)sum += x[j-i] * h[i];y[j] = sum >> 15;}}#include<stdio.h>#include<math.h>#define true 1#define false 0#define n 8#define bufsize 100 /* the buffer size is 100 *//* global declarations */int in_buffer[bufsize]; /* processing data buffers */int out_buffer[bufsize];/* functions */static int processing(int *input, int *output);static void dataio(void);static long round(long a);void main(){int *input = &in_buffer[0];int *output = &out_buffer[0];puts("the 1st experiment started\n");/* loop forever */while(true){/** read input data using a probe-point connected to a host file.* write output data to a graph connected through a probe-point.*/// read the input signal.// if the input file is sine1.dat, the signal contains 300hz,400hz and 500hz.// if the input file is sine2.dat, the signal contains 100hz,400hz and 500hz.// the sampling frequency is 1200hz.dataio();/* remove the frequency compoment of 400hz and 500hz*/processing(input, output);// write the output signal.// the output file is result.dat.dataio();}}/** ======== processing ========** function: apply a low-pass fir filter to input signal and remove the frequency higher than 350hz.** parameters: address of input and output buffers.** return value: true.static int processing(int *input, int *output){int i,size = bufsize;short xx0,x,y;// short z[n]={0,0,0,0,0,0,0,0,0};short z[n]={0,0,0,0,0,0,0,0};//short w[2*n+1]={22,356,155,990,466,220,777,216,777,26,466,9,155,0,22};//short w[2*n+1]={6,457,56,1024,224,418,523,382,784,99,784,43,523};// shortw[2*n+1]={330*2,3299*2,1982*2,6867*2,4955*2,1594*2,6607*2,1065*2,4955*2,109*2,1982*2,17*2, 330*2};//short w[2*n+1]={661,6598,3964,13733,9910,3187,13214,2131,9910,217,3964,34,661};// shortw[2*n+1]={58,5628,526,8192,2105,5883,4913,3829,7369,1543,7369,504,4913,102,2105,14,526,1,5 8};//shortw[2*n+1]={28,4432,280,8192,1259,4883,3356,3975,5873,1509,7048,644,5873,142,3356,30,1259,3, 280,0,28};// short w[2*n+1]={26,651,182,1024,545,421,909,247,909,51,545,11,182,1,26};//shortw[2*n+1]={831,20846,5815,32768,17445,13486,29075,7888,29075,1647,17445,349,5815,21,831}; //short w[2*n+1]={208,5211,1454,8192,4361,3371,7269,1972,7269,412,4361,87,1454,5,208};short w[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810}; // shortw[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810,2,101};// shortw[2*n+1]={50,3814,454,8192,1815,3504,4235*,3084,6353,831,6353,349,4235,50,1815,8,454,0,50} ;long y0,z0;//22222222222222while(size--){xx0=*input++;x=xx0*6;z0=(long)x<<15;y0=0;for(i=0;i<n;i++){z0-=(long)w[2*i+1]*(long)z[i];y0+=(long)w[2*i+2]*(long)z[i];}y0+=(long)w[0]*(z0>>15);y0=round(y0);for(i=n-1;i>0;i--)z[i]=z[i-1];z0=round(z0);z[0]=(short)(z0>>15);y=(short)(y0>>15);*output++ =y;}/* additional processing load */return(true);/** ======== dataio ========** function: read input signal and write processed output signal. ** parameters: none.** return value: none.*/static void dataio(){/* do data i/o */return;}static long round(long a){long x3;x3=a&(0xffff0000);return x3;}。

fir函数c语言实现

fir函数c语言实现

fir函数c语言实现FIR滤波器是一种广泛应用于数字信号处理领域的滤波器,它能够实现无限冲击响应(InfiniteImpulseResponse,简称FIR)滤波。

在许多实际应用中,FIR 滤波器被用来对信号进行平滑处理,去除噪声等。

下面将介绍如何使用C语言实现FIR滤波器。

一、FIR滤波器原理FIR滤波器是一种线性时不变系统,它通过一组滤波器系数将输入信号进行加权叠加,从而实现对信号的滤波处理。

FIR滤波器的输出信号与输入信号的关系可以用冲激响应表示,其冲激响应具有有限长度。

二、C语言实现FIR滤波器以下是一个简单的FIR滤波器的C语言实现,它采用递归方法实现滤波器的计算:```c#include<stdio.h>//FIR滤波器参数定义#defineFIR_LEN6//滤波器长度#defineTARGET_SNR10//目标信噪比#defineALPHA0.001//噪声系数//FIR滤波器系数定义floatfir_coeff[]={/*...*/};//滤波器系数数组//FIR滤波器函数实现floatfir_filter(floatinput){floatoutput=0;//滤波器输出floatx=input;//输入信号当前值floaty=x;//输入信号之前值floatz=x;//滤波器输出之前值inti;for(i=0;i<FIR_LEN;i++){y=y*ALPHA+fir_coeff[i]*z;//更新输入信号和滤波器输出output+=y;//更新滤波器输出z=x;//更新滤波器输出之前值}returnoutput/FIR_LEN;//归一化滤波器输出值}```这个代码实现了简单的FIR滤波器,其输入是一个浮点数类型的信号。

滤波器的长度和参数需要根据具体的应用场景进行调整。

此外,还需要准备一个FIR滤波器系数数组,并将其定义在代码中。

三、使用示例下面是一个使用示例,展示了如何使用上述代码对一组信号进行FIR滤波处理:```c#include<stdio.h>#include<stdlib.h>#include<time.h>intmain(){//生成一组随机信号作为输入数据floatsignals[]={/*...*/};//输入信号数组,包含多个样本数据intsignal_len=sizeof(signals)/sizeof(float);//信号长度srand(time(NULL));//设置随机数种子intidx=rand()%signal_len;//随机选择一个样本作为输入信号的起始点floatoutput[signal_len];//输出数组,用于存储滤波处理后的结果inti;for(i=idx;i<idx+signal_len;i++){//对每个样本进行滤波处理output[i-idx]=fir_filter(signals[i]);//使用fir_filter函数进行滤波处理,并将结果存储在output数组中}printf("Filteredsignals:\n");//输出滤波处理后的结果for(i=0;i<signal_len;i++){//输出每个样本的滤波处理结果printf("%f\n",output[i]);}return0;}```这个示例代码生成了一组随机信号作为输入数据,并使用上述实现的FIR滤波器对每个样本进行滤波处理。

DSP的FIR设计低通滤波C语言编写

DSP的FIR设计低通滤波C语言编写

DSP的FIR设计低通滤波C语言编写FIR(有限脉冲响应)滤波器是一种常用的数字滤波器,用于数字信号处理中的滤波操作。

FIR滤波器的设计通常包括两个主要步骤:滤波器的规格化和滤波器系数的计算。

滤波器的规格化是指确定滤波器的采样频率,截止频率以及陷波增益等参数。

在设计低通FIR滤波器时,我们需要确定滤波器的截止频率。

假设我们希望设计一个截止频率为Fs/4的低通FIR滤波器,其中Fs是采样频率。

根据滤波器设计的基本原理,我们可以得到滤波器的频率响应公式为:H(k) = (2 * Fs/4 * sin(2 * pi * Fs/4 * k))/(pi * k)其中,k是从0到N-1的整数序列,N是滤波器的长度。

经过频域设计,我们可以通过计算滤波器的频率响应公式来获得滤波器的系数。

接下来,我们将使用C语言编写一个低通FIR滤波器的代码示例。

在这个示例中,我们将实现一个截止频率为Fs/4的低通FIR滤波器,采样频率为Fs。

代码如下:```c#include <stdio.h>#include <stdlib.h>#include <math.h>//定义滤波器的长度#define N 51//定义采样频率//定义滤波器的截止频率#define Fc (Fs/4)//计算滤波器的系数void calculateCoefficients(float* coefficients)float sum = 0;for (int k = 0; k < N; k++)if (k == N/2)coefficients[k] = 2 * Fc/Fs;} elsecoefficients[k] = (sin(2.0 * M_PI * Fc * (k - N/2) / Fs)) / (M_PI * (k - N/2));}sum += coefficients[k];}//归一化滤波器的系数for (int k = 0; k < N; k++)coefficients[k] /= sum;}//应用滤波器void applyFilter(float* input, float* output, float* coefficients, int length)for (int n = 0; n < length; n++)output[n] = 0;for (int k = 0; k < N; k++)if (n - k >= 0)output[n] += input[n - k] * coefficients[k];}}}int mai//定义输入信号和输出信号的长度int length = 100;//为输入信号和输出信号分配内存空间float* input = (float*)malloc(length*sizeof(float));float* output = (float*)malloc(length*sizeof(float));//为滤波器的系数分配内存空间float* coefficients = (float*)malloc(N*sizeof(float));//生成输入信号for (int n = 0; n < length; n++)input[n] = sin(2.0 * M_PI * 1000 * n / Fs);}//计算滤波器的系数calculateCoefficients(coefficients);//应用滤波器applyFilter(input, output, coefficients, length); //打印输出信号for (int n = 0; n < length; n++)printf("%f\n", output[n]);}//释放内存空间free(input);free(output);free(coefficients);return 0;```在上面的代码示例中,我们首先定义了滤波器的长度、采样频率以及截止频率。

DSP论文-FIR滤波器的DSP实现

DSP论文-FIR滤波器的DSP实现

FIR滤波器的DSP实现一.实验中出现的错误:错误一/fdacoefs.h 为Matlab 生成的系数表头文件,刚开始没办法正常运行导入到工程的C语言源代码,原因是下面框图所示,修改fdacoefs.h 中的代码后,要将.h 文件与工程文件放入同一个文件夹中。

1.新建工程2.编写C 语言源代码并导入工程#include "stdio.h"#include "fdacoefs.h"#define N 81#define LEN 200long yn;int input[LEN];int output[LEN];void main(){int i,j;int *x;for(j=0;j<LEN-1;j++){x=&input[j];yn = 0;for(i=0; i<N-1; i++)yn += B[i]*(*x++);output[j]=yn>>15;}while(1);}错误二:开始的时候还在工程中导入了rts.libwen文件,结果出现上面显示的错误,最终将.lib从工程中移除后编译成功。

错误三:错误三是最终出打开之前Matlab 生成的input.dat 文件,设置完Address时,Adress不能正确设置,导致出现上述错误。

在将实验全部重新调试多变,找张琼英和江杰都重新将程序重新运行后,仍然得不到解决。

程序运行全部正确,换了台电脑最后做出结果,得出的解释可能是自己的电脑出了问题,因为用记事本打开的inputdat文件全是乱码,而在别人的电脑上打开是正确的。

考虑到系统最近运行不畅,感觉是这个原因。

以上是程序及调试过程中出现的主要错误。

二.实验目的和要求:旨在研究FIR滤波器的DSP实现方法。

软件仿真利用C语言产生一个方波暑假文件fir_in.dat,利用CCS的探针和中断调试功能读入数据文件作为FIR滤波器的输信号,经FIR滤波后输出正弦信号fir_out.dat文件,然后对该输出文件用图形文件显示出来。

DSP的FIR设计C语言编写

DSP的FIR设计C语言编写

DSP的FIR设计C语言编写FIR(Finite Impulse Response)滤波器是数字信号处理中常用的一种滤波器类型。

它具有有限的冲激响应,只对有限长度的输入信号做出响应。

低通滤波器是一种能够通过滤除高频分量而保留低频分量的滤波器。

FIR低通滤波器的设计可以通过数字滤波器设计方法来实现,其中一种常用的方法是窗函数法。

以下是一个用C语言编写的FIR低通滤波器设计实例:```c#include <stdio.h>#include <stdlib.h>#include <math.h>//FIR低通滤波器设计函数void fir_lowpass_filter_design(float *filter, int order, float cutoff_freq, float sampling_freq)int i;float omega_c = 2 * M_PI * cutoff_freq / sampling_freq;//计算滤波器系数for (i = 0; i <= order; i++)if (i == (order / 2))filter[i] = omega_c / M_PI;filter[i] = sin(omega_c * (i - (order / 2))) / (M_PI * (i - (order / 2)));}int mainint order = 51; // 滤波器阶数float cutoff_freq = 1000.0; // 截止频率float sampling_freq = 8000.0; // 采样频率float *filter = malloc((order + 1) * sizeof(float)); // 分配滤波器系数数组内存//调用FIR低通滤波器设计函数fir_lowpass_filter_design(filter, order, cutoff_freq, sampling_freq);//打印滤波器系数printf("Filter Coefficients:\n");for (int i = 0; i <= order; i++)printf("h[%d] = %f\n", i, filter[i]);}free(filter); // 释放滤波器系数数组内存return 0;上述代码中的`fir_lowpass_filter_design`函数用于计算滤波器系数,其参数`filter`是一个指向滤波器系数数组的指针,`order`是滤波器阶数,`cutoff_freq`是截止频率,`sampling_freq`是采样频率。

FIR低通滤波器C语言实现

FIR低通滤波器C语言实现

provided that
* the above copyright notice and this license appear in all
第1页
文文: C:\Documents and Settings\user\桌桌\FirAlgs.c 2009-3-27 27, 15:53:51
source copies. * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF * ANY KIND. See /wol.htm for more information. * ************************************************************** ***************/
implement FIR filters
* in C.
*
* Copyright 2000 by Grant R. Griffin
*
* Thanks go to contributors of comp.dsp for teaching me some
of these
* techniques, and to Jim Thomas for his review and great
not very
* efficient in C, and are provided here mainly to illustrate
FIR
* algorithmic concepts. However, the functions fir_split,
fir_double_z
* and fir_double_h are all fairly efficient ways to

FIR滤波器设计C语言程序

FIR滤波器设计C语言程序

FIR滤波器设计C语言程序1.确定滤波器的设计规格:包括截止频率、通带衰减和阻带衰减等参数。

2.确定滤波器的阶数:滤波器的阶数决定了它对信号的滤波效果,一般通过经验或者设计规范来确定。

3. 确定滤波器的频率响应:可以通过Matlab等工具进行设计,也可以根据设计规范选择标准的频率响应曲线。

常见的设计方法包括窗函数法、最小最大设计法等。

4.根据频率响应设计滤波器的系数:根据频率响应的定义,可以使用反离散傅里叶变换(IDFT)计算滤波器的系数。

5.实现滤波器的差分方程:根据滤波器的差分方程,可以使用C语言编写对应的代码。

差分方程描述了滤波器的输入和输出之间的关系。

下面是一个简单的FIR滤波器设计的C语言程序示例:```c#include <stdio.h>#include <stdlib.h>#define N 10 // 滤波器的阶数//FIR滤波器系数float h[N] =0.1,0.2,0.3,0.4,0.5,0.4,0.3,0.2,0.1,0.05};//输入信号缓冲区float x[N] = {0};//输出信号float y = 0;//FIR滤波器函数float fir_filter(float input) int i;//将最新的输入信号插入到缓冲区for (i = N - 1; i > 0; i--)x[i]=x[i-1];}x[0] = input;//计算输出信号y=0;for (i = 0; i < N; i++)y+=h[i]*x[i];}return y;int main//输入信号float input_signal[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//滤波后的输出信号float output_signal[10] = {0};int i;//对输入信号进行滤波for (i = 0; i < 10; i++)output_signal[i] = fir_filter(input_signal[i]);}//打印输出结果for (i = 0; i < 10; i++)printf("Output[%d] = %f\n", i, output_signal[i]);}return 0;```在上面的示例代码中,我们采用了一个长度为10的缓冲区来存储输入信号。

基于DSP的FIR滤波器的C语言算法实现

基于DSP的FIR滤波器的C语言算法实现
h = fir1( 16, 1500/ 8000* 2) ;
得到 17 个滤波器系数转化成 Q15 格式, 即分别乘以 32768( 215 ) , 转化成 Q15 格式的滤波器系数如下 :
h [ ] = { 0, 158, 263, - 290, - 1406, - 951, 3186, 9287, 12272, 9287, 3186, - 951, - 1406, - 290, 263, 158, 0} 。
信号与信息处理
基于 DSP 的 FIR 滤波器的 C 语言算法实现
史明泉
( 内蒙古科技大学 信息工程学院, 内蒙古 包头 014010)
摘 要 有 限冲 激 响应 ( FIR ) 滤 波器 是 数字 信 号处 理系 统 中最 基本 的 元件 , 具 有 严格 的 线 性相 频 特 性 , 同 时 其 单位抽 样 响 应 是 有 限 长 的 , 系 统 稳 定 。 阐 述 了 FIR 的 基 本 原 理 , 并 进 行 了 MATLAB 仿 真 。 基 于 T I 公 司 的 TMS320VC5402 DSP 硬件 平 台 , 设 计 了 FIR 低 通 滤 波 器 。 采 用 C 语 言 算 法 , 利 用 集 成 开 发 环 境 代 码 调 式 器 ( Code Composer Studio, CCS ) 分 别观 察 了输 入和 输 出波 形 , 验 证了 此算 法 的 准 确 性 和 高 效 性 , 对 信 号 处 理 及 信 号 传 输 有 重 要的 研究 意 义。 关键词 FIR 滤波器 ; 数字信号处理 ; DSP; 算法 中图分类号 TN713 文献标识码 A 文章编号 1003- 3106( 2011) 01- 0013- 02
图1
收稿日期 : 2010 10 08

(完整word版)c语言写的fir低通滤波器

(完整word版)c语言写的fir低通滤波器

根据fir滤波器的公式y(n)=∑h(m)x(n-m);(m: 0~(N-1)).利用MATLAB产生滤波器系数(h(n))并归一化,下面为一个LP滤波算法void filter(void){uint16 i,j;fp32 sum;int16 x1[2030];fp32 h[19]={ -0.0027, -0.0025, 0.0050, 0.0157, -0.0000, -0.0471, -0.0482, 0.0838, 0.2953, 0.4013,0.2953, 0.0838, -0.0482, -0.0471, -0.0000,0.0157, 0.0050, -0.0025, -0.0027};for(i=0;i<2020;i++)x1[i] = data0[i];for(i=0;i<2020;i++){sum=0.0;for(j=0;j<19;j++){if(i >= j)sum+=h[j]*x1[i-j];else;}data0[i]=(int16)sum;}for(i=0;i<2000;i++){data0[i] = data0[i+20];}}考虑到前19个点为不完全累加和,故抛去前19个点。

(应该是前后各18个点都是不完全累加和,都应该去掉,对于数据分段进入滤波器的情况,应该把前一段的后面数据放到下一段的前面,这段时间我在解调FSK时遇到了这个问题,通过滤波器的数据的分段处理。

)设输入数据x[N],输出数据y[N],滤波器系数h[n]1.直接法(由y(m)=h(0)*x(m)+h(1)*x(m-1)+...+h(N-1)*x(m-n-1));void fir(short x[], short h[], short y[]){int i,j;long long sum;for (j = 0; j < N; j++){sum = 0;for (i = 0; i < n; i++)sum += x[j-i] * h[i];y[j] = sum >> 15;}}乘法器使用次数:N*n2.逆推法:void fir(short x[], short h[], short y[]){int i,j;long sum;for (j = 0; j < n; j++){for (i = 0; i < N; i++){sum = 0;sum = h[j] * x[i]y[i] += sum >> 15;}}}乘法器使用次数:N*n3.倒序法:(输入输出可以是同一量)void fir(short x[], short h[], short y[]) {int i,j;long long sum;for (j = N; j > 0; j--){sum = 0;for (i = n; i > 0; i--)sum += x[j-i] * h[i];y[j] = sum >> 15;}}#include<stdio.h>#include<math.h>#define true 1#define false 0#define n 8#define bufsize 100 /* the buffer size is 100 *//* global declarations */int in_buffer[bufsize]; /* processing data buffers */int out_buffer[bufsize];/* functions */static int processing(int *input, int *output);static void dataio(void);static long round(long a);void main(){int *input = &in_buffer[0];int *output = &out_buffer[0];puts("the 1st experiment started\n");/* loop forever */while(true){/** read input data using a probe-point connected to a host file.* write output data to a graph connected through a probe-point.*/// read the input signal.// if the input file is sine1.dat, the signal contains 300hz,400hz and 500hz.// if the input file is sine2.dat, the signal contains 100hz,400hz and 500hz.// the sampling frequency is 1200hz.dataio();/* remove the frequency compoment of 400hz and 500hz*/processing(input, output);// write the output signal.// the output file is result.dat.dataio();}}/** ======== processing ========** function: apply a low-pass fir filter to input signal and remove the frequency higher than 350hz.** parameters: address of input and output buffers.** return value: true.static int processing(int *input, int *output){int i,size = bufsize;short xx0,x,y;// short z[n]={0,0,0,0,0,0,0,0,0};short z[n]={0,0,0,0,0,0,0,0};//short w[2*n+1]={22,356,155,990,466,220,777,216,777,26,466,9,155,0,22};//short w[2*n+1]={6,457,56,1024,224,418,523,382,784,99,784,43,523};// shortw[2*n+1]={330*2,3299*2,1982*2,6867*2,4955*2,1594*2,6607*2,1065*2,4955*2,109*2,1982*2,17*2, 330*2};//short w[2*n+1]={661,6598,3964,13733,9910,3187,13214,2131,9910,217,3964,34,661};// shortw[2*n+1]={58,5628,526,8192,2105,5883,4913,3829,7369,1543,7369,504,4913,102,2105,14,526,1,5 8};//shortw[2*n+1]={28,4432,280,8192,1259,4883,3356,3975,5873,1509,7048,644,5873,142,3356,30,1259,3, 280,0,28};// short w[2*n+1]={26,651,182,1024,545,421,909,247,909,51,545,11,182,1,26};//shortw[2*n+1]={831,20846,5815,32768,17445,13486,29075,7888,29075,1647,17445,349,5815,21,831}; //short w[2*n+1]={208,5211,1454,8192,4361,3371,7269,1972,7269,412,4361,87,1454,5,208};short w[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810}; // shortw[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810,2,101};// shortw[2*n+1]={50,3814,454,8192,1815,3504,4235*,3084,6353,831,6353,349,4235,50,1815,8,454,0,50} ;long y0,z0;//22222222222222while(size--){xx0=*input++;x=xx0*6;z0=(long)x<<15;y0=0;for(i=0;i<n;i++){z0-=(long)w[2*i+1]*(long)z[i];y0+=(long)w[2*i+2]*(long)z[i];}y0+=(long)w[0]*(z0>>15);y0=round(y0);for(i=n-1;i>0;i--)z[i]=z[i-1];z0=round(z0);z[0]=(short)(z0>>15);y=(short)(y0>>15);*output++ =y;}/* additional processing load */return(true);/** ======== dataio ========** function: read input signal and write processed output signal. ** parameters: none.** return value: none.*/static void dataio(){/* do data i/o */return;}static long round(long a){long x3;x3=a&(0xffff0000);return x3;}。

c语言写的fir低通滤波器

c语言写的fir低通滤波器

创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*根据fir滤波器的公式y(n)=∑h(m)x(n-m);(m: 0~(N-1)).利用MATLAB产生滤波器系数(h(n))并归一化,下面为一个LP滤波算法void filter(void){uint16 i,j;fp32 sum;int16 x1[2030];fp32 h[19]={ -0.0027, -0.0025, 0.0050, 0.0157, -0.0000, -0.0471, -0.0482, 0.0838, 0.2953, 0.4013,0.2953, 0.0838, -0.0482, -0.0471, -0.0000,0.0157, 0.0050, -0.0025, -0.0027};for(i=0;i<2020;i++)x1[i] = data0[i];for(i=0;i<2020;i++){sum=0.0;for(j=0;j<19;j++){if(i >= j)sum+=h[j]*x1[i-j];else;}data0[i]=(int16)sum;}for(i=0;i<2000;i++){data0[i] = data0[i+20];}}考虑到前19个点为不完全累加和,故抛去前19个点。

(应该是前后各18个点都是不完全累加和,都应该去掉,对于数据分段进入滤波器的情况,应该把前一段的后面数据放到下一段的前面,这段时间我在解调FSK时遇到了这个问题,通过滤波器的数据的分段处理。

)设输入数据x[N],输出数据y[N],滤波器系数h[n]1.直接法(由y(m)=h(0)*x(m)+h(1)*x(m-1)+...+h(N-1)*x(m-n-1));void fir(short x[], short h[], short y[]){int i,j;long long sum;for (j = 0; j < N; j++){sum = 0;for (i = 0; i < n; i++)sum += x[j-i] * h[i];y[j] = sum >> 15;}}乘法器使用次数:N*n2.逆推法:void fir(short x[], short h[], short y[]){int i,j;long sum;for (j = 0; j < n; j++){for (i = 0; i < N; i++){sum = 0;sum = h[j] * x[i]y[i] += sum >> 15;创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*}}}乘法器使用次数:N*n3.倒序法:(输入输出可以是同一量)void fir(short x[], short h[], short y[]){int i,j;long long sum;for (j = N; j > 0; j--){sum = 0;for (i = n; i > 0; i--)sum += x[j-i] * h[i];y[j] = sum >> 15;}}#include<stdio.h>#include<math.h>#define true 1#define false 0#define n 8#define bufsize 100 /* the buffer size is 100 *//* global declarations */int in_buffer[bufsize]; /* processing data buffers */int out_buffer[bufsize];/* functions */static int processing(int *input, int *output);static void dataio(void);static long round(long a);void main(){int *input = &in_buffer[0];int *output = &out_buffer[0];puts("the 1st experiment started\n");/* loop forever */while(true){/** read input data using a probe-point connected to a host file.* write output data to a graph connected through a probe-point.*/// read the input signal.// if the input file is sine1.dat, the signal contains 300hz,400hz and 500hz.// if the input file is sine2.dat, the signal contains 100hz,400hz and 500hz.// the sampling frequency is 1200hz.dataio();/* remove the frequency compoment of 400hz and 500hz*/processing(input, output);// write the output signal.// the output file is result.dat.dataio();}}/** ======== processing ========** function: apply a low-pass fir filter to input signal and remove the frequency higher than 350hz.** parameters: address of input and output buffers.创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*** return value: true.*/static int processing(int *input, int *output){int i,size = bufsize;short xx0,x,y;// short z[n]={0,0,0,0,0,0,0,0,0};short z[n]={0,0,0,0,0,0,0,0};//short w[2*n+1]={22,356,155,990,466,220,777,216,777,26,466,9,155,0,22};//short w[2*n+1]={6,457,56,1024,224,418,523,382,784,99,784,43,523};// shortw[2*n+1]={330*2,3299*2,1982*2,6867*2,4955*2,1594*2,6607*2,1065*2,4955*2,109*2,1982*2, 17*2,330*2};//short w[2*n+1]={661,6598,3964,13733,9910,3187,13214,2131,9910,217,3964,34,661};// shortw[2*n+1]={58,5628,526,8192,2105,5883,4913,3829,7369,1543,7369,504,4913,102,2105,14,52 6,1,58};//shortw[2*n+1]={28,4432,280,8192,1259,4883,3356,3975,5873,1509,7048,644,5873,142,3356,30,12 59,3,280,0,28};// short w[2*n+1]={26,651,182,1024,545,421,909,247,909,51,545,11,182,1,26};//shortw[2*n+1]={831,20846,5815,32768,17445,13486,29075,7888,29075,1647,17445,349,5815,21,83 1};//shortw[2*n+1]={208,5211,1454,8192,4361,3371,7269,1972,7269,412,4361,87,1454,5,208};shortw[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810};// shortw[2*n+1]={101,4356,810,8192,2835,3403,5670,2517,7088,605,5670,193,2835,21,810,2,101}; // shortw[2*n+1]={50,3814,454,8192,1815,3504,4235*,3084,6353,831,6353,349,4235,50,1815,8,454, 0,50};long y0,z0;//22222222222222while(size--){xx0=*input++;x=xx0*6;z0=(long)x<<15;y0=0;for(i=0;i<n;i++){z0-=(long)w[2*i+1]*(long)z[i];y0+=(long)w[2*i+2]*(long)z[i];}y0+=(long)w[0]*(z0>>15);y0=round(y0);for(i=n-1;i>0;i--)z[i]=z[i-1];z0=round(z0);z[0]=(short)(z0>>15);y=(short)(y0>>15);*output++ =y;}/* additional processing load */return(true);}/** ======== dataio ========** function: read input signal and write processed output signal.** parameters: none.** return value: none.*/static void dataio(){/* do data i/o */return;}static long round(long a){long x3;x3=a&(0xffff0000);return x3;}创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

三、FIR 滤波器的 MATLAB 实现
MATLAB 辅 助 DSP 实 现 FIR , 其总体过程为在 DSP 中编写 处理程序 ,在 MATLAB中利用滤波器设计、 分析工具( FDATOOL) ,根据指定的滤波器性能快速 设计一个FIR ,再把滤波器系数以头文件形式导入CCS 中,头文件中MATLAB 辅 助DSP 实现FIR 数字滤波器含滤波器阶数和系数数组,在MATLAB中调试、运行 DSP 程序并显示、分析处理后的数据。使用该方法,便于采用汇编语言来实现程 序。头文件名不变,当MATLAB中设计的滤波器系数改变时,相应头文件中系数也 改变,方便程序调试、仿真。 (1)输入信号的产生 首先利用 Matlab 产生导入 CCS 的 dat 文件,具体实现如下代码所示 sl=500; %有效信号 ns1=3000; %高频噪声 ns2=8000; %高频噪声 fs=20000; %采样频率 N=1000; T=1/fs; n=0:N; signal=sin(2*pi*sl*n*T); noise1=0.7*sin(2*pi*ns1*n*T); noise2=0.4*sin(2*pi*ns2*n*T); x=(signal+noise1+noise2);%待滤波信号 figure(1) plot(x) figure(2) y=abs(fft(x));%待滤波频谱 df=n*(fs/N); plot(df,y) figure(3) plot(signal) figure(4) ysignal=abs(fft(signal));%滤波后频谱 df=n*(fs/N); plot(df,ysignal) %滤波数据导出 xout=x/max(x); %归一化
0.4
0.2
0
-0.2
-0.4
-0.6
-0.8
-1
0
200
400
600
800
1000
1200
图 输出时域波形
频谱如图所示
500
450
400
350
300
250
200
150
100
50
0
0
0.2
0.4
0.6
8
1
1.2
1.4
1.6
1.8 x 10
2
4
图 输出频谱
(2)滤波器的设计 MATLAB 集成了一套功能强大的滤波器设计工具 FDATool(Filter Design & Analysis Tool) ,可以完成多种滤波器的设计、分析和性能评估。 a.打开 Filter Design & Analysis Tool 单击 MATLAB 主窗口下方的“Start”按钮,选择菜单“ToolBox” →“Filter Design” →“Filter Design & Analysis Tool(FDATool) ”命令,打开 FDATool, 如图所示。
分别观察滤波前后的时域波形图
图 滤波前时域波形
图 滤波后时域波形
五、FIR 滤波器的 DSP 实现
(1)DSP 中滤波器的 z 算法实现 FIR 滤波器的输出表达式为
y (n) h(i )x(n i )
n 0 N 1 N / 2 1 n 0
1
h(i)s(n i)
式中,为滤波器系数;x(n)表示滤波器在 n 时刻的输入;y(n)为 n 时刻的输出。 它的基本算法是一种乘法-累加运算,即不断地输入样本 x(n),经过延时后, 再进行乘法-累加,最后输出滤波结果 y(n)。 1)线性缓冲区法:线性缓冲区法又称延迟线法,其特点: (a)对于 N 级的 FIR 滤波器, 在数据存储器中开辟一个 N 单元的缓冲区 (滑 窗) ,用来存放最新的 N 个输入样本; (b)从最老样本开始取数,每取一个样本后,将此样本向下移位; (c)读完最后一个样本后,输入最新样本存入缓冲区的顶部。 2)循环缓冲区法:循环缓冲区法的特点如下: (a)对于 N 级 FIR 滤波器,在数据存储器中开辟一个 N 单元的缓冲区(滑 窗) ,用来存放最新的 N 个输入样本; (b)从最新样本开始取数; (c)读完最后一个样本(最老样本)后,输入最新样本来代替最老样本, 而其他数据位置不变; (d)用片内 BK(循环缓冲区长度)寄存器对缓冲区进行间接寻址,使循环 缓冲区地址首尾相邻。本次设计的 FIR 滤波器所采用的就是循环缓冲区法。 (2)C 语言实现 FIR
f( ) argH(e j ) 是使频率产生严重的非线性的原因。但是在图像处理、数据传
输等波形传递系统中都越来越多的要求信道具有线性的相位特性。 在这方面 FIR 滤波器具有它独特的优点,设 FIR 滤波器单位脉冲响应 h(n)长度为 N,其系统函 数 H(z)为
H ( z ) h( n) z n
图 fadatool 的启动
b.产生滤波器 (chebyshev) , 阶数为 81 阶, 这里应填 80, 比阶数少 1。 窗函数选择切比雪夫型 采样频率为 20000Hz,通带截止频率为 750Hz。
图 滤波器的幅频特性
图 滤波器的相位特性
c.产生滤波器系数和头文件
图 滤波器系数
图 头文件的产生
采用 C 语言算法在 DSP 平台上实现了 FIR 低通数字滤波器,C 语言算法相 比于汇编算法可移植性很强。这里是在 TMS320VC5510DSP 为平台编写的 C 语 言算法, 此算法可以稍加改动用在其他 DSP 芯片上, 而汇编算法则不然。 这种方 法具有以下优点: (a) 程序的入口和出口由 C 语言自动管理,不必手工编写汇编程序实现。 (b) 程序结构清晰,可读性强。 (c) 程序调试方便。由于 C 程序中的变量全部由 C 语言来定义,因此采用 C 源码调试器可以方便地观察 C 语言变量。 (d) 可移植性较强,通用性较好。 具体代码如下: #include"stdio.h" #include"fdacoefs.h" //头文件包含滤波器的系数 #define N 81 //定义滤波器的阶数为 81 阶 #define Length 200 //定义缓冲区数组大小为 200 long yn; int input[Length]; //存放输入数据 int output[Length]; //存放输出数据 void main() { int m,n; int *x; for(n=0;n<Length-1;n++) //循环导入数据 { x=&input[n]; //指针指向每次导入的数据 yn=0; //每做完一次乘累加后,把值赋给 output 数组后,从新归 0 for(m=0;m<N-1;m++) yn+=B[m]*(*(x++)); //做 N 次的乘累加 output[n]=yn; 把值赋给 output 数组 } while(1); //做完滤波后使程序保持在本循环中 } (3)CSS 仿真调试 CCS 是 TI 推出的用于开发其 DSP 芯片的继承开发调试工具, 集编辑、编 译、 链接、 软件仿真、 硬件调试及实时跟踪等功能于一体, 极大地方便了 DSP 程 序的设计与开发, 此外还提供图形显示功能, 方便用户观察特定地址的波形。此 外, 还需向工程中添加 Link. cmd 文件(源码见附录) 。 在 CCSV3.3 中建立工程,把 c 源代码和.cmd 文件导入后,外加 rts. lib 文件, 它是 TI 提供的运行时支持库, 如果是 C 代码写的源程序, 必须要包含该库,该库
y ( n) a k x ( n k )
k 0 N 1
对上式进行Z变换得到FIR滤波器的传递函数为:
H z Y z N 1 k bk z X z i 0
由上式可以看出,H(z)是 z 1 的N-1次多项式,它在z平面内有N-1个零点,同 时在原点处有N-1个重极点。 N阶滤波器通常采用N个延迟单元、 N个加法器与N+1 个乘法器,取图中(a)、(b)两种结构。
切比雪夫逼近理论,这样的多项式是存在的,且是唯一的,并指出了构造这种最 佳一致逼近多项式的方法,就是有名的“交错点组定理”。 切比雪夫逼近理论解决了p(x)的存在性、唯一性和如何构造等问题。 J.H.McClellan、 T.W.Parks、L.R.Rabiner 等人应用切比雪夫逼近理论提出了一
种设计FIR滤波器的计算机辅助算法。 这种算法由于是在一致意义上对 H d e jw 作 最佳逼近, 因而获得了较好的通带和阻带性能,并能准确地指定通带和阻带的边 缘。但它的效率依赖于初始极值频率点的估计,且通带和阻带内波纹数较多,这 是Chebyshev方法的两个主要缺点。
n 0
N 1
H(z)是 z 1 的(N-1)次多项式,它在 z 平面上有(N-1)个零点,原点 z=0 是(N-1)阶重 极点。因此,H(z)永远稳定,它可以在幅度特性随意设计的同时,保证精确、严 格的线性相位。 (2)FIR 滤波器的基本结构 数字滤波是将输入的信号序列,按规定的算法进行处理,从而得到所期望的 输出序列,FIR滤波器的差分方程为:
图 FIR滤波器的一般结构
因为FIR滤波器的单位抽样响应是有限长的,所以它永远是稳定的。另外, 若对 h(n)提出一些约束条件,那么可以很容易地使 H(z)具有线性相位,这在信 号处理的很多领域是非常重要的。FIR滤波器的设计任务,是要决定一个转移函 数H(z),使它的频率响应满足给定的要求。这里所说的要求,除了通带频率 p 、 阻带频率及两个带上的最大和最小衰减 p 和 s 外,很重要的一条是保证H(z)具 有线性相位。 (3)Chebyshev逼近法 窗函数法和频率采样法设计出的滤波器的频率特性都是在不同意义上对所 给理想频率特性 H d e jw 的逼近。由数值逼近理论可知,对某个函数f(x)的逼近 一般有以下三种方法: 插值法(Interpolating Way) 最小平方逼近法(Least Square Approaching Way) 一致逼近法(Consistent Approaching Way) 切比雪夫最佳一致逼近的基本思想是,对于给定区间[a,b]上的连续函数
相关文档
最新文档