通用的一阶IIR 数字高通滤波器的实现

  • 书接上回
  • 开始推算
  • 浮点转定点
  • 最后

书接上回

上一篇讲述了一阶IIR滤波器的一些特点,并设计了一个高通的IIR。实际应用中往往需要动态调整滤波器的参数满足不同场合,不同平台的需要,本章基于上一节的高通滤波器来继续给出一个通用的灵活的高通IIR: H ( s ) = s s + Ω c H(s) = \frac{s}{s+\Omega_c} H(s)=s+Ωc​s​
数字滤波器的截止频率计算公式: ω c = 2 π f f s \omega_c =\frac{2\pi f}{f_s} ωc​=fs​2πf​

开始推算

数字和模拟频率的转换关系: Ω c = ω c T \Omega_c = \frac{\omega_c}{T} Ωc​=Tωc​​
直接带入传递函数得到:
H ( s ) = s s + ω c T H(s) = \frac{s}{s+ \frac{\omega_c}{T}} H(s)=s+Tωc​​s​
带入双线性变换公式: s = 2 T 1 − z − 1 1 + z − 1 和 ω c = 2 π f f s s =\frac{2}{T} \frac{1-z^{-1}}{1+z^{-1}} 和 \omega_c =\frac{2\pi f}{f_s} s=T2​1+z−11−z−1​和ωc​=fs​2πf​
我们得到
H ( s ) = 2 T 1 − z − 1 1 + z − 1 2 T 1 − z − 1 1 + z − 1 + 2 π f f s T = 1 − z − 1 ( π f c f s + 1 ) + ( π f c f s − 1 ) z − 1 = Y ( Z ) X ( Z ) H(s) = \frac{\frac{2}{T} \frac{1-z^{-1}}{1+z^{-1}}}{\frac{2}{T} \frac{1-z^{-1}}{1+z^{-1}}+ \frac{\frac{2\pi f}{f_s}}{T}}=\frac{1-z^{-1}}{(\pi\frac{f_c}{f_s}+1)+(\pi\frac{f_c}{f_s}-1)z^{-1}}=\frac{Y(Z)}{X(Z)} H(s)=T2​1+z−11−z−1​+Tfs​2πf​​T2​1+z−11−z−1​​=(πfs​fc​​+1)+(πfs​fc​​−1)z−11−z−1​=X(Z)Y(Z)​
根据这个得出时域差分方程 y ( n ) = 1 π f c f s + 1 ( x ( n ) − x ( n − 1 ) ) − π f c f s − 1 π f c f s + 1 y ( n − 1 ) y(n)= \frac{1}{\pi\frac{f_c}{f_s}+1} (x(n)-x(n-1))-\frac{\pi\frac{f_c}{f_s}-1}{\pi\frac{f_c}{f_s}+1} y(n-1) y(n)=πfs​fc​​+11​(x(n)−x(n−1))−πfs​fc​​+1πfs​fc​​−1​y(n−1)
同理得出预畸变(双线性变换对频率作预畸变处理): Ω c = 2 T tan ⁡ ω c 2 \Omega_c = \frac{2}{T}\tan{\frac{\omega_c}{2}} Ωc​=T2​tan2ωc​​的差分方程 y ( n ) = 1 t a n ( π f c f s ) + 1 ( x ( n ) − x ( n − 1 ) ) − t a n ( π f c f s ) − 1 t a n ( π f c f s ) + 1 y ( n − 1 ) y(n)= \frac{1}{tan{(\frac{\pi f_c}{f_s}})+1} (x(n)-x(n-1))-\frac{tan{(\frac{\pi f_c}{f_s}})-1}{tan{(\frac{\pi f_c}{f_s}})+1} y(n-1) y(n)=tan(fs​πfc​​)+11​(x(n)−x(n−1))−tan(fs​πfc​​)+1tan(fs​πfc​​)−1​y(n−1)
为何提出这两种形式呢? 主要是因为在低频段两者基本可以互换,而前者能省掉tan计算,对于一些比较弱鸡的嵌入式系统,三角计算是不支持的。
下边给了一个例子,在48k采样率的情况下,1000Hz以内的截止频率,两者的系数计算结果基本可以互换。

PRE_WARP: temp_alpha1=-0.986995 temp_beta1=0.993497 freqz: 100, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-16170 temp_beta1=16277 freqz: 100, srate:48000
NORMAL: alpha1=-0.986995 beta1=0.993498 freqz: 100, srate:48000
NORMAL TRANSTO INT: a0=-16170 a1=16277 freqz: 100, srate:48000PRE_WARP: temp_alpha1=-0.974157 temp_beta1=0.987078 freqz: 200, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-15960 temp_beta1=16172 freqz: 200, srate:48000
NORMAL: alpha1=-0.974158 beta1=0.987079 freqz: 200, srate:48000
NORMAL TRANSTO INT: a0=-15960 a1=16172 freqz: 200, srate:48000PRE_WARP: temp_alpha1=-0.961481 temp_beta1=0.980741 freqz: 300, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-15752 temp_beta1=16068 freqz: 300, srate:48000
NORMAL: alpha1=-0.961486 beta1=0.980743 freqz: 300, srate:48000
NORMAL TRANSTO INT: a0=-15752 a1=16068 freqz: 300, srate:48000PRE_WARP: temp_alpha1=-0.948965 temp_beta1=0.974482 freqz: 400, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-15547 temp_beta1=15965 freqz: 400, srate:48000
NORMAL: alpha1=-0.948976 beta1=0.974488 freqz: 400, srate:48000
NORMAL TRANSTO INT: a0=-15548 a1=15966 freqz: 400, srate:48000PRE_WARP: temp_alpha1=-0.936602 temp_beta1=0.968301 freqz: 500, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-15345 temp_beta1=15864 freqz: 500, srate:48000
NORMAL: alpha1=-0.936624 beta1=0.968312 freqz: 500, srate:48000
NORMAL TRANSTO INT: a0=-15345 a1=15864 freqz: 500, srate:48000PRE_WARP: temp_alpha1=-0.924390 temp_beta1=0.962195 freqz: 600, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-15145 temp_beta1=15764 freqz: 600, srate:48000
NORMAL: alpha1=-0.924428 beta1=0.962214 freqz: 600, srate:48000
NORMAL TRANSTO INT: a0=-15145 a1=15764 freqz: 600, srate:48000PRE_WARP: temp_alpha1=-0.912326 temp_beta1=0.956163 freqz: 700, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-14947 temp_beta1=15665 freqz: 700, srate:48000
NORMAL: alpha1=-0.912384 beta1=0.956192 freqz: 700, srate:48000
NORMAL TRANSTO INT: a0=-14948 a1=15666 freqz: 700, srate:48000PRE_WARP: temp_alpha1=-0.900404 temp_beta1=0.950202 freqz: 800, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-14752 temp_beta1=15568 freqz: 800, srate:48000
NORMAL: alpha1=-0.900491 beta1=0.950245 freqz: 800, srate:48000
NORMAL TRANSTO INT: a0=-14753 a1=15568 freqz: 800, srate:48000PRE_WARP: temp_alpha1=-0.888622 temp_beta1=0.944311 freqz: 900, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-14559 temp_beta1=15471 freqz: 900, srate:48000
NORMAL: alpha1=-0.888744 beta1=0.944372 freqz: 900, srate:48000
NORMAL TRANSTO INT: a0=-14561 a1=15472 freqz: 900, srate:48000PRE_WARP: temp_alpha1=-0.876976 temp_beta1=0.938488 freqz: 1000, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-14368 temp_beta1=15376 freqz: 1000, srate:48000
NORMAL: alpha1=-0.877141 beta1=0.938571 freqz: 1000, srate:48000
NORMAL TRANSTO INT: a0=-14371 a1=15377 freqz: 1000, srate:48000PRE_WARP: temp_alpha1=-0.865464 temp_beta1=0.932732 freqz: 1100, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-14179 temp_beta1=15281 freqz: 1100, srate:48000
NORMAL: alpha1=-0.865681 beta1=0.932840 freqz: 1100, srate:48000
NORMAL TRANSTO INT: a0=-14183 a1=15283 freqz: 1100, srate:48000PRE_WARP: temp_alpha1=-0.854081 temp_beta1=0.927040 freqz: 1200, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13993 temp_beta1=15188 freqz: 1200, srate:48000
NORMAL: alpha1=-0.854359 beta1=0.927179 freqz: 1200, srate:48000
NORMAL TRANSTO INT: a0=-13997 a1=15190 freqz: 1200, srate:48000PRE_WARP: temp_alpha1=-0.842824 temp_beta1=0.921412 freqz: 1300, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13808 temp_beta1=15096 freqz: 1300, srate:48000
NORMAL: alpha1=-0.843174 beta1=0.921587 freqz: 1300, srate:48000
NORMAL TRANSTO INT: a0=-13814 a1=15099 freqz: 1300, srate:48000PRE_WARP: temp_alpha1=-0.831691 temp_beta1=0.915846 freqz: 1400, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13626 temp_beta1=15005 freqz: 1400, srate:48000
NORMAL: alpha1=-0.832123 beta1=0.916061 freqz: 1400, srate:48000
NORMAL TRANSTO INT: a0=-13633 a1=15008 freqz: 1400, srate:48000PRE_WARP: temp_alpha1=-0.820679 temp_beta1=0.910339 freqz: 1500, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13446 temp_beta1=14915 freqz: 1500, srate:48000
NORMAL: alpha1=-0.821204 beta1=0.910602 freqz: 1500, srate:48000
NORMAL TRANSTO INT: a0=-13454 a1=14919 freqz: 1500, srate:48000PRE_WARP: temp_alpha1=-0.809784 temp_beta1=0.904892 freqz: 1600, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13267 temp_beta1=14825 freqz: 1600, srate:48000
NORMAL: alpha1=-0.810414 beta1=0.905207 freqz: 1600, srate:48000
NORMAL TRANSTO INT: a0=-13277 a1=14830 freqz: 1600, srate:48000PRE_WARP: temp_alpha1=-0.799004 temp_beta1=0.899502 freqz: 1700, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-13090 temp_beta1=14737 freqz: 1700, srate:48000
NORMAL: alpha1=-0.799751 beta1=0.899876 freqz: 1700, srate:48000
NORMAL TRANSTO INT: a0=-13103 a1=14743 freqz: 1700, srate:48000PRE_WARP: temp_alpha1=-0.788336 temp_beta1=0.894168 freqz: 1800, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-12916 temp_beta1=14650 freqz: 1800, srate:48000
NORMAL: alpha1=-0.789213 beta1=0.894607 freqz: 1800, srate:48000
NORMAL TRANSTO INT: a0=-12930 a1=14657 freqz: 1800, srate:48000PRE_WARP: temp_alpha1=-0.777778 temp_beta1=0.888889 freqz: 1900, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-12743 temp_beta1=14563 freqz: 1900, srate:48000
NORMAL: alpha1=-0.778798 beta1=0.889399 freqz: 1900, srate:48000
NORMAL TRANSTO INT: a0=-12759 a1=14571 freqz: 1900, srate:48000PRE_WARP: temp_alpha1=-0.767327 temp_beta1=0.883663 freqz: 2000, srate:48000
PRE_WARP: TRANSTO INT: temp_alpha1=-12571 temp_beta1=14477 freqz: 2000, srate:48000
NORMAL: alpha1=-0.768503 beta1=0.884252 freqz: 2000, srate:48000
NORMAL TRANSTO INT: a0=-12591 a1=14487 freqz: 2000, srate:48000

浮点转定点

低端的数字信号处理器大都是定点处理器,所以真要这个滤波器活蹦乱掉的跑起来,还得做一个浮点转定点的工作。听着很高大上,其实很简单,就是系数转换为Qxx的整形格式(以2的整数次幂放大),然后一顿加乘计算后,再等量缩减。细心的读者可以发现脚本例子中“TRANSTO INT”一行的系数算出了一个巨大的整数值,这个值就是浮点转定点的系数。实在觉得费尽,可以找一些现成的代码,下面的代码就是一个Q15的转换函数。

int To_Q15_Fixed_Point(double Data_Float)
{unsigned int  Data_Q15_Format = 0;if(Data_Float == 1) return (unsigned short)0x7FFF;else if(Data_Float == -1) return (unsigned short)0x8000;else if(Data_Float < 0){Data_Float = -Data_Float;Data_Q15_Format |= (unsigned short)0x8000;}Data_Q15_Format |= (short)(Data_Float*0x8000);if(Data_Q15_Format&0x8000){Data_Q15_Format &= 0x7FFF;Data_Q15_Format = ((~Data_Q15_Format) + 0x0001);}return (int)Data_Q15_Format;
}

最后

有了系数和差分方程,写函数这件事就是最简单的了。在上一篇的基础上,我们彻底解放了这个一阶iir的高通滤波器,使用的时候需要评估采用哪种系数计算方法更满足要求。

通用的一阶IIR数字高通滤波器的实现相关推荐

  1. 一阶IIR数字滤波器的设计

    一阶IIR数字滤波器的设计 最简单的低通滤波器传递函数入手 对原始滤波器的改造 低通变高通 低通变带通 高通变带阻 从模拟到数字,采用双线性变换,简单方便 频域分析 结论 最简单的低通滤波器传递函数入 ...

  2. java限制数字_是否存在将我的通用方法限制为数字类型的约束?

    谁能告诉我泛型是否可以将泛型类型参数T限制为: Int16 Int32 Int64 UInt16 UInt32 UInt64 我知道where关键字,但是找不到仅适用于这些类型的接口, 就像是: st ...

  3. 一阶低通滤波器与高通滤波器的使用

    文章目录 1. 一阶低通滤波器 2. 一阶高通滤波器 3. 互补滤波器 4. Simulink仿真 1. 一阶低通滤波器 其传递函数为:YU=11+RC⋅S\frac{Y}{U}=\frac{1}{1 ...

  4. IIR数字低通滤波器

    即令Ha(s)->H(z),两种要求: 1.因果转换后仍是因果稳定的 2.数字滤波器的频率响应模仿模拟滤波器的频响 两种方法: 1.脉冲响应不变法:数字频率与模拟频率成线性关系 2.双线性变换法 ...

  5. FIR窗函数和IIR模拟、数字滤波器的MATLAB实现

    导语 本文采用MATLAB R2014b对x.mat信号进行了时域频域的分析,同时创建窗函数.IIR模拟巴特沃兹.IIR数字滤波器对x.mat信号进行滤波处理. 原始信号的时频域分析 我是把x.mat ...

  6. 经典IIR数字滤波器设计一般步骤的总结

    基于Butterworth模拟LPF进行经典IIR数字滤波器一般设计的步骤总结   趁着这两天刚考完试,DSP忘掉的东西还不多,赶紧写篇note记录一下自己总结的经典IIR数字滤波器的一般设计流程. ...

  7. 【转】电子毕业设计题目

    电子毕业设计题目 默认分类 2009-10-22 18:42:31 阅读1795 评论2 字号:大中小 1.基于labVIEW虚拟滤波器的设计与实现 2.双闭环直流调速系统设计 3.单片机脉搏测量仪 ...

  8. 最热电气专业论文选题

    这几年,每个学校对毕设的要求是越来越高了,难度也越来越大- 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定要提前准备,避免到后面措手不及,草草 ...

  9. 如何使用双线性变换法将模拟电路滤波器设计成为数字滤波器?

    信号处理(数字模拟信号) 1.1 双线性变换设计递归滤波器 设计滤波器1 试着写出双线性变换法设计IIR数字高通滤波器的主要步骤 将数字高通的频率指标转换为模拟高通的频率指标(其中将高通截止频率通过预 ...

最新文章

  1. python最好用的助手_想学Python的小伙伴注意了,pip工具或许是您最好的助手!本文详解安装教程哦!...
  2. 基于linux的java学习,Java学习---Linux总结
  3. linux命令:groupdel
  4. delphi控件切图界面闪烁_小程序设计,不得不说的7个坑 (附资源:新版小程序 UI 控件,Sketch 版)...
  5. python经典程序实例_Python入门经典实例(一)
  6. python getcwd 与dirname_Python中获取路径os.getcwd()和os.path.dirname(os.path.realpath(__file__))的区别和对比...
  7. 【python】详解zipfile模块读取处理压缩文件实例
  8. sonarlint 安装
  9. ftdi+usb转串口驱动+android,FTDI usb转串口驱动
  10. 用视频录制软件Captura学习网课
  11. 怎样快速将方形图片剪裁成椭圆形?分享大家一个小妙招
  12. 如何求子网掩码,默认网关地址,网络地址
  13. 未能找到路径中的某个部分_C# 未能找到 的一部分
  14. 微信可以用邮箱吗?邮箱无法分享到微信怎么办?微信邮箱从哪找呢
  15. fedora35下配置grub2主题
  16. 我用纯C语言开发的中英文混合分词服务器3.0正式发布,词库190多万词,每秒切分5万+,同时提供 c、java、C#、delphi、js调用范例
  17. 读论文:Noise2Noise: Learning Image Restoration without Clean Data
  18. 盛世昊通打造线上线下融合的百业联盟商业生态
  19. ARM服务器和ARM集群服务器的区别
  20. ig信息增益 java_【Python 编程】实现文本分类中的信息增益算法

热门文章

  1. HashMap的实际应用
  2. 【javascript】纯原生js的轻便组织结构图,树状图,支持自定义样式
  3. clang vectorization
  4. DFT的一些基本性质
  5. 数据科学家的一天,是怎样度过的?
  6. TeamViewer商业版改成免费版
  7. EPLAN_语言翻译工具的使用
  8. 变分自编码AVE器生成图像(Pytorch)
  9. 支持居者有其屋,支持房产税出台与落地。
  10. 兄弟hl3150cdn打印测试页6_打印性能测试:LED高效输出_兄弟 3150CDN_办公打印评测试用-中关村在线...