利用MATLAB生成软件二阶低通滤波器(绝对靠谱)

article/2025/10/21 11:12:25

利用MATLAB生成软件二阶低通滤波器

`=================================================
嵌入式的软件滤波中,除了均值和限幅,我们常用的也就是一阶或者二阶,这些都是可以通过c语言代码来实现的。其过程包括分母A和分子B参数的求取,再者通过公式得出想要的输出结果。


文章目录

  • 利用MATLAB生成软件二阶低通滤波器
  • 一、一阶巴特沃斯低通滤波器设计
  • 二、 二阶巴特沃斯低通滤波器设计
  • 三、IIR滤波器的差分方程
  • 总结


一、一阶巴特沃斯低通滤波器设计

第一步:其参数A和B的求取可以通过Matlab的滤波器工具箱
来获得(因为这个c语言代码还不知道怎么写出来),打开Matlab软件,依次Start(在Matlab界面的左下角)->Toolboxes->Filter Design->Filter Design & Analysis Tool (fdatool),打开的界面如下:
在这里插入图片描述
可以针对自己想要的滤波器,这里都可以进行设置,得到相应的参数,本人需要一阶巴特沃斯低通滤波器,采样频率:250Hz,截止频率5Hz,设置如下:

在这里插入图片描述
然后,点Design Filter即可,接着在菜单栏Analysis->Filter Coefficients,可以看到分母A和分子B相应的参数:
第二步:参数得到,代入公式即可了。
差分方程公式为: 在这里插入图片描述

xt 为当前输入,c语言代码为:
float  LOW_PASS_FILTER1ORDER(float curr_input)
{static  float  input[2];static  float  output[2];/*获取最新输入*/input[1] = curr_input;/* Butterworth */output[1] =B[0] * input[1] +B[1] * input[0] - A[1] * output[0];/* 输入序列保存 */input[0] = input[1];/*输出序列保存 */output[0] = output[1];return output[1];
}

二、 二阶巴特沃斯低通滤波器设计

第一步:二阶的话,其用Matlab获取参数和c语言代码得到参数都可以,Matlab获取参数跟上述类似,如下图所示:
第一步设置FS和FC并生成滤波器:
在这里插入图片描述
生成滤波器后,电机左上角的[b,a]选项模块
在这里插入图片描述
第三步,点击edit->convert to single section 获得bk和ak
在这里插入图片描述
最后:
在这里插入图片描述
其中,Numerator,分子,也就是传递函数中的b项们,从上到下依次为b0、b1、b2。
Denominator,分母,也就是传递函数中的a项,从上到下依次为a0、a1、a2,其中a0总是为1。
除了上述方法,现在使用c语言代码得到分子B和分母A的参数。
设置采样频率为fs,截止频率为fc,则:
在这里插入图片描述
其公式的代码展示为:


/**************************************************
通过此函数可以得到二阶巴特沃斯的系数
****************************************************/
void  Lowpassfilter2orderSetCutoffFreq(float sample_freq, float cutoff_freq)
{float fr =0;  float ohm =0;float c =0;fr= sample_freq/cutoff_freq;ohm=tanf(M_PI_F/fr);c=1.0f+2.0f*cosf(M_PI_F/4.0f)*ohm + ohm*ohm;//    _cutoff_freq1 = cutoff_freq;
//    if (_cutoff_freq1 > 0.0f) 
//		{b_acc[0] = ohm*ohm/c;b_acc[1] = 2.0f*b_acc[0];b_acc[2] = b_acc[0];a_acc[1] = 2.0f*(ohm*ohm-1.0f)/c;a_acc[2] = (1.0f-2.0f*cosf(M_PI_F/4.0f)*ohm+ohm*ohm)/c;
//		}
}
第二步:代入公式
一个二阶结构是这样的一个表达式:

在这里插入图片描述
这个表达式中需要过去的4个历史值: Xt-1,Xt-2,Yt-1,Yt-2
二阶的意思就是:输入和输出项最多用到过去两个阶段的历史值,要用static来描述过去的变量和过去的过去的变量。
C代码的实现如下(已验证,得到了实现):

float  LowPassfilter2order(float curr_input)
{static  float  input[3];static  float  output[3];/*获取最新输入*/input[2] = curr_input;/* Butterworth */output[2] =B[0] * input[2] +B[1] * input[1] +B[2] * input[0] - A[1] * output[1] - A[2] * output[0];/* 输入序列保存 */input[0] = input[1];input[1] = input[2];/*输出序列保存 */output[0] = output[1];output[1] = output[2];return output[2];
}
有一个简单的技巧,可以把上面的计算简化,使得历史状态由4减为2,定义下面的表达式:

在这里插入图片描述
那么代码就可以写为:

/******************************************
二阶巴特沃斯低通滤波函数
*******************************************/
static float           _delay_element_11;        // buffered sample -1
static float           _delay_element_21;        // buffered sample -2float  LowPassfilter2order(float sample)
{float delay_element_0 = 0, output=0;delay_element_0 = sample - _delay_element_11 * a_acc[1] - _delay_element_21 * a_acc[2];if (isnan(delay_element_0) || isinf(delay_element_0)) {// don't allow bad values to propogate via the filterdelay_element_0 = sample;}output = delay_element_0 * b_acc[0] + _delay_element_11 * b_acc[1] + _delay_element_21 * b_acc[2];_delay_element_21 = _delay_element_11;_delay_element_11 = delay_element_0;// return the value.  Should be no need to check limitsreturn output;
//		}
}
两种方法都可使用哦,看个人的选择。

三、IIR滤波器的差分方程

那有的朋友就问了,这个滤波器方程是从哪来的呢,当初我也有这个疑问。

在这里插入图片描述
这个方程是如何得出的呢,通过如下的图片可以给出解答(down别人的):
在这里插入图片描述
上面的方程是通过IIR差分方程的直接型得出的。
具体的解释为:

首先,当一个系统的输入为冲激函数时,它的输出即为冲激响应。
IIR(Infinite impulse response)&FIR(Finite impulse response)
(1)IIR(无限冲激响应)型数字滤波器顾名思义,当输入为冲激函数时,输出冲激响应h[n](由于属于数字滤波器,自变量变为n)可以无限延长。(2)FIR(有限冲激响应)型数字滤波器当输入为冲激函数时,输出冲激响应 h[n] 可以在有限的时间长内结束。造成这种现象的主要原因是因为IIR型的滤波器采用了递归的结构,即结构中存在回环形成反馈支路来不断地产生输入以进行无限的输出;与之相比,FIR滤波器则实现的较为简单,它的结构中不存在反馈部分,因此它的冲激响应是有限的。

所以,利用左上角的差分方程带入相应的阶数k即可得到所需要的C语言函数方程了。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了二阶巴特沃斯低通滤波器的调用,绝对没有什么问题。

其中参考:

https://www.csdn.net/tags/MtjakgwsMDkxNDEtYmxvZwO0O0OO0O0O.html


http://chatgpt.dhexx.cn/article/5aiHN63P.shtml

相关文章

第八篇,滤波:二阶低通滤波、卡尔曼滤波

目录 1.引言 2.理解与demo 2.1 二阶低通滤波 2.1.1 LP_2Order的个人理解 2.1.2 refer 2.1.3 demo 2.2 卡尔曼滤波 2.2.1 理解 2.2.2 refer 2.2.3 卡尔曼滤波的几个tips 2.2.4 demo 3.其它 1.引言 相比于上一篇,这篇会写的简单很多,可能因为…

【模电】0007 有源滤波器2(二阶有源滤低通波器)

滤波器的阶数越高,则可以得到越陡峭的频率响应,使得在通带内尽量不衰减信号,而在阻带内尽可能多地衰减信号。 上一节我们讲的一阶有源滤波器,在对数坐标系上,其阻带内的衰减是20dB/十倍频程;如果想要更好的…

什么是二阶滤波器?有什么优点?

原文来自公众号:工程师看海 滤波器是常见的信号调理电路,其中低通滤波器最为普遍,我们常听说一阶滤波器、二阶滤波器,二者有什么差别呢? 低通滤波器有3个重要参数:通带、阻带和过度带,理想的滤…

【滤波器】5. 三种类型二阶低通滤波器

滤波器的品质因数 Q,也称为滤波器的截止特性系数。其值决定于 f f 0 ff_0 ff0​ 附近的频率特性。按照 f f 0 ff_0 ff0​ 附近频率特性的特点,可将滤波器分为 巴特沃斯 ( Butterworth)、切比雪夫(Chebyshev) 和 贝塞尔(Bessel) 三种类型。下图是这三种…

二阶低通有源滤波器设计与仿真测试

前言 传感器输出的测量信号中,除了有用的信息外,往往还包含许多噪声以及其他与被测量无关的信号,从而影响测量精度。这冲噪声般随机性很强,难于从时域中直分离出来,但限于其产生的物理机理、噪声功率是有限的&#xf…

带农历万年历C语言程序,c语言万年历程序代码

本篇文章介绍了使用c语言实现万年历程序的代码,希望对学习c语言的朋友有帮助! c语言万年历程序代码 C语言实现万年历程序的代码如下:#include int year(int y) { if ((y%40) && (y%100!0) || y%4000) return 366; else return 365; …

Java万年历程序

【程序说明】该程序实现了输出任意一年的日历,并输出该年中任意一天是该年的第几周。 【规定】①闰年366天,2月29天;平年365天,2月28天。 ②周日为某月的第一天,周六为该月的最后一天。 ③某年的1月1号为该年的第一天…

Java 实现万年历

通过Java的基本语法来实现我们的万年历 请看代码 public class CalDate{public static void main(String[] args){Scanner sc new Scanner(System.in);System.out.println("请输入年:");int year sc.nextInt();System.out.println("请…

C++万年历程序

C万年历 文章目录 C万年历一、运行结果二、源代码 一、运行结果 二、源代码 #include<iostream> #include<stdio.h> #include<string.h> #include<iomanip> using namespace std;class Calendar{ public :Calendar(){TotalDays 0;MonthDays 0;};voi…

编写万年历程序时的一些意外收获

前些天在CSDN每日一练上做到了万年历程序的一道题&#xff0c;觉得很有意思&#xff0c;于是便尝试自己写写看&#xff0c;结果遇到了“公元1年1月1日是星期几”这个问题。拿着手机翻华为日历翻了半天&#xff0c;找到了这一天是星期六&#xff1a; 然而我发现&#xff0c;根据…

C语言编写小程序——万年历

一、杂谈 大一学了C之后一直困惑&#xff0c;C到底怎么用&#xff1f;它不像HTML那么直观&#xff0c;也没有SQL那么常用&#xff0c;更没有Java那么功能强大&#xff0c;那他为何还存在&#xff0c;并依然火热呢&#xff1f; 答案很简单&#xff1a;编程语言是一家&#xff0c…

前端:运用js制作一个万年历程序

前端&#xff1a;运用js制作一个万年历程序 1.HTML代码 首先&#xff0c;依旧是一个套路&#xff0c;先写HTML代码&#xff0c;就好比如建一座楼先建地基和楼的结构一样。 外部这个class属性值为time的div标签是为了让整个内容处于居中地位。 class属性值为head1的div标签是…

用Java写一个万年历程序

从控制台输入指定年份&#xff08;在1900年至2099年之内&#xff09;和月份&#xff0c;输出当月的日历。要求效果如下图所示 思路分析如下&#xff1a; 假设输出2020年5月份的日历。那么要求得1900年1月1日到2020年5月1日前一天的天数总和 再求总天数余7的值&#xff0c;结果…

C++编写万年历,公元后日历程序,考虑了1582年前后以及该年的特殊情况。

目录 一&#xff0c;万年历的基本要求前言&#xff1a;万年历的创建思路1.公元天数与日期1.日期输入问题2.闰年与平年的数目 3.日历的输出问题1.日数转化为星期2.日历月份开头 二&#xff0c;万年历正确性的额外补丁1.1582年闰年定义的变更解决2.1582年消失的十天 三&#xff0…

C语言 万年历 三种版本

C语言 万年历 万年历 一、第1版&#xff1a; 制作一个万年历&#xff08;阳历版&#xff09;。程序从键盘读入年份和月份&#xff0c;然后输出该年该月的月历。 【实现提示】&#xff1a; 本问题的关键是确定所求月份的第一天是星期几。如我们想确定2009年12月1日是星期几&a…

编制万年历的历程

初入编程之道的学子大都试编过万年历。万年历有二种&#xff1a;一为只有西历的月历&#xff0c;另一为有农历对照的月历或日历。编写万年历程序可以练练手&#xff0c;加深对编程语言的理解。记得我初入此道是在1994年&#xff0c;我那时刚买了486电脑&#xff0c;也刚开始有视…

显示万年历的程序(汇编语言实现,附源代码)

运行环境&#xff1a;Masm for Windows 集成实验环境 2015 一、课题内容和要求 课题内容&#xff1a; 用汇编语言编写一个有简单界面显示的日历&#xff0c;要求输入年月日后&#xff0c;将该月的完整日历显示出来&#xff0c;包括星期几&#xff0c;且每月的星期六&#xff…

c语言编写万年历程序

这个程序最核心的地方在于计算当前日期是周几&#xff0c;然后才好显示万年历&#xff0c;因为输入只知道月&#xff0c;所以默认是1号。 通过这个日期我们就可以计算总天数&#xff0c;通过总天数进行%7运算&#xff0c;就能得到周几。 通过这个周几&#xff0c;在结合这个月有…

C语言实现万年历程序

C语言实现万年历程序 #include <stdio.h>int year(int y) {if ((y%40) && (y%100!0) || y%4000)return 366;elsereturn 365; }int main() {int y;int i,j,sum0; int begin,week;int days[12]{31,28,31,30,31,30,31,31,30,31,30,31};scanf("%d",&y)…

C语言实现万年历(附代码) 小白完成的第一个C语言程序,希望大家多多关注,点赞

C语言实现万年历 前言&#xff1a;本文章向大家介绍如何使用C语言代码实现万年历使用实例&#xff0c;讲解编写万年历的方法&#xff0c;教你轻松学会写出万年历。这个小程序算是我自己写的第一个比较完整的小程序&#xff0c;算是对大一上学期学习的C语言程序设计基础的一个总…