单片机数据采集系统中常常需要对采集到的数据进行滤波处理,比如心电采集系统中50Hz市电工频信号对微弱的心电信号干扰就很严重,所以要对50Hz的信号做衰减,需要实现一个带阻滤波器。且单片机内部计算能力有限,使用IIR滤波器比较合适。
一 matlab生成模型和参数
1,打开matlab-->APP-->滤波器设计工具
2,滤波器设计工具界面输入滤波器参数,设置如下,最终生成的频率响应如下图所示。
3,滤波器设计工具界面,生成滤波器模型。
4,生成模型后,双击模型,查看详细的滤波器结构图。
5,双击结构图中的节点可以查看系数,根据模型和系数完成程序,就可以实现滤波器。这一步对于没有学过数字信号处理的人可能有点困难,其实只要把搞懂就很简单了,它表示下一个计算周期,将输入移位到输出处。
6,如下图操作可以查看所有节点的系数,也可以生成一个头文件。
二 单片机程序实现
1,下图为matlab生成的滤波器结构体,根据图列出计算公式。
从左到右:
1是输入数据、是当前时刻采集到的数据。
三角形表示将输入乘上系数然后输出,S(1)是增益系数,滤波器经过一些列计算后可能会改变数据的幅值,该系数补偿后有用信号幅值不变。
圆形符号为加减运算关系,里面的加减符号表示输入信号的加减关系。
方形符号为延时,它表示下一个计算周期,将输入移位到输出处。为了描述方便,需要引入三个变量,这三个变量的位置如下图所示,当前计算完成后,Z2 = Z1;Z1 = Z0;
所以,下图的结构图可以用如下公式计算。
1,首先初始化Z0、Z1、Z2为0,定义输入为input,输出为output
2,
3,
4,Z2 = Z1;Z1 = Z0;
//50Hz带通滤波器参数
float IIR_50Hz_Bs_B[3] =
{
1,
-1.994229000737674617482753092190250754356,
1
};
float IIR_50Hz_Bs_A[3] =
{
1,
-1.983324992232913253076276305364444851875,
0.989064436932039492411661285586887970567
};
float IIR_50Hz_Bs_Gain = 0.994532218466019801716981874051271006465;
//50Hz带阻滤波器包含三个中间参数
static float Bs_50Hz_Z[3]={0};
void Filter_IIR_50Hz_Bs(float inValue,float outValue)
{
//1,输入参数乘上增益系数
//2,根据matlab生成的模型和系数计算
Bs_50Hz_Z[0] = (inValue * IIR_50Hz_Bs_Gain - Bs_50Hz_Z[1] * IIR_50Hz_Bs_A[1] - Bs_50Hz_Z[2] *IIR_50Hz_Bs_A[2])/IIR_50Hz_Bs_A[0];//先计算滤波器模型左半边参数,根据输入和之前算出来的中间参数,
outValue = Bs_50Hz_Z[0] * IIR_50Hz_Bs_B[0] + Bs_50Hz_Z[1] * IIR_50Hz_Bs_B[1] + Bs_50Hz_Z[2] * IIR_50Hz_Bs_B[2];//再计算滤波器模型右半边参数,根据之前算出来的中间参数,
//3,中间参数移位
Bs_50Hz_Z[2] = Bs_50Hz_Z[1];
Bs_50Hz_Z[1] = Bs_50Hz_Z[0];
}
2,滤波器的使用
一般数据采集都是有固定采样频率的,且该采样频率要和matlab生成参数时输入的频率一样。每次采样到一个数据就使用滤波器公式计算一次,得到一个输出值。注意,Z0、Z1、Z2这三个参数只在第一次初始化为0。