陷波器的离散化及仿真验证

2023-11-04

一、陷波器在连续域的传递函数

1、最基本的陷波器传函

\frac{y(s)}{x(s)}=\frac{s^2+w_0^2}{s^2+2*w_0*\zeta *s+w_0^2}                             (1)

其中,wo​是所谓“中心频率”,也就是你想要“陷掉”的频率。而 ζ 则是“陷阱”的宽度。

根据公式可以发现,当输入信号频率很小(s=0)或者很大( s=+∞)的时候,上面式子的值是1;当输入信号频率刚好等于 s=jωo的时候,分子是0,所以增益变成0,那这个频率的信号当然就全都被衰减掉了。

 由上图可见,ζ越大,则弦波带宽越宽,但弦波频率处的衰减越小。

2、三参数陷波器传函

\frac{y(s)}{x(s)}=\frac{s^2+2*\zeta _2*w_o*s+w_0^2}{s^2+2*\zeta_1*w_0*s+w_0^2}                     (2)

其中,ωo是陷波频率(即凹陷的中心频率),ζ1和ζ2是陷波系数

陷波滤波器重点关注的参数一般有三个:

(1)陷波频率(ωo rad/s可转换Hz)

(2)陷波深度(depth为衰减倍数)

        例如对于100Hz频率处的衰减深度是100,那经过该滤波器后,幅值衰减100倍。

(3)陷波宽度(△f单位Hz)

        即中心频率两侧,幅值衰减-3dB时,对应的两个频率的差值。

 ζ1和ζ2与陷波深度depth和陷波宽度△f(Hz)的关系表示如下:

 

二、陷波器传函在MATLAB中的表达及其离散化

1、以最基本的陷波器传函为例

a、MATLAB中编写如下m文件:

syms w0  s Ts z zeta                   % 定义符号变量
G1 =(s^2+w0^2)/(s^2+2*w0*zeta*s+w0^2)  %传递函数
sys_s2c = 2*(z-1)/Ts/(z+1);
G2 = subs(G1,s,sys_s2c)                %离散化  tustin变换
G3 = collect(G2,z)                     % 将表达式G2中的以z为变量合并相同次幂;

得到连续域和Z域的传递函数如下:

G1 =(s^2 + w0^2)/(s^2 + 2*zeta*s*w0 + w0^2)


G2 =(w0^2 + (2*z - 2)^2/(Ts^2*(z + 1)^2))/(w0^2 + (2*z - 2)^2/(Ts^2*(z + 1)^2) + (2*w0*zeta*(2*z - 2))/(Ts*(z + 1)))
 
G3 =((Ts^2*w0^2 + 4)*z^2 + (2*Ts^2*w0^2 - 8)*z + Ts^2*w0^2 + 4)/((Ts^2*w0^2 + 4*zeta*Ts*w0 + 4)*z^2 + (2*Ts^2*w0^2 - 8)*z + Ts^2*w0^2 - 4*zeta*Ts*w0 + 4)

根据离散化的方法:

分子分母同时除以A0,得到差分方程系数 

 差分方程为:

y(k) = b0*x(k) + b1*x(k-1) +b2*x(k-2) - a1*y(k-1) - a2*y(k-2);


B0 = Ts^2*w0^2 + 4;
B1 = 2*Ts^2*w0^2 - 8;
B2 = B0;                                                                                                        (3)
A0 = Ts^2*w0^2 + 4*zeta*Ts*w0 + 4;
A1 = B1;
A2 = Ts^2*w0^2 - 4*zeta*Ts*w0 + 4;

 可得差分方程系数
a0 = 1
b0 = B0/A0
b1 = B1/A0                                                                                                     (4)
b2 = B2/A0
a1 = A1/A0
a2 = A2/A0

b、代入实际参数,求得差分方程系数

f0 = 100;       %目标频率
w0 = 2*pi*f0;
Ts = 10e-6;     %离散化周期
zeta = 0.5;     %带宽

% Control object funciton 
gxnum2 = [1 0 w0^2];           % 传函分子
gxden3 = [1 2*w0*zeta w0^2];   % 传函分母
sys2 = tf(gxnum2, gxden3)      % 传函
zpk(sys2, 's');                % 将传函用零极点格式表示
dsys2 = c2d(sys2, Ts, 'tustin')   % s到z,即,连续到离散域的变换
zpk(dsys2, 'z');               % 将传函用零极点格式表示
[num2, den2] = tfdata(dsys2, 'v'); % 提取传递函数分子、分母的z次幂的系数,并保存到数组

得到传递函数如下:

 需要注意的是,在上图Z域传递函数dsys2的各项系数是经四舍五入的,如果直接用这些系数到Simulink或编写程序进行仿真,得到的结果是错误的!!!需要使用更加精确的系数。这些系数可以将式3和式4代入MATLAB中直接求解得到。

b0 =   0.996868276853708                         b1 =  -1.993697199313698

b2 =   0.996868276853708                         a1 =  -1.993697199313698

a2 =   0.993736553707416

2、以三参数陷波器为例

三、仿真验证

1、使用经四舍五入的系数仿真        

 结果错误

 2、使用正确的系数

 结果正确:

 四、C程序验证

1、方式一

直接将差分方程用代码呈现:

double ADValue;

//Notching Filter Coefficient 
#define Notching_filter_100Hz_a0      1
#define Notching_filter_100Hz_a1      -1.998704711158930
#define Notching_filter_100Hz_a2      0.998744164397945
#define Notching_filter_100Hz_b0      0.999372082198973
#define Notching_filter_100Hz_b1      -1.998704711158930
#define Notching_filter_100Hz_b2      0.999372082198973

// Control law 2p2z data define
typedef struct IIR_2OR_DATA_TAG{
    double coeff_a0;
    double coeff_a1;
    double coeff_a2;
    double coeff_b0;
    double coeff_b1;
    double coeff_b2;

    double filter_out;
    double filter_y1;
    double filter_y2;
    double filter_u1;
    double filter_u2;    
} IIR_2OR_DATA_DEF;

IIR_2OR_DATA_DEF notching_data = {
    Notching_filter_100Hz_a0,
    Notching_filter_100Hz_a1,       
    Notching_filter_100Hz_a2,       
    Notching_filter_100Hz_b0,       
    Notching_filter_100Hz_b1,        
    Notching_filter_100Hz_b2,  
    0, 0, 0, 0 ,0
};

double iir_2or_func(IIR_2OR_DATA_DEF *filter_date, double target)
{
     //
     //y(out) = b0*x(k) + b1*x(k-1) +b2*x(k-2) - a1*y(k-1) - a2*y(k-2);
     //
    filter_date->filter_out = (filter_date->coeff_b0 * (target)) \
                            + (filter_date->coeff_b1 * filter_date->filter_u1) \
                            + (filter_date->coeff_b2 * filter_date->filter_u2) \
                            - (filter_date->coeff_a1 * filter_date->filter_y1) \
                            - (filter_date->coeff_a2 * filter_date->filter_y2);

    //
    // Update last data
    //
    filter_date->filter_y2 = filter_date->filter_y1;
    filter_date->filter_y1 = filter_date->filter_out;
    filter_date->filter_u2 = filter_date->filter_u1;
    filter_date->filter_u1 = target;

    //
    // Return Value
    //
    return(filter_date->filter_out);
}

得到结果正确:

 2、方式二

参考文献3中的方法,增加一个中间变量w,来实现。

double ADValue;

//Notching Filter Coefficient 

#define Notching_filter_100Hz_GAIN      1
#define Notching_filter_100Hz_A1      -1.998704711158930
#define Notching_filter_100Hz_A2      0.998744164397945
#define Notching_filter_100Hz_B0      0.999372082198973
#define Notching_filter_100Hz_B1      -1.998704711158930
#define Notching_filter_100Hz_B2      0.999372082198973


// Control law 2p2z data define
typedef struct IIR_2OR_DATA_TAG{
    double coeff_GAIN;
    double coeff_B0;
    double coeff_B1;
    double coeff_B2;
    double coeff_A1;
    double coeff_A2;

    double filter_out;
    double filter_W0;
    double filter_W1;
    double filter_W2;
} IIR_2OR_DATA_DEF;

IIR_2OR_DATA_DEF notching_data = {
    Notching_filter_100Hz_GAIN,
    Notching_filter_100Hz_B0,       
    Notching_filter_100Hz_B1,       
    Notching_filter_100Hz_B2,       
    Notching_filter_100Hz_A1,        
    Notching_filter_100Hz_A2,  
    0, 0, 0, 0 
};

double iir_2or_func(IIR_2OR_DATA_DEF *filter_date, double target)
{
     //
     // w0 = x(0) - A1 * W1 - A2 * W2
     //
    filter_date->filter_W0 = (target) - filter_date->coeff_A1 * filter_date->filter_W1 \
                           - filter_date->coeff_A2 * filter_date->filter_W2;

    //
    // Y(0) = Gain * (B0 * W0 + B1 * W1 + B2 * W2)
    //
    filter_date->filter_out = filter_date->coeff_GAIN * ( filter_date->coeff_B0 * filter_date->filter_W0 \
                            + filter_date->coeff_B1 * filter_date->filter_W1 \
                            + filter_date->coeff_B2 * filter_date->filter_W2 );

    //
    // Update last data
    //
    filter_date->filter_W2 = filter_date->filter_W1;
    filter_date->filter_W1 = filter_date->filter_W0;

    //
    // Return Value
    //
    return(filter_date->filter_out);
}

仿真结果:

        与方法一完全一样。

参考文献:

1、Simulink 窄带陷波滤波器(Notch filter)仿真到代码生成

2、温故知新(五)——三参数陷波滤波器离散化推导及MATLAB实现

3、陷波器及其算法(基于C语言)

PLECS仿真:notch_filter.plecs

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

陷波器的离散化及仿真验证 的相关文章

  • 模电基础(2)半导体二极管

    1 二极管的组成 二极管 将PN结封装起来 引出两个电极就构成了半导体二极管 二极管的常见结构包括 点接触型 图a 面接触型 图b 平面型 图c 点接触型 结面积小 不可通过较大的电流 结电容小 工作频率高 面接触型的结面积变大 所允许的电
  • 电路端接电阻与信号完整性

    信号沿着传输线传播时 每时每刻阻抗都可能发生变化 例如 PCB走线的宽度或者厚度发生变化 PCB过孔 PCB转角 PCB上的电阻 电容 电感 接插件和器件引脚都会产生阻抗变化 若走线的瞬时阻抗 只和传输线的横截面积和材质特性有关 发生变化
  • 各种FIFO硬件设计(FIFO概念、异步、同步、非2次幂深度FIFO)

    文章目录 一 FIFO概述 二 FIFO分类 三 FIFO重要信号与参数 3 1 信号 3 2 参数 3 2 1 data depth的确定 四 FIFO存储原理 五 同步FIFO 5 1 空满信号判断 5 2 同步FIFO源码 5 3 测
  • 模拟电路设计(8)--- 耗尽型MOSFET

    上篇我们讲到增强型MOSFET的特点是 N沟道的建立是Ugs的贡献 没有Ugs gt Ut 导电沟道就无法建立 D S就不会有导通电流 这边我们要说的是另一种MOSFET 称为耗尽型MOSFET N沟道耗尽型MOSFET结构示意图 以N沟道
  • 芯片手册中的英文的表示含义

    芯片手册中的英文的表示含义 在读芯片的数据手册的时候 会有一些英文表示不知道是什么含义 现在整理了一些在下面 1 ppm 在一些电压芯片数据手册里 有一个描述基准性能的直流参数 称为温度漂移 也称温度系数 或简称TC Temperature
  • 带你了解锂电池保护板的工作原理

    拆过手机或者平板的用户 应该都注意过 在手机或者平板的锂电池部分 其上端有一块质地较软且被塑料膜包裹起来的电路板 电池大小不同 电路板尺寸也不一样 揭开塑料膜 你会发现 其上布置了很多的元器件 或许会有人问 这块板子究竟有何作用 其实呢 电
  • 硬件学习——I2C

    I2C简单来讲就是2线的串行总线 由SDA Serial Data Line 和SCL Serial Clock Line 构成 它遵循主从结构 允许多主多从 主设备 发起 停止数据输出 并且通过控制时钟来控制数据传输过程 从设备 响应主设
  • Altium Designer20快捷键整理合集

    花了点时间整理了一下平常经常用到的一些AD20的快捷键操作 自用可取 经过验证均可用 原理图 PCB通用快捷键 保存 CTRL S 打开 CTRL O 关闭 CTRL F4 打印 CTRL P 退出 ALT F4 项目打包 C P 文档切换
  • 手把手教你Modelsim仿真【2020.4版本】

    首先新建一个文件夹 test5 打开Modelsim 依次选择 File gt Change Directory 把目录选择到创建的 test5 文件夹 创建库 依次选择 File gt New gt Library 一般我们选择第三个 库
  • 霍尔传感器测电机的转速

    霍尔传感器可以用于测量电机的转速 测量原理是通过检测电机旋转时产生的磁场变化来计算转速 具体的测量方法如下 1 在电机旋转的轴上安装一个磁铁 磁铁的北极和南极在轴上相隔一定距离 2 在电机旋转轴的一侧安装一个霍尔传感器 传感器的感应面与磁铁
  • 最详细的Vivado安装教程

    V i v a d o 安 装
  • AD16出现your licence is already used on computer的解决办法

    AD16出现报错警告如何解决 AD16持续出现报错警告 AD为什么会报错 如何解决报错 AD16持续出现报错警告 AD为什么会报错 在使用破解版AD的时候 你用的注册表跟别人的注册表一样 也就是说你两用的是同一个安装包 用的是相同的注册码
  • 硬件基础之电容篇

    一 技术理论 1 电容定义 两个相互靠近的金属板中间夹一层绝缘介质组成的器件 当两端存在电势差时 由于介质阻碍了电荷移动而积累在金属板上 衡量金属板上储存电荷的能力 称为电容 相应的器件称为电容器 电容的符号为C 单位为法拉 F 电容越大
  • 直流-直流(DC-DC)变换电路

    直流 直流 DC DC 变换电路 可以将一种直流电源经过变换电路后输出另一种具有不同输出特性的直流电源 可以是一种固定电压或可调电压的直流电 按照电路拓扑结构的不同 DC DC变换电路可以分成两种形式 不带隔离变压器的DC DC变换电路和带
  • N沟道和P沟道MOS管的四个不同点

    作者 快捷芯 功率半导体创新品牌 1 芯片材质不同 虽然芯片都是硅基 但是掺杂的材质是不同 使得N沟道MOS管是通过电子形成电流沟道 P沟道MOS管是用空穴流作为载流子 具体原理可以参考一些教科书 属于工艺方面的问题 2 同等参数P沟道MO
  • 【零基础玩转BLDC系列】基于反电动势过零检测法的无刷直流电机控制原理

    无刷直流电动机基本转动原理请参考 基于HALL传感器的无刷直流电机控制原理 基本原理及基础知识本篇不再赘述 目录 反电势过零检测法的原理 反电势过零检测实现方法 位置传感器的存在限制了无刷直流电机在某些特定场合中的应用 如 使电机系统的体积
  • ORcad Capture CIS元件库管理

    当电子元器件数量多到一定程度的时候 所有器件都集中在一个library里杂乱无章 使用起来相当不方便 时间长了也很容易把相似的器件封装混淆 如何规范化整理 就成了一个让人头疼的问题 还有就是贴片时硬件工程师都要面对一个整理BOM的问题 小公
  • 2023 华子(华为)硬件岗位面试2

    写在前面 本内容仅作参考 如有侵权或者其他问题 立马删除 也仅作为笔者个人经历或者回忆 不一定完全准确 一切都在改变 也祝愿大家面试顺利 顺利取得自己心仪的offer 编辑切换为居中 添加图片注释 不超过 140 字 可选 本次是业务主管面
  • 【三电平SVPWM学习

    导读 本期对三电平SVPWM的原理和建模做一个简单介绍 并与两电平SVPWM做了一个对比 后面把三电平的SVPWM运用到异步电机直接转矩控制中 看与传统的两电平SVPWM 控制性能是否得到改善 模型可分享 关注公众号 浅谈电机控制 留下邮箱
  • 如何正确使用电感和磁珠

    电感和磁珠不仅在外形上相似 而且功能上也存在很多相同之处 有些应用场景下 两者甚至可以相互替代使用 但是 电感和磁珠之间真的能完全划上等号吗 或许 以下的比较会让你更加清楚地知道两者之间存在的差异 额定电流 当电感的工作电流超过其额定电流时

随机推荐

  • 微服务项目nginx前后台配置实例

    微服务项目nginx配置实例 1 准备好nginx服务我本地版本是nginx 1 18 0 zip 2 将前台代码放入nginx html目录下 3 将修改config nginx conf文件 user nobody worker pro
  • ubuntu问题g++ : 依赖: g++-4.8 (>= 4.8.2-5~) 但是它将不会被安装

    截图中选取了一个等同的例子 python dev 依赖 libpython dev 2 7 5 5ubuntu3 但是它将不会被安装 凡是遇到类似问题 括号里面会是一些版本号 这通常代表的意思是Ubuntu自生安装的软件包版本高 而所安装软
  • [非线性控制理论]4_反馈线性化_反步法

    非线性控制理论 1 Lyapunov直接方法 非线性控制理论 2 不变性原理 非线性控制理论 3 基础反馈稳定控制器设计 非线性控制理论 4 反馈线性化 反步法 非线性控制理论 5 自适应控制器 Adaptive controller 非线
  • C语言编译器

    C语言编译器是指用于将C语言源代码转换成可执行程序的工具软件 编译器将C语言源程序转化为目标代码的过程称为编译 目标代码通常是机器码 可由计算机直接执行 常见的C语言编译器有 GCC GNU Compiler Collection GNU编
  • 【C++入门】文件流(fstream)介绍和使用

    1 打开函数 open mode 含义 ios in 以读取方式打开文件 ios out 以写入方式打开文件 ios binary 以二进制方式存取 ios ate 存取指针在文件末尾 ios app 写入时采用追加方式 ios trunc
  • 一个 SPI 转串口驱动的优化

    rel File List href file C 5CDOCUME 7E1 5Czjujoe 5CLOCALS 7E1 5CTemp 5Cmsohtml1 5C01 5Cclip filelist xml gt 一个 SPI 转串口驱动的
  • JavaScript动态加载CSS的三种方法

    JavaScript动态加载CSS的三种方法 CSDN Blog推出文章指数概念 文章指数是对Blog文章综合评分后推算出的 综合评分项分别是该文章的点击量 回复次数 被网摘收录数量 文章长度和文章类型 满分100 每月更新一次 如果你有很
  • 程序员也要学英语——印欧语音变规律总结

    目录 一 印欧语音变规律 二 口诀汇总 三 元音互换 a e i o u w y 1 词根 uni 一 统一 2 词根 tri 三 四 u v w 1 词根 nov 新 2 词根 vol 意愿 五 b p m f v 1 词根 bene 好
  • U3D打包DLL插件 DLL Builder

    前面的文章讲过如何通过cmd打包dll文件 文章链接 实际中 需求一般是很多文件需要打包到一个dll时 此时 一个一个添加打包吗 这里介绍一个很不错的插件 DLL Builder 商店地址 九块九 包邮 这是一个可视化的dll打包工具 可以
  • 小米SOAR

    小米soar工具安装 系统Ubuntu 18 04 更新下apt get包 防止报错 sudo apt get update sudo apt get install sudo apt get upgrade 安装Go语言 sudo apt
  • 如何在C语言中进行字符串的查找操作?

    首先 要进行字符串的查找操作 我们需要使用到C语言中的字符串函数 这些函数包括strlen strcmp strcat strcpy strstr 等等 它们可以实现字符串的长度计算 比较 拼接 复制 查找等操作 如果要在一个字符串中查找另
  • git clone和直接下载压缩包的区别

    目录 一 区别 一 区别 Git是公司开发中必不可少的一项基础技能 很多大型企业经常会有自己的内网 在内网直接下载压缩包后 写完业务后在进行远程ssh的绑定是无法绑定上的 因为公司内网对这种绑定作出了限制 而上司邀请你有开发权限后 直接使用
  • C++ main函数中参数argc和argv含义及用法( argument count和 argument vector)

    rgc 是 argument count的缩写 表示传入main函数的参数个数 argv 是 argument vector的缩写 注意 不是argument value的缩写 自己以前理解错了 表示传入main函数的参数序列或指针 并且第
  • Paxos与2PC

    Paxos与2PC Paxos协议和2PC协议在分布式系统中所起的作用并不相同 Paxos协议用于保证同一个数据分片的多个副本之间的数据一致性 当这些副本分布到不同的数据中心时 这个需求尤其强烈 2PC协议用于保证属于多个数据分片上的操作的
  • Winclone Pro for Mac(Windows分区备份还原工具)

    Winclone Pro for Mac一款Windows分区备份还原工具 winclone pro mac版保护您的Boot Camp Windows系统免受数据丢失以及将Boot Camp分区移动到新Mac的完整解决方案 Winclon
  • java返回值float_Java Float类的compare()方法与示例

    Float类compare 方法compare 方法在java lang包中可用 compare 方法用于检查给定两个浮点值的相等或不相等 换句话说 可以说此方法用于比较两个浮点值 compare 方法是一个静态方法 也可以使用类名进行访问
  • 爬虫手册05 异步爬虫

    异步爬虫 目标 例举asyncio和aiohttp模块的常规用法代码 关于协程概念参考 https blog csdn net weixin 40743639 article details 122394616 spm 1001 2014
  • 线程安全同步问题

    需求 模拟3个窗口同时在售50张 票 问题1 为什么50张票被卖出了150次 出现 的原因 因为num是非静态的 非静态的成员变量数据是在每个对象中都会维护一份数据的 三个线程对象就会有三份 解决方案 把num票数共享出来给三个线程对象使用
  • Unity3D打包发生错误 "The type or namespace name `UnityEditor' could not be found"(小心使用)

    这句话是说明UnityEditor未发现 主要是某个脚本里写了关于Editor相关的函数 首先我们需要知道 使用UnityEditor的时候 一般是在自己项目调试运行的时候使用 而打包出来生成文件的时候 这个命令是没法在文件中使用的 所以就
  • 陷波器的离散化及仿真验证

    一 陷波器在连续域的传递函数 1 最基本的陷波器传函 1 其中 wo 是所谓 中心频率 也就是你想要 陷掉 的频率 而 则是 陷阱 的宽度 根据公式可以发现 当输入信号频率很小 s 0 或者很大 s 的时候 上面式子的值是1 当输入信号频率