精华内容
下载资源
问答
  • 一、模拟滤波器的阶数选择函数 1.函数调用: [N,Wn]=buttord(wp,ws,Rp,Rs,'s') 2.范例: wp=[0.2*pi 0.3*pi];...% 巴特沃斯滤波器设计 [N,Wn]=buttord(wp,ws,Rp,Rs,'s'); % 求巴特沃斯滤波器阶数 其中N是滤波器最小

    一、模拟滤波器的阶数选择函数

    1.函数调用:

    [N,Wn]=buttord(wp,ws,Rp,Rs,'s')
    

    2.范例:

    wp=[0.2*pi 0.3*pi];              % 设置通带频率
    ws=[0.1*pi 0.4*pi];              % 设置阻带频率
    Rp=1; Rs=20;                     % 设置波纹系数
    % 巴特沃斯滤波器设计
    [N,Wn]=buttord(wp,ws,Rp,Rs,'s'); % 求巴特沃斯滤波器阶数
    

    其中N是滤波器最小阶数**(滤波器的阶数是指在滤波器的传递函数中有几个极点),Wn是等效低通滤波器的截止频率**

    二、在MATLAB中设计模拟滤波器的函数

    1.函数调用

    [b,a]=butter(N,Wn,'s');        % 求巴特沃斯滤波器系数
    

    2.范例

    [b,a]=butter(N,Wn,'s');        % 求巴特沃斯滤波器系数
    

    三、滤波器频率分析函数

    1.freqs函数(s表示s域,对模拟滤波器进行分析)

    (1)函数调用:

    在这里插入图片描述

    (2)范例:

    clear all; close all; clc;
    wp=[0.2*pi 0.3*pi];              % 设置通带频率
    ws=[0.1*pi 0.4*pi];              % 设置阻带频率
    Rp=1; Rs=20;                     % 设置波纹系数
    % 巴特沃斯滤波器设计
    [N,Wn]=buttord(wp,ws,Rp,Rs,'s'); % 求巴特沃斯滤波器阶数
    fprintf('巴特沃斯滤波器 N=%4d\n',N) % 显示滤波器阶数
    [bb,ab]=butter(N,Wn,'s');        % 求巴特沃斯滤波器系数
    W=0:0.01:2;                      % 设置模拟频率
    [Hb,wb]=freqs(bb,ab,W);          % 求巴特沃斯滤波器频率响应
    plot(wb/pi,20*log10(abs(Hb)),'b')% 作图
    

    在这里插入图片描述

    展开全文
  • Butterworth (巴特沃斯滤波器设计参考,适合研究滤波器的硬件工程师参考使用
  • 这意味着 信号的模拟频率 fff= 50 (Hz),注意它的单位是Hz 信号的表达式为 y=sin(2πft)=sin(2π∗50t)=sin(100πt)y = sin(2\pi ft)=sin(2\pi *50 t)=sin(100\pi t)y=sin(2πft)=sin(2π∗50t)=sin(100πt) 由于...

    本文是模拟滤波器设计,如果需要了解数字滤波器的内容,可以按顺序看我写的另外两篇博客,如下:

    2.MATLAB实现无限脉冲响应数字滤波器(IIR)

    3.MATLAB实现有限脉冲响应数字滤波器(FIR)

    1. 基础知识介绍

    我们首先明确一个知识(这个非常重要):

    某正弦信号,频率为50Hz
    这意味着 信号的模拟频率 f f f= 50 (Hz),注意它的单位是Hz

    信号的表达式为
    y = s i n ( 2 π f t ) = s i n ( 2 π ∗ 50 t ) = s i n ( 100 π t ) y = sin(2\pi ft)=sin(2\pi *50 t)=sin(100\pi t) y=sin(2πft)=sin(2π50t)=sin(100πt)

    由于信号也可以表示为 y = s i n ( Ω t ) y = sin(\Omega t) y=sin(Ωt)的形式,所以这里
    Ω = 2 π f = 100 π \Omega=2\pi f=100\pi Ω=2πf=100π

    这里的 Ω \Omega Ω模拟角频率它的单位是rad/s

    注意模拟角频率 Ω \Omega Ω模拟频率 f f f的关系 Ω = 2 π f \Omega=2\pi f Ω=2πf

    2. 函数介绍

    首先介绍一些用到的MATLAB函数

    2.1 buttord - 求解滤波器的阶数N和3dB截止频率wc

    [N,wc] = buttord(wp, ws, Rp, As, ‘s’)  
    

    输入参数如下:

    通带边界模拟频率wp、阻带边界模拟频率ws模拟角频率单位是rad/s

    通带最大衰减Rp、阻带最小衰减As单位是dB

    ‘s’指的就是模拟滤波器,设计数字滤波器时就没有’s’这个参数了。

    2.2 butter - 求解N阶滤波器的具体参数B和A,求解完B和A后滤波器就设计完成了。

    [B,A] = butter(N, wc, ‘ftype’, ‘s’)  - 模拟滤波器设计
    

    输入参数如下:

    N - 滤波器阶数

    wc - 3dB截止模拟频率(单位rad/s,N和wc都是用buttord函数计算出来的)

    ftype - 滤波器类型‘’:
    (1)当输入wc为一维向量时:
    默认情况下设计的低通滤波器,设计高通滤波器的话令ftype=high

    (2)当输入wc为二维向量[wcl,wcu]时:
    默认情况下设计的带通滤波器,设计带阻滤波器的话令ftype=stop

    2.3 filter - 滤波函数

    y = filter(B,A,x)
    

    这个就是滤波函数了,

    x是输入的有噪声的信号,

    B,A就是设计好的滤波器参数

    得到的输出y就是滤波后的信号了。

    3. 代码实现:

    (1)低通滤波器:

    例: 设计通带截止频率5kHz,通带衰减2dB,阻带截止频率12kHz,阻带衰减30dB的巴特沃斯低通滤波器

    由题可知,设计的是模拟滤波器,所以用到下面三个函数:

    [N,wc] = buttord(wp, ws, Rp, As, ‘s’)
    [B,A] = butter(N, wc, ‘ftype’, ‘s’)
    y = filter(B,A,x)
    

    划重点 ! ! !

    模拟滤波器的频率都是模拟角频率 Ω \Omega Ω ,它和频率 f f f 的关系
    Ω = 2 π f \Omega = 2\pi f Ω=2πf

    所以这里

    wp = 2 ∗ p i ∗ 5000 2*pi*5000 2pi5000,ws = 2 ∗ p i ∗ 12000 2*pi*12000 2pi12000,Rp = 2, As = 30

    代码如下:

    
    wp = 2 * pi * 5000;
    ws = 2 * pi * 12000;
    Rp = 2;
    As = 30;
    
    [N, wc] = buttord(wp, ws, Rp, As, 's');
    [B, A] = butter(N, wc, 's');
    
    

    上面这些代码就设计好了滤波器

    如果有输入噪声信号x的话,调用y = filter(B,A,x),得到的y就是滤波后的信号了。

    下面是绘图部分

    为了让滤波器的结果得到更形象的表示,我们可以画出来它的幅频特性曲线,代码如下:
    其中,我们使用了freqs这个函数,

    h = freqs(B,A,wk)
    

    它是用来计算当频率为wk时,对应的频率响应h的大小,主要是用来画图的。

    绘图代码如下:

    
    f = 0 : 10 : 14000;%取点,从0-14000,每隔10取一个点
    w = 2 * pi * f;%注意模拟滤波器用的频率都是模拟角频率,要乘上2pi的
     
    Hk = freqs(B,A,w);%对于取的每个点,求该处的频率响应大小
     
    %画图
    figure
    plot(f/1000, 20 * log10(abs(Hk)));%横坐标单位是kHz,纵坐标单位是dB,
    grid on;
    %设置横纵坐标标签
    xlabel('f/kHz');
    ylabel('-A(f)/dB');
    %设置横纵坐标轴范围
    axis([0, 14, -40, 5]);
    
    

    绘图结果如下:

    在这里插入图片描述

    (2)高通滤波器:

    高通滤波器与低通几乎完全一样,只要注意
    [B,A] = butter(N, wc, ‘ftype’, ‘s’)中的 ftype=high

    例: 设计通带截止频率4kHz,通带衰减0.1dB,阻带截止频率1kHz,阻带衰减40dB的巴特沃斯高通滤波器

    代码如下:

    
    wp = 2 * pi * 4000;
    ws = 2 * pi * 1000;
    Rp = 0.1;
    As = 40;
     
    [N, wc] = buttord(wp, ws, Rp, As, 's');
    [B, A] = butter(N, wc,'high', 's');%注意这个'high'
    
    

    高通滤波器设计完成了

    如果有输入噪声信号x的话,调用 y = filter(B,A,x),得到的y就是滤波后的信号了。

    接着我们画出高通滤波器的幅频特性曲线

    
    f = 0 : 10 : 14000;%取点,从0-14000,每隔10取一个点
    w = 2 * pi * f;%注意模拟滤波器用的频率都是模拟角频率,要乘上2pi的
     
    Hk = freqs(B,A,w);%对于取的每个点,求该处的频率响应大小
     
    %画图
    figure
    plot(f/1000, 20 * log10(abs(Hk)));%横坐标单位是kHz,纵坐标单位是dB,
    grid on;
    %设置横纵坐标标签
    xlabel('f/kHz');
    ylabel('-A(f)/dB');
    %设置横纵坐标轴范围
    axis([0, 14, -60, 5]);
    
    

    曲线图如下:

    在这里插入图片描述

    (3)带通滤波器:

    例: 设计巴特沃斯带通滤波器,通带上下边界频率分别为4kHz和7kHz,通带衰减1dB,阻带上下边界频率2kHz和9kHz,阻带衰减20dB。

    滤波器设计代码如下:

    %带通
    wp = 2 * pi * [4000, 7000];
    ws = 2 * pi * [2000,9000];
    Rp = 1;
    As = 20;
     
    [N, wc] = buttord(wp, ws, Rp, As, 's');%此时输入wp和ws都是二维的,输出wc也是两维的
    [B, A] = butter(N, wc,'s');
    

    带通模拟滤波器设计完成了

    如果有输入噪声信号x的话,调用y = filter(B,A,x),得到的y就是滤波后的信号了。

    接着我们画出带通滤波器的幅频特性曲线,如下:

    
    f = 0 : 10 : 14000;%取点,从0-14000,每隔10取一个点
    w = 2 * pi * f;%注意模拟滤波器用的频率都是模拟角频率,要乘上2pi的
     
    Hk = freqs(B,A,w);%对于取的每个点,求该处的频率响应大小
     
    %画图
    figure
    plot(f/1000, 20 * log10(abs(Hk)));%横坐标单位是kHz,纵坐标单位是dB,
    grid on;
    %设置横纵坐标标签
    xlabel('f/kHz');
    ylabel('-A(f)/dB');
    %设置横纵坐标轴范围
    axis([0, 14, -60, 5]);
    
    

    曲线图如下:
    在这里插入图片描述

    (4)带阻滤波器:

    例: 设计巴特沃斯带阻滤波器,通带上下边界频率分别为2kHz和9kHz,通带衰减1dB,阻带上下边界频率4kHz和7kHz,阻带衰减20dB。

    
    %带阻
    wp = 2 * pi * [2000, 9000];
    ws = 2 * pi * [4000,7000];
    Rp = 1;
    As = 20;
     
    [N, wc] = buttord(wp, ws, Rp, As, 's');%此时输入wp和ws都是二维的,输出wc也是两维的
    [B, A] = butter(N, wc,'stop','s');
    
    带阻模拟滤波器设计完成了,如果有输入噪声信号x的话,调用
    y = filter(B,A,x),得到的y就是滤波后的信号了。
    
    

    接着我们画出带阻滤波器的幅频特性曲线,代码如下:

    
    f = 0 : 10 : 14000;%取点,从0-14000,每隔10取一个点
    w = 2 * pi * f;%注意模拟滤波器用的频率都是模拟角频率,要乘上2pi的
     
    Hk = freqs(B,A,w);%对于取的每个点,求该处的频率响应得下
     
     
    %画图
    figure
    plot(f/1000, 20 * log10(abs(Hk)));%横坐标单位是kHz,纵坐标单位是dB,
    grid on;
    %设置横纵坐标标签
    xlabel('f/kHz');
    ylabel('-A(f)/dB');
    %设置横纵坐标轴范围
    axis([0, 14, -100, 5]);
    
    

    结果如下:

    在这里插入图片描述

    展开全文
  • MATLAB实现巴特沃斯数字滤波器

    万次阅读 多人点赞 2019-08-03 10:07:35
    MATLAB实现巴特沃斯数字滤波器 MATLAB实现巴特沃斯数字滤波器 前因:因为要准备保研面试,今年暑假就重新把烂尾的项目捡起来了。 为了提取采集到的脑电信号中有用的部分,想用数字带通滤波器实现,浏览了很多帖子...

    MATLAB实现巴特沃斯数字滤波器

    前因:因为要准备保研面试,今年暑假就重新把烂尾的项目捡起来了。
    为了提取采集到的脑电信号中有用的部分,想用数字带通滤波器实现,浏览了很多帖子。要不是只有代码,没有注释;要不就是只有理论,没有代码。索性自己写一篇,方便回顾。

    1. 用↓观察频谱

    f=fftshift(fft(b));                  %b表示信号值data
    w=linspace(-512/2,512/2,length(b));  %根据奈奎斯特采样定理,512/2为最大频率
    plot(w,abs(f));                      %Hz为单位
    

    • k、Hz等纵坐标如何判断(5.同理)

    2. 频率转化

    Fs=512
    fp=0.5Hz - 50Hz
    fs=0.25Hz - 55Hz

    ///
    *Q:↑为何如此取值
    A:为防止频谱泄露,滤波器并非完全垂直截止,需过渡衰减

    在这里插入图片描述

    回归正题,然后将单位为‘Hz’的模拟频率转化为单位为‘rad’的数字角频率
    基础知识见本连接
    (wp,ws分别为数字滤波器的通带、阻带截止频率的归一化值。要求:0≤wp≤1,0≤ws≤1。
    1表示数字频率pi。)

    Fs=512;
    wp=[0.5*2*pi/Fs,50*2*pi/Fs];                %设置通带数字角频率
    ws=[0.25*2*pi/Fs,55*2*pi/Fs];                %设置阻带数字角频率
    

    再设置参数
    Rp=1; %通带最大衰减
    Rs=30; %阻带最小衰减

    *为何如此取值见 ↓
    在这里插入图片描述

    3. 巴特沃斯滤波器设计

    [N,Wn]=buttord(wp,ws,Rp,Rs,'s');        %求巴特沃斯滤波器阶数N和截止频率Wn
    %无论是高通、带通和带阻滤波器,在设计中最终都等效于一个截止频率为Wn的低通滤波器(我现在也不是很理解为啥是这样,毕竟我也是刚接触滤波器)
    fprintf('巴特沃斯滤波器 N= %4d\n',N);    %显示滤波器阶数
    [bb,ab]=butter(N,Wn,'s');               %求巴特沃斯滤波器系数,即求传输函数的分子和分母的系数向量
    b2=filter(bb,ab,b);                     %filter既能进行IIR滤波又能进行FIR滤波
    
    • 分子分母系数如何排列

    *阶数N越大,变化越剧烈
    *Wn是指低频、高频信号功率降低至 最大值的0.707倍(-3dB)或0.5倍的点(-6dB),即上下限截止频率 ↓
    Wn是指低频、高频信号功率降低一半的点,即上下限截止频率

    4. 观察滤波器频率响应

    W=-600:0.1:600;                             %设置模拟频率
    [Hb,wb]=freqz(bb,ab,W,Fs);                  %求巴特沃斯滤波器频率响应
    plot(wb,20*log10(abs(Hb)),'b');             %作图
    xlabel('Hz');
    ylabel('幅值/dB');
    
    • 所画频谱不正确,未明白fft()和fftshift(fft())的区别

    *值得一提的是
    freqs(b,a,w)是针对模拟滤波器求频率响应,输入信号w的单位为rad/s
    freqz()是针对数字滤波器,当freqz(…,N,Fs)时,输入信号w的单位为fs

    附官方说明

    5. 观察滤波后信号频谱

    f=fft(b2);                            %b2是滤波后信号
    w=linspace(-512/2,512/2,length(b2));  %根据奈奎斯特采样定理,512/2为最大频率
    plot(w,abs(f));
    

    最后
    附上可以参考的实验
    实验

    展开全文
  • 提出了使用 MATLAB 设计巴特沃斯和切比雪夫滤波器的分析方法。 还计算了滤波器的阶数、传递函数以及各个滤波器的电容器和电感器的值。
  • C语言实现巴特沃斯IIR滤波器

    千次阅读 2014-06-09 15:00:55
    1.模拟滤波器设计  1.1巴特沃斯滤波器的次数  根据给定的参数设计模拟滤波器,然后进行变数变换,求取数字滤波器的方法,称为滤波器的间接设计。做为数字滤波器的设计基础的模拟滤波器,称之为原型滤波器。...
    
    1.模拟滤波器的设计

          1.1巴特沃斯滤波器的次数

            根据给定的参数设计模拟滤波器,然后进行变数变换,求取数字滤波器的方法,称为滤波器的间接设计。做为数字滤波器的设计基础的模拟滤波器,称之为原型滤波器。这里,我们首先介绍的是最简单最基础的原型滤波器,巴特沃斯低通滤波器。由于IIR滤波器不具有线性相位特性,因此不必考虑相位特性,直接考虑其振幅特性。

           在这里,N是滤波器的次数,Ωc是截止频率。从上式的振幅特性可以看出,这个是单调递减的函数,其振幅特性是不存在纹波的。设计的时候,一般需要先计算跟所需要设计参数相符合的次数N。首先,就需要先由阻带频率,计算出阻带衰减
    将巴特沃斯低通滤波器的振幅特性,直接带入上式,则有

    最后,可以解得次数N为

    当然,这里的N只能为正数,因此,若结果为小数,则舍弃小数,向上取整。

          1.2巴特沃斯滤波器的传递函数

             巴特沃斯低通滤波器的传递函数,可由其振幅特性的分母多项式求得。其分母多项式

    根据S解开,可以得到极点。这里,为了方便处理,我们分为两种情况去解这个方程。当N为偶数的时候,

    这里,使用了欧拉公式。同样的,当N为奇数的时候,


    同样的,这里也使用了欧拉公式。归纳以上,极点的解为


    上式所求得的极点,是在s平面内,在半径为Ωc的圆上等间距的点,其数量为2N个。为了使得其IIR滤波器稳定,那么,只能选取极点在S平面左半平面的点。选定了稳定的极点之后,其模拟滤波器的传递函数就可由下式求得。


           1.3巴特沃斯滤波器的实现(C语言)

              首先,是次数的计算。次数的计算,我们可以由下式求得。
             
    其对应的C语言程序为
    1. N = Ceil(0.5*( log10 ( pow (10, Stopband_attenuation/10) - 1) /   
    2.             log10 (Stopband/Cotoff) ));  

             然后是极点的选择,这里由于涉及到复数的操作,我们就声明一个复数结构体就可以了。最重要的是,极点的计算含有自然指数函数,这点对于计算机来讲,不是太方便,所以,我们将其替换为三角函数,


    这样的话,实部与虚部就还可以分开来计算。其代码实现为

    1. typedef struct   
    2. {  
    3.     double Real_part;  
    4.     double Imag_Part;  
    5. } COMPLEX;  
    6.   
    7.   
    8. COMPLEX poles[N];  
    9.   
    10. for(k = 0;k <= ((2*N)-1) ; k++)  
    11. {  
    12.     if(Cotoff*cos((k+dk)*(pi/N)) < 0)  
    13.     {  
    14.         poles[count].Real_part = -Cotoff*cos((k+dk)*(pi/N));  
    15.       poles[count].Imag_Part= -Cotoff*sin((k+dk)*(pi/N));        
    16.         count++;  
    17.         if (count == N) break;  
    18.     }  
    19. }   

           计算出稳定的极点之后,就可以进行传递函数的计算了。传递的函数的计算,就像下式一样


    这里,为了得到模拟滤波器的系数,需要将分母乘开。很显然,这里的极点不一定是整数,或者来说,这里的乘开需要做复数运算。其复数的乘法代码如下,

    1. int Complex_Multiple(COMPLEX a,COMPLEX b,  
    2.                  double *Res_Real,double *Res_Imag)  
    3.       
    4. {  
    5.        *(Res_Real) =  (a.Real_part)*(b.Real_part) - (a.Imag_Part)*(b.Imag_Part);  
    6.        *(Res_Imag)=  (a.Imag_Part)*(b.Real_part) + (a.Real_part)*(b.Imag_Part);      
    7.      return (int)1;   
    8. }  
    有了乘法代码之后,我们现在简单的情况下,看看其如何计算其滤波器系数。我们做如下假设
    这个时候,其传递函数为

    将其乘开,其大致的关系就像下图所示一样。


    计算的关系一目了然,这样的话,实现就简单多了。高阶的情况下也一样,重复这种计算就可以了。其代码为

    1.  Res[0].Real_part = poles[0].Real_part;   
    2.  Res[0].Imag_Part= poles[0].Imag_Part;  
    3.  Res[1].Real_part = 1;   
    4.  Res[1].Imag_Part= 0;  
    5.   
    6. for(count_1 = 0;count_1 < N-1;count_1++)  
    7. {  
    8.   for(count = 0;count <= count_1 + 2;count++)  
    9.   {  
    10.       if(0 == count)  
    11.   {  
    12.               Complex_Multiple(Res[count], poles[count_1+1],  
    13.                    &(Res_Save[count].Real_part),  
    14.                    &(Res_Save[count].Imag_Part));  
    15.       }  
    16.       else if((count_1 + 2) == count)  
    17.       {  
    18.             Res_Save[count].Real_part  += Res[count - 1].Real_part;  
    19.     Res_Save[count].Imag_Part += Res[count - 1].Imag_Part;  
    20.       }         
    21.    else   
    22.    {  
    23.               Complex_Multiple(Res[count], poles[count_1+1],  
    24.                    &(Res_Save[count].Real_part),  
    25.                    &(Res_Save[count].Imag_Part));                 
    26. 1     Res_Save[count].Real_part  += Res[count - 1].Real_part;  
    27.      Res_Save[count].Imag_Part += Res[count - 1].Imag_Part;  
    28.   }  
    29.   }  
    30.    *(b+N) = *(a+N);  
    到此,我们就可以得到一个模拟滤波器巴特沃斯低通滤波器了。

    2.双1次z变换

          2.1双1次z变换的原理

            我们为了将模拟滤波器转换为数字滤波器的,可以用的方法很多。这里着重说说双1次z变换。我们希望通过双1次z变换,建立一个s平面到z平面的映射关系,将模拟滤波器转换为数字滤波器。
            和之前的例子一样,我们假设有如下模拟滤波器的传递函数。

    将其做拉普拉斯逆变换,可得到其时间域内的连续微分方程式,

    其中,x(t)表示输入,y(t)表示输出。然后我们需要将其离散化,假设其采样周期是T,用差分方程去近似的替代微分方程,可以得到下面结果

    然后使用z变换,再将其化简。可得到如下结果

    从而,我们可以得到了s平面到z平面的映射关系,即

    由于所有的高阶系统都可以视为一阶系统的并联,所以,这个映射关系在高阶系统中,也是成立的。

    然后,将关系式

    带入上式,可得

    到这里,我们可以就可以得到Ω与ω的对应关系了。


             这里的Ω与ω的对应关系很重要。我们最终的目的设计的是数字滤波器,所以,设计时候给的参数必定是数字滤波器的指标。而我们通过间接设计设计IIR滤波器时候,首先是要设计模拟滤波器,再通过变换,得到数字滤波器。那么,我们首先需要做的,就是将数字滤波器的指标,转换为模拟滤波器的指标,基于这个指标去设计模拟滤波器。另外,这里的采样时间T的取值很随意,为了方便计算,一般取1s就可以。

           2.2双1次z变换的实现(C语言)

             我们设计好的巴特沃斯低通滤波器的传递函数如下所示。
         
    我们将其进行双1次z变换,我们可以得到如下式子

    可以看出,我们还是需要将式子乘开,进行合并同类项,这个跟之前说的算法相差不大。其代码为。
    1. for(Count = 0;Count<=N;Count++)  
    2.     {         
    3.            for(Count_Z = 0;Count_Z <= N;Count_Z++)  
    4.             {  
    5.                  Res[Count_Z] = 0;  
    6.              Res_Save[Count_Z] = 0;    
    7.             }  
    8.                 Res_Save [0] = 1;  
    9.            for(Count_1 = 0; Count_1 < N-Count;Count_1++)  
    10.             {  
    11.               for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)  
    12.                 {  
    13.                     if(Count_2 == 0)  Res[Count_2] += Res_Save[Count_2];      
    14.                   else if((Count_2 == (Count_1+1))&&(Count_1 != 0))    
    15.                             Res[Count_2] += -Res_Save[Count_2 - 1];   
    16.                   else  Res[Count_2] += Res_Save[Count_2] - Res_Save[Count_2 - 1];  
    17.               for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    18.                  {  
    19.                       Res_Save[Count_Z]  =  Res[Count_Z] ;  
    20.                      Res[Count_Z]  = 0;  
    21.                  }            
    22.             }  
    23.         for(Count_1 = (N-Count); Count_1 < N;Count_1++)  
    24.             {  
    25.                         for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)  
    26.                 {  
    27.                      if(Count_2 == 0)  Res[Count_2] += Res_Save[Count_2];     
    28.                  else if((Count_2 == (Count_1+1))&&(Count_1 != 0))    
    29.                               Res[Count_2] += Res_Save[Count_2 - 1];  
    30.                  else    
    31.                        Res[Count_2] += Res_Save[Count_2] + Res_Save[Count_2 - 1];     
    32.              }  
    33.                   for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    34.                   {  
    35.                        Res_Save[Count_Z]  =  Res[Count_Z] ;  
    36.                    Res[Count_Z]  = 0;  
    37.                   }  
    38.             }  
    39.             for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    40.         {  
    41.                     *(az+Count_Z) +=  pow(2,N-Count) * (*(as+Count)) *  
    42.                        Res_Save[Count_Z];  
    43.                 *(bz+Count_Z) +=  (*(bs+Count)) * Res_Save[Count_Z];               
    44.          }    
    45.     }  
    到此,我们就已经实现了一个数字滤波器。


    3.IIR滤波器的间接设计代码(C语言)

    1. #include <stdio.h>  
    2. #include <math.h>  
    3. #include <malloc.h>  
    4. #include <string.h>  
    5.   
    6.   
    7. #define     pi     ((double)3.1415926)  
    8.   
    9.   
    10. struct DESIGN_SPECIFICATION  
    11. {  
    12.     double Cotoff;     
    13.     double Stopband;  
    14.     double Stopband_attenuation;  
    15. };  
    16.   
    17. typedef struct   
    18. {  
    19.     double Real_part;  
    20.     double Imag_Part;  
    21. } COMPLEX;  
    22.   
    23.   
    24.   
    25. int Ceil(double input)  
    26. {  
    27.      if(input != (int)input) return ((int)input) +1;  
    28.      else return ((int)input);   
    29. }  
    30.   
    31.   
    32. int Complex_Multiple(COMPLEX a,COMPLEX b  
    33.                                      ,double *Res_Real,double *Res_Imag)  
    34.       
    35. {  
    36.        *(Res_Real) =  (a.Real_part)*(b.Real_part) - (a.Imag_Part)*(b.Imag_Part);  
    37.        *(Res_Imag)=  (a.Imag_Part)*(b.Real_part) + (a.Real_part)*(b.Imag_Part);      
    38.      return (int)1;   
    39. }  
    40.   
    41.   
    42. int Buttord(double Cotoff,  
    43.                  double Stopband,  
    44.                  double Stopband_attenuation)  
    45. {  
    46.    int N;  
    47.   
    48.    printf("Wc =  %lf  [rad/sec] \n" ,Cotoff);  
    49.    printf("Ws =  %lf  [rad/sec] \n" ,Stopband);  
    50.    printf("As  =  %lf  [dB] \n" ,Stopband_attenuation);  
    51.    printf("--------------------------------------------------------\n" );  
    52.        
    53.    N = Ceil(0.5*( log10 ( pow (10, Stopband_attenuation/10) - 1) /   
    54.                     log10 (Stopband/Cotoff) ));  
    55.      
    56.      
    57.    return (int)N;  
    58. }  
    59.   
    60.   
    61. int Butter(int N, double Cotoff,  
    62.                double *a,  
    63.                double *b)  
    64. {  
    65.     double dk = 0;  
    66.     int k = 0;  
    67.     int count = 0,count_1 = 0;  
    68.     COMPLEX poles[N];  
    69.     COMPLEX Res[N+1],Res_Save[N+1];  
    70.   
    71.     if((N%2) == 0) dk = 0.5;  
    72.     else dk = 0;  
    73.   
    74.     for(k = 0;k <= ((2*N)-1) ; k++)  
    75.     {  
    76.          if(Cotoff*cos((k+dk)*(pi/N)) < 0)  
    77.          {  
    78.                poles[count].Real_part = -Cotoff*cos((k+dk)*(pi/N));  
    79.           poles[count].Imag_Part= -Cotoff*sin((k+dk)*(pi/N));        
    80.               count++;  
    81.             if (count == N) break;  
    82.          }  
    83.     }   
    84.   
    85.      printf("Pk =   \n" );     
    86.      for(count = 0;count < N ;count++)  
    87.      {  
    88.            printf("(%lf) + (%lf i) \n" ,-poles[count].Real_part  
    89.                                       ,-poles[count].Imag_Part);  
    90.      }  
    91.      printf("--------------------------------------------------------\n" );  
    92.        
    93.      Res[0].Real_part = poles[0].Real_part;   
    94.      Res[0].Imag_Part= poles[0].Imag_Part;  
    95.   
    96.      Res[1].Real_part = 1;   
    97.      Res[1].Imag_Part= 0;  
    98.   
    99.     for(count_1 = 0;count_1 < N-1;count_1++)  
    100.     {  
    101.          for(count = 0;count <= count_1 + 2;count++)  
    102.          {  
    103.               if(0 == count)  
    104.            {  
    105.                     Complex_Multiple(Res[count], poles[count_1+1],  
    106.                                    &(Res_Save[count].Real_part),  
    107.                                    &(Res_Save[count].Imag_Part));  
    108.                //printf( "Res_Save : (%lf) + (%lf i) \n" ,Res_Save[0].Real_part,Res_Save[0].Imag_Part);  
    109.               }  
    110.   
    111.               else if((count_1 + 2) == count)  
    112.               {  
    113.                      Res_Save[count].Real_part  += Res[count - 1].Real_part;  
    114.                 Res_Save[count].Imag_Part += Res[count - 1].Imag_Part;    
    115.               }         
    116.             else   
    117.             {  
    118.                      Complex_Multiple(Res[count], poles[count_1+1],  
    119.                                    &(Res_Save[count].Real_part),  
    120.                                    &(Res_Save[count].Imag_Part));  
    121.   
    122.                        //printf( "Res          : (%lf) + (%lf i) \n" ,Res[count - 1].Real_part,Res[count - 1].Imag_Part);  
    123.                 //printf( "Res_Save : (%lf) + (%lf i) \n" ,Res_Save[count].Real_part,Res_Save[count].Imag_Part);  
    124.                   
    125.                 Res_Save[count].Real_part  += Res[count - 1].Real_part;  
    126.                 Res_Save[count].Imag_Part += Res[count - 1].Imag_Part;  
    127.               
    128.                 //printf( "Res_Save : (%lf) + (%lf i) \n" ,Res_Save[count].Real_part,Res_Save[count].Imag_Part);  
    129.                   
    130.             }  
    131.             //printf("There \n" );  
    132.          }  
    133.   
    134.          for(count = 0;count <= N;count++)  
    135.          {  
    136.                Res[count].Real_part = Res_Save[count].Real_part;   
    137.                  Res[count].Imag_Part= Res_Save[count].Imag_Part;  
    138.                    
    139.             *(a + N - count) = Res[count].Real_part;  
    140.          }  
    141.            
    142.          //printf("There!! \n" );  
    143.            
    144.         }  
    145.   
    146.      *(b+N) = *(a+N);  
    147.   
    148.      //------------------------display---------------------------------//  
    149.      printf("bs =  [" );     
    150.      for(count = 0;count <= N ;count++)  
    151.      {  
    152.            printf("%lf ", *(b+count));  
    153.      }  
    154.      printf(" ] \n" );  
    155.   
    156.      printf("as =  [" );     
    157.      for(count = 0;count <= N ;count++)  
    158.      {  
    159.            printf("%lf ", *(a+count));  
    160.      }  
    161.      printf(" ] \n" );  
    162.   
    163.      printf("--------------------------------------------------------\n" );  
    164.   
    165.      return (int) 1;  
    166. }  
    167.   
    168.   
    169. int Bilinear(int N,   
    170.                  double *as,double *bs,  
    171.                  double *az,double *bz)  
    172. {  
    173.       int Count = 0,Count_1 = 0,Count_2 = 0,Count_Z = 0;  
    174.       double Res[N+1];  
    175.     double Res_Save[N+1];   
    176.   
    177.         for(Count_Z = 0;Count_Z <= N;Count_Z++)  
    178.     {  
    179.                  *(az+Count_Z)  = 0;  
    180.             *(bz+Count_Z)  = 0;  
    181.     }  
    182.   
    183.       
    184.     for(Count = 0;Count<=N;Count++)  
    185.     {         
    186.           for(Count_Z = 0;Count_Z <= N;Count_Z++)  
    187.             {  
    188.                  Res[Count_Z] = 0;  
    189.              Res_Save[Count_Z] = 0;    
    190.             }  
    191.              Res_Save [0] = 1;  
    192.       
    193.           for(Count_1 = 0; Count_1 < N-Count;Count_1++)  
    194.             {  
    195.             for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)  
    196.                 {  
    197.                      if(Count_2 == 0)    
    198.                  {  
    199.                        Res[Count_2] += Res_Save[Count_2];  
    200.                      //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    201.                  }    
    202.   
    203.                  else if((Count_2 == (Count_1+1))&&(Count_1 != 0))    
    204.                  {  
    205.                        Res[Count_2] += -Res_Save[Count_2 - 1];     
    206.                               //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    207.                  }   
    208.   
    209.                  else    
    210.                  {  
    211.                        Res[Count_2] += Res_Save[Count_2] - Res_Save[Count_2 - 1];  
    212.                     //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    213.                  }                 
    214.             }  
    215.   
    216.                     //printf( "Res : ");  
    217.               for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    218.               {  
    219.                      Res_Save[Count_Z]  =  Res[Count_Z] ;  
    220.                    Res[Count_Z]  = 0;  
    221.                 //printf( "[%d]  %lf  " ,Count_Z, Res_Save[Count_Z]);       
    222.               }  
    223.               //printf(" \n" );  
    224.               
    225.             }  
    226.   
    227.         for(Count_1 = (N-Count); Count_1 < N;Count_1++)  
    228.             {  
    229.                     for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)  
    230.                 {  
    231.                      if(Count_2 == 0)    
    232.                  {  
    233.                        Res[Count_2] += Res_Save[Count_2];  
    234.                      //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    235.                  }    
    236.   
    237.                  else if((Count_2 == (Count_1+1))&&(Count_1 != 0))    
    238.                  {  
    239.                        Res[Count_2] += Res_Save[Count_2 - 1];  
    240.                               //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    241.                   }   
    242.   
    243.                  else    
    244.                  {  
    245.                        Res[Count_2] += Res_Save[Count_2] + Res_Save[Count_2 - 1];  
    246.                      //printf( "Res[%d] %lf  \n" , Count_2 ,Res[Count_2]);  
    247.                  }                 
    248.             }  
    249.   
    250.                    //   printf( "Res : ");  
    251.               for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    252.               {  
    253.                      Res_Save[Count_Z]  =  Res[Count_Z] ;  
    254.                    Res[Count_Z]  = 0;  
    255.                 //printf( "[%d]  %lf  " ,Count_Z, Res_Save[Count_Z]);       
    256.               }  
    257.                //printf(" \n" );  
    258.             }  
    259.   
    260.   
    261.              //printf( "Res : ");  
    262.         for(Count_Z = 0;Count_Z<= N;Count_Z++)  
    263.         {  
    264.                     *(az+Count_Z) +=  pow(2,N-Count)  *  (*(as+Count)) * Res_Save[Count_Z];  
    265.              *(bz+Count_Z) +=  (*(bs+Count)) * Res_Save[Count_Z];         
    266.                      //printf( "  %lf  " ,*(bz+Count_Z));           
    267.          }    
    268.          //printf(" \n" );  
    269.   
    270.     }  
    271.   
    272.   
    273.         
    274.      for(Count_Z = N;Count_Z >= 0;Count_Z--)  
    275.      {  
    276.           *(bz+Count_Z) =  (*(bz+Count_Z))/(*(az+0));  
    277.           *(az+Count_Z) =  (*(az+Count_Z))/(*(az+0));  
    278.      }  
    279.        
    280.   
    281.     //------------------------display---------------------------------//  
    282.       printf("bz =  [" );     
    283.       for(Count_Z= 0;Count_Z <= N ;Count_Z++)  
    284.       {  
    285.            printf("%lf ", *(bz+Count_Z));  
    286.       }  
    287.       printf(" ] \n" );  
    288.       printf("az =  [" );     
    289.       for(Count_Z= 0;Count_Z <= N ;Count_Z++)  
    290.       {  
    291.            printf("%lf ", *(az+Count_Z));  
    292.       }  
    293.       printf(" ] \n" );  
    294.       printf("--------------------------------------------------------\n" );  
    295.   
    296.       
    297.   
    298.      return (int) 1;  
    299. }  
    300.   
    301.   
    302.   
    303.   
    304.   
    305. int main(void)  
    306. {  
    307.      int count;  
    308.   
    309.      struct DESIGN_SPECIFICATION IIR_Filter;  
    310.   
    311.      IIR_Filter.Cotoff      = (double)(pi/2);         //[red]  
    312.      IIR_Filter.Stopband = (double)((pi*3)/4);   //[red]  
    313.      IIR_Filter.Stopband_attenuation = 30;        //[dB]  
    314.     
    315.      int N;  
    316.   
    317.      IIR_Filter.Cotoff = 2 * tan((IIR_Filter.Cotoff)/2);            //[red/sec]  
    318.      IIR_Filter.Stopband = 2 * tan((IIR_Filter.Stopband)/2);   //[red/sec]  
    319.   
    320.      N = Buttord(IIR_Filter.Cotoff,  
    321.                   IIR_Filter.Stopband,  
    322.                   IIR_Filter.Stopband_attenuation);  
    323.      printf("N:  %d  \n" ,N);  
    324.      printf("--------------------------------------------------------\n" );  
    325.   
    326.      double as[N+1] , bs[N+1];  
    327.      Butter(N,   
    328.                 IIR_Filter.Cotoff,  
    329.              as,  
    330.              bs);   
    331.   
    332.      double az[N+1] , bz[N+1];  
    333.        
    334.      Bilinear(N,   
    335.                as,bs,  
    336.                az,bz);  
    337.   
    338.      printf("Finish \n" );  
    339.      return (int)0;  
    340. }  


    3.间接设计实现的IIR滤波器的性能

           3.1设计指标

                 

            3.2程序执行结果

               使用上述程序,gcc编译通过,执行结果如下。

           其频率响应如下所示。

    from:http://blog.csdn.net/thnh169/

    展开全文
  • 滤波器设计、低通滤波器、巴特沃斯滤波器,滤波器设计、低通滤波器、巴特沃斯滤波器
  • 巴特沃斯滤波器设计

    2021-07-17 18:12:16
    巴特沃斯滤波器振幅平方函数为 式中,N为整数,称为滤波器的阶数,N越大,通带和阻带的近似性越好,过渡带也越...例 产生一个 20阶低通模拟滤波器原型,表示为零极点增益形式,并绘制频率特性图。 程序如下: clear all; [Z,P
  • 基于Matlab巴特沃斯低通滤波器的设计谢继杨(成都理工大学工程技术学院,四川乐山,614000)摘要:现如今已经有相当成熟的技术去模拟滤波器,人们为了更加深入的理解巴特沃斯滤波器,于是巴特沃斯模拟滤波器便基于...
  • 什么是巴特沃斯滤波器巴特沃斯滤波器是电子滤波器的一种。巴特沃斯滤波器的特点是通频带的频率响应曲线最平滑。这种滤波器最先由英国工程师斯替芬·巴特沃斯(StephenButterworth)在1930年发表在英国《无线电工程》...
  • 数字IIR带阻滤波器的设计 基于巴特沃斯法 1 数字带阻IIR滤波器设计 IIR数字滤波器在很多领域中有着广阔的应用与FIR数字滤波器相比,它可以用较低的阶数获得高选择性,所用存储单元少,经济而效率高,在相同门级规模和...
  • 该程序用于模拟滤波器设计。 该程序设计一个滤波器,计算滤波器阶数,绘制脉冲和阶跃响应,并计算传递函数。 对于巴特沃斯和切比雪夫近似: 示例运行: >> 过滤器 输入您将使用的近似方法输入 (b) 用于巴特沃斯...
  • 模拟滤波器设计matlab代码,低通、高通、带通、带阻,巴特沃斯滤波器
  • 浅谈五阶巴特沃斯低高通滤波器归一化设计方法 注:滤波器由滤波节构成,一个滤波器可能只有一个滤波节,也可以由多个滤波节构成。以下示例为10Hz~500Hz的带通滤波器(由一个五阶巴特沃斯低通滤波器和一个五阶...
  • MATLAB实现巴特沃斯数字滤波器前因:因为要准备保研面试,今年暑假就重新把烂尾的项目捡起来了。为了提取采集到的脑电信号中有用的部分,想用数字带通滤波器实现,浏览了很多帖子。要不是只有代码,没有注释;要不...
  • 巴特沃斯模拟滤波器2.切比雪夫Ⅰ型滤波器3. 切比雪夫Ⅱ型滤波器4.椭圆滤波器5.模拟域频率变换(1)模拟低通到高通变换(2)模拟低通到带通变换(3)模拟低通到带阻变换6.补充函数三、例题:四、作业:更多相关文章点...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 857
精华内容 342
关键字:

巴特沃斯模拟滤波器设计