程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

巴特沃斯(Butterworth)滤波器的设计和幅频特性曲线绘制

发布于2021-12-18 22:19     阅读(1343)     评论(0)     点赞(17)     收藏(3)


大佬的一些文章
设计滤波器的参考链接
绘制伯德图的源码参考链接

一、设计Butterworth滤波器

设计滤波器,其实就是设计传递函数,butterworth滤波器的传递函数如下:
在这里插入图片描述
其中的归一化后的系数如下:
(所谓归一化,就是只按照阶数来定系数,不考虑截至频率)
在这里插入图片描述

反归一化过程(考虑截止频率):将s用以下公式代替
在这里插入图片描述
就得到考虑了阶数以及截至频率的Butterworth滤波器的传递函数。

1.1 利用matlab获取滤波器的归一化系数

通过改变下面公式的N值(阶数),可以得到任意阶的归一化系数,(上面只给出了10阶的,你可以对比看看对不对)。

clc;clear
N = 10;%阶数
wc = 1;%截至频率设置为1rad/s,这样相当于归一化
[B,A]= butter(N,wc,'s')  %代入N和wn设计低通巴特沃斯模拟滤波器
B=B./B(N);
A=A./B(N);

1.2 设计低通Butterworth滤波器

 %% butterworth滤波器的归一化系数,共7阶
    coff=[1 1 0 0 0 0 0 0;
          1 sqrt(2) 1 0 0 0 0 0;
          1 2 2 1 0 0 0 0;
          1 2.6131 3.4142 2.6131 1 0 0 0;
          1 3.2361 5.2361 5.2361 3.2361 1 0 0;
          1 3.8637 7.4641 9.1416 7.4641 3.8637 1 0;
          1 4.4940 10.0978 14.5918 14.5918 10.0978 4.4940 1];
    N=4;%滤波器的阶数
    wc=90;%单位Hz
    wc=2*pi*wc;%转换为rad/s
    
    num1=[0 0 0 0 1];	%分子系数
    for i=1:(N+1)
        den1(i)=coff(N,i)*(1/wc)^(N-i+1);%分母系数
    end
    
    %整理系数
    num1=num1/den1(1);
    den1=den1/den1(1);

1.3 设计高通Butterworth滤波器

高低通的区别,仅仅只是分子项的区别。
对于低通,分子项为1;——以5阶为例为[0 0 0 0 1]
对于高通,分子项为s^n;——以5阶为例为[1 0 0 0 0]

 %% butterworth滤波器的归一化系数,共7阶
    coff=[1 1 0 0 0 0 0 0;
          1 sqrt(2) 1 0 0 0 0 0;
          1 2 2 1 0 0 0 0;
          1 2.6131 3.4142 2.6131 1 0 0 0;
          1 3.2361 5.2361 5.2361 3.2361 1 0 0;
          1 3.8637 7.4641 9.1416 7.4641 3.8637 1 0;
          1 4.4940 10.0978 14.5918 14.5918 10.0978 4.4940 1];
    N=4;%滤波器的阶数
    wc=90;%单位Hz
    wc=2*pi*wc;%转换为rad/s
    
    num1=[1 0 0 0 0];	%分子系数
    for i=1:(N+1)
        den1(i)=coff(N,i)*(1/wc)^(N-i+1);%分母系数
    end
    
    %整理系数
    num1=num1/den1(1);
    den1=den1/den1(1);

二、绘制伯德图

头文件如下:

#ifndef BODE_H
#define BODE_H
/******************************************************************************
* 文件       :    bode.h
* 作者       :     dhs 746769845@qq.com
* 版本       :    V1.0
* 日期       :    2020-7-31
* 描述       :    给定传递函数绘制,计算对应的波特图坐标的数据(幅值、相角)
*
******************************************************************************/
#include <complex>
#include <cmath>
using namespace std;
 
#define PI 3.1415926535
/*传递函数结构体*/
struct TransferFunctiona
{
   double num[10]; //传递函数分子项
   double den[10]; //传递函数分母项
   char  n;       //分子个数
   char  d;       //分母个数
};
/*幅值、相角结构体*/
struct BodeNum
{
   double mag;      //幅值 db
   double phase;    //相角 度(角度)
};
/*频率、角频率结构体*/
struct fre
{
   double f;       //频率 Hz
   double w;       //角频率 rad/s
};
class Bode
{
public:
   Bode(struct TransferFunction TF);  //传入传递函数
   ~Bode();
   struct BodeNum *compute();         //完成计算
   struct fre *logspace(int start, int stop, int num=50, int base=10.0);
   int getWlen(){return _wlen;}      //获取数组长度
 
private:
   struct TransferFunction _TF;      //传递函数
   double *_w;                        //频率指针
   int _wlen;                        //频率长度
   struct fre *freData;              //频率、角频率
   struct BodeNum *BodeData;         //幅值、相角
};
 
#endif // BODE_H

cpp文件如下:

 
/******************************************************************************
* 文件       :    bode.h
* 作者       :     dhs 746769845@qq.com
* 版本       :    V1.0
* 日期       :    2020-7-31
* 描述       :    给定传递函数绘制,计算对应的波特图坐标的数据(幅值、相角)
*
******************************************************************************/
#include "bode.h"
 
 
/*******************************************************************************
* 函 数 名         : Bode
* 函数功能         : bode类,构造函数
* 输入参数         : TF          --> 传入传递函数
* 返 回 值         : 无
*******************************************************************************/
Bode::Bode(struct TransferFunction TF)
   :_TF(TF)
{
   freData  = 0;
   BodeData = 0;
}
/*******************************************************************************
* 函 数 名         : compute()
* 函数功能         : bode图数据计算
* 输入参数         : 无
* 返 回 值         : bode图计算后的数据(数组指针)
*******************************************************************************/
struct BodeNum *Bode::compute()
{
   int i=0;
   int j=0;
   complex<double> ds,ms,s,j1;
   if(freData ==0)
   {
       return 0;
   }
   ds=ms={0,0};
   j1={0,1};                //虚数单位
   for (i=0; i<_wlen; i++)
   {
       s=j1*freData[i].w; //传递函数中的 s用jw代入
       ms ={0,0};         //保存分子项
       ds ={0,0};         //保存分母项
       for (j=0; j<_TF.n; j++)
       {
           ms= ms * s + _TF.num[j];
       }
       for (j=0; j<_TF.d; j++)
       {
           ds= ds * s + _TF.den[j];
       }
       s = ms/ds;
       BodeData[i].mag = 20.0 * log10(abs(s));       //20倍 log10幅度值
       BodeData[i].phase = atan2(s.imag(),s.real()) * 180.0 / PI;  //相角值
   }
   return BodeData;
}
/*******************************************************************************
* 函 数 名         : logspace
* 函数功能         : 生成频率
* 输入参数         : start-->对数开始的冥
*                   stop -->对数结束的冥
*                   num  --> 生成频率的个数 默认50
*                   base --> 对数的底  默认为10
*                  例:logspace(-2, 5, 200, 10)  //表示从0.01Hz~0.1MHz按照10倍频的间距 生成200个频率
* 返 回 值         : 返回生成的频率(数组指针)
*******************************************************************************/
struct fre *Bode::logspace(int start, int stop, int num, int base)
{
   double step=0;
   int i =0;
   _wlen = num;
   freData  = new struct fre[num];
   BodeData =new struct BodeNum[num];
   step =(stop-start)/(num-1.0);
   for(i=0;i<num; i++)
   {
       freData[i].f=pow(base, start+step*i);
       freData[i].w=freData[i].f*2*PI;
   }
 
   return freData;
 
}
/*******************************************************************************
* 函 数 名         : ~Bode
* 函数功能         : 析构
* 输入参数         :
* 返 回 值         :
*******************************************************************************/
Bode::~Bode()
{
   delete BodeData;
   delete freData;
 
}
 


所属网站分类: 技术文章 > 博客

作者:php程序员

链接:http://www.phpheidong.com/blog/article/242526/0a464674bc73cf126dc8/

来源:php黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

17 0
收藏该文
已收藏

评论内容:(最多支持255个字符)