安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
第第3377章章 FFIIRR 滤滤波波器器的的实实现现
本章节讲解 FIR 滤波器的低通,高通,带通和带阻滤波器的实现。
37.1 FIR 滤波器介绍
37.2 Matlab 工具箱生成 C 头文件
37.3 FIR 低通滤波器设计
37.4 FIR 高通滤波器设计
37.5 FIR 带通滤波器设计
37.6 FIR 带阻滤波器设计
37.7 切比雪夫窗口设计带通滤波器
37.8 FIR 滤波后的群延迟
37.9 总结
3377..11 FFIIRR 滤滤波波器器介介绍绍
ARM 官方提供的 FIR 库支持 Q7,Q15,Q31 和浮点四种数据类型。其中 Q15 和 Q31 提供了快速算
法版本。
FIR 滤波器的基本算法是一种乘法-累加(MAC)运行,输出表达式如下:
y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
结构图如下:
22001155年年0011月月1155日日 版版本本::11..00 第第 11 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
这种网络结构就是在 35.2.1 小节所讲的直接型结构。
3377..22 MMaattllaabb 工工具具箱箱 ffddaattooooll 生生成成 CC 头头文文件件
下面我们讲解下如何通过 fdatool 工具生成 C 头文件,也就是生成滤波器系数。首先在 matlab 的命
窗口输入 fadtool 就能打开这个工具箱:
fadtool 界面打开效果如下:
22001155年年0011月月1155日日 版版本本::11..00 第第 22 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
FIR 滤波器的低通,高通,带通,带阻滤波的设置会在下面一一讲解,这里说一下设置后相应参数后如何
生成滤波器系数。参数设置好以后点击如下按钮:
点击 Design Filter 按钮以后就生成了所需的滤波器系数,生成滤波器系数以后点击 fadtool 界面上的菜
单 Targets->Generate C header ,打开后显示如下界面:
22001155年年0011月月1155日日 版版本本::11..00 第第 33 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
然后点击 Generate,生成如下界面:
再点击保存,并打开 fdatool.h 文件,可以看到生成的系数:
/*
* Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool
*
* Generated by MATLAB(R) 7.14 and the Signal Processing Toolbox 6.17.
*
* Generated on: 22-Dec-2014 21:34:29
*
*/
22001155年年0011月月1155日日 版版本本::11..00 第第 44 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
/*
* Discrete-Time FIR Filter (real)
* -------------------------------
* Filter Structure : Direct-Form FIR
* Filter Length : 51
* Stable : Yes
* Linear Phase : Yes (Type 1)
*/
/* General type conversion for MATLAB generated C-code */
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\Program Files\MATLAB\R2012a\extern\include\tmwtypes.h
*/
/*
* Warning - Filter coefficients were truncated to fit specified data type.
* The resulting response may not match generated theoretical response.
* Use the Filter Design & Analysis Tool to design accurate
* single-precision filter coefficients.
*/
const int BL = 51;
const real32_T B[51] = {
-0.0009190982091, -0.00271769613,-0.002486952813, 0.003661438357, 0.0136509249,
0.01735116541, 0.00766530633,-0.006554719061,-0.007696784101, 0.006105459295,
0.01387391612,0.0003508617228, -0.01690892503,-0.008905642666, 0.01744112931,
0.02074504457, -0.0122964941, -0.03424086422,-0.001034529647, 0.04779030383,
0.02736303769, -0.05937951803, -0.08230702579, 0.06718690693, 0.3100151718,
0.4300478697, 0.3100151718, 0.06718690693, -0.08230702579, -0.05937951803,
0.02736303769, 0.04779030383,-0.001034529647, -0.03424086422, -0.0122964941,
0.02074504457, 0.01744112931,-0.008905642666, -0.01690892503,0.0003508617228,
0.01387391612, 0.006105459295,-0.007696784101,-0.006554719061, 0.00766530633,
0.01735116541, 0.0136509249, 0.003661438357,-0.002486952813, -0.00271769613,
-0.0009190982091
};
上面数组 B[51]中的数据就是滤波器系数。下面小节讲解如何使用 fdatool 配置 FIR 低通,高通,带通和
带阻滤波。关于 fdatool 的其它用法,大家可以在 matlab 命令窗口中输入 help fadtool 打开帮助文档进
行学习。
3377..33 FFIIRR 低低通通滤滤波波器器设设计计
本章使用的 FIR 滤波器函数是 arm_fir_f32。下面使用此函数设计 FIR 低通,高通,带通和带阻
滤波器。
3377..33..11 函函数数 aarrmm__ffiirr__ff3322 说说明明
函数定义如下:
void arm_fir_f32(
const arm_fir_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
参数定义:
22001155年年0011月月1155日日 版版本本::11..00 第第 55 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
[in] *S points to an instance of the floating-point FIR filter structure.
[in] *pSrc points to the block of input data.
[out] *pDst points to the block of output data.
[in] blockSize number of samples to process per call.
return none.
注意事项:
结构 arm_fir_instance_f32 的定义如下(在文件 arm_math.h 文件):
typedef struct
{
uint16_t numTaps; /**< number of filter coefficients in the filter. */
float32_t *pState; /**< points to the state variable array. The array is of length
numTaps+blockSize-1. */
float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
} arm_fir_instance_f32;
1. 参数 pCoeffs 指向滤波因数,滤波因数数组长度为 numTaps。但要注意 pCoeffs 指向的滤波因数应
该按照如下的逆序进行排列:
{b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
但满足线性相位特性的 FIR 滤波器具有奇对称或者偶对称的系数,偶对称时逆序排列还是他本身。
2. pState 指向状态变量数组,这个数组用于函数内部计算数据的缓存。
3. blockSize 这个参数的大小没有特殊要求,用户只需保证大于 1 小于等于采样点个数即可。
3377..33..22 ffddaattooooll 获获取取低低通通滤滤波波器器系系数数
设计一个如下的例子:
信号由 50Hz 正弦波和 200Hz 正弦波组成,采样率 1Kbps,现设计一个低通滤波器,截止频率 125Hz,
采样 320 个数据,采用函数 fir1 进行设计(注意这个函数是基于窗口的方法设计 FIR 滤波,默认是 hamming
窗),滤波器阶数设置为 28。fadtool 的配置如下:
22001155年年0011月月1155日日 版版本本::11..00 第第 66 页页 共共 3355 页页
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
配置好低通滤波器后,具体滤波器系数的生成大家参考本章第二小节的方法即可。
3377..33..33 低低通通滤滤波波器器实实现现
通过工具箱fdatool获得低通滤波器系数后在开发板上运行函数arm_fir_f32 来测试低通滤波器的效
果。
#define TEST_LENGTH_SAMPLES 320 /* 采样点数 */
#define BLOCK_SIZE 32 /* 调用一次arm_fir_f32处理的采样点个数 */
#define NUM_TAPS 29 /* 滤波器系数个数 */
uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE; /* 需要调用arm_fir_f32的次数 */
static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
static float32_t testOutput[TEST_LENGTH_SAMPLES]; /* 滤波后的输出 */
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1]; /* 状态缓存,大小numTaps + blockSize - 1*/
/* 低通滤波器系数 通过fadtool获取*/
const float32_t firCoeffs32LP[NUM_TAPS] = {
-0.001822523074f, -0.001587929321f, 1.226008847e-18f, 0.003697750857f, 0.008075430058f,
0.008530221879f, -4.273456581e-18f, -0.01739769801f, -0.03414586186f, -0.03335915506f,
8.073562366e-18f, 0.06763084233f, 0.1522061825f, 0.2229246944f, 0.2504960895f,
22001155年年0011月月1155日日 版版本本::11..00 第第 77 页页 共共 3355 页页
uint32_t i;
arm_fir_instance_f32 S;
float32_t *inputF32, *outputF32;
/* 初始化输入输出缓存指针 */
inputF32 = &testInput_f32_50Hz_200Hz[0];
outputF32 = &testOutput[0];
安安富富莱莱 UUMM440033
DDSSPP 教教程程 SSTTMM3322--VV55 开开发发板板系系统统篇篇手手册册
0.2229246944f, 0.1522061825f, 0.06763084233f, 8.073562366e-18f, -0.03335915506f,
-0.03414586186f, -0.01739769801f, -4.273456581e-18f, 0.008530221879f, 0.008075430058f,
0.003697750857f, 1.226008847e-18f, -0.001587929321f, -0.001822523074f
};
/*
*********************************************************************************************************
* 函 数 名: arm_fir_f32_lp
* 功能说明: 调用函数arm_fir_f32_lp实现低通滤波器
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void arm_fir_f32_lp(void)
{
}
运行如上函数可以通过串口打印出函数arm_fir_f32滤波后的波形数据,下面通过Matlab绘制波形来对比
Matlab计算的结果和ARM官方库计算的结果。
/* 打印滤波后结果 */
for(i=0; i