plt.ylim( -60, 10)

plt.axvline(cutoff_freq, color= ‘red’)

plt.axhline( -3.01, linewidth= 0.8, color= ‘black’, linestyle= ‘:’)

# 相频响应

plt.subplot( 2, 1, 2)

plt.plot(w, 180* np.angle(h) / pi)

plt.xlabel( ‘Frequency [Hz]’)

plt.ylabel( ‘Phase [°]’)

plt.xlim( 0, sample_rate / 2)

plt.ylim( -180, 90)

plt.yticks([ -180, -135, -90, -45, 0, 45, 90])

plt.axvline(cutoff_freq, color= ‘red’)

plt.show

取采样率为200Hz,滤波器长度为7可得下面的幅频、相频响应曲线。从其主瓣可见其幅频响应为一低通滤波器。幅频响应略有不平,随频率上升而衰减。其相频响应线性。如果对滤波器有经验的朋友会知道FIR滤波器的相频响应是线性的,而移动平均滤波器刚好是FIR的一种特例。

当改变滤波器长度为3/7/21时,仅观察其幅频响应:

可见,随着滤波器的长度变长,其截止频率变小,其通带变窄。滤波器的响应变慢,延迟变大。所以实际使用的时候,须根据有用频率带宽合理选择滤波器的长度。有用信号的带宽可以通过按采样率采集一定的点进行傅立叶分析可得。如果有带FFT功能的示波器,也可以直接测量得到。

C语言实现

滤波器的C语言实现,比较容易。干货在此,快快领走

# defineMVF_LENGTH 5

typedeffloatE_SAMPLE;

/*定义移动平均寄存器历史状态*/

typedefstruct_ t_MAF

{

E_SAMPLE buffer[MVF_LENGTH];

E_SAMPLE sum;

intindex;

}t_MAF;

voidmoving_average_filter_init(t_MAF * pMaf)

{

pMaf-》index = -1;

pMaf-》sum = 0;

}

E_SAMPLE moving_average_filter(t_MAF * pMaf,E_SAMPLE xn)

{

E_SAMPLE yn= 0;

inti= 0;

if(pMaf-》index == -1)

{

for(i = 0; i 《 MVF_LENGTH; i++)

{

pMaf-》buffer = xn;

}

pMaf-》sum = xn*MVF_LENGTH;

pMaf-》index = 0;

}

else

{

pMaf-》sum -= pMaf-》buffer[pMaf-》index];

pMaf-》buffer[pMaf-》index] = xn;

pMaf-》sum += xn;

pMaf-》index++;

if(pMaf-》index》=MVF_LENGTH)

pMaf-》index = 0;

}

yn = pMaf-》sum/MVF_LENGTH;

returnyn;

}

测试代码:

# defineSAMPLE_RATE 500.0f