记录 ARM DSP 库下 FIR 滤波器的使用,方便后续使用。
使用示例
ARM DSP 库下 FIR 滤波器的使用如下所示,FIR 以块的形式滤波,示例中的采样点数和滤波快大小可以是一样的。FIR 系数表由 Matlab 的 fdatool 工具导出,示例代码中的系数对应的参数为 500Hz 采样率、低通滤波、汉明窗、16 阶、截止频率为 10Hz。
#include "arm_math.h"
#define SAMPLES_NUM 1024 //采样点数
#define BLOCK_SIZE 8 //FIR 滤波块大小
#define NUM_TAPS 17 //滤波器系数个数
void SGM58031Task(void)
{
//状态缓存,大小numTaps + blockSize - 1
static float32_t s_arrFirStateF32[BLOCK_SIZE + NUM_TAPS - 1];
//FIR 系数表
const float32_t s_arrFirCoeffF32[NUM_TAPS] = {
0.007925619371, 0.01188393217, 0.02299686521, 0.04016345739, 0.06104932353,
0.08247635514, 0.1009953544, 0.1135294884, 0.1179592237, 0.1135294884,
0.1009953544, 0.08247635514, 0.06104932353, 0.04016345739, 0.02299686521,
0.01188393217, 0.007925619371
};
//其它静态变量
static u8 s_iInitFlag = 1;
static arm_fir_instance_f32 s_FirF32;
static float32_t s_arrInput[SAMPLES_NUM];
static float32_t s_arrOutput[SAMPLES_NUM];
static u32 s_iSampleCnt = 0;
//局部变量
i16 adc;
float32_t volt;
u32 blockBeginAddr, i;
//需要初始化
if(0 != s_iInitFlag)
{
s_iInitFlag = 0;
arm_fir_init_f32(&s_FirF32, NUM_TAPS, (float32_t*)&s_arrFirCoeffF32[0], &s_arrFirStateF32[0], BLOCK_SIZE);
s_iSampleCnt = 0;
}
//获取转换结果
adc = GetADC();
volt = 3.3 * adc / 4096.0;
//采样
s_arrInput[s_iSampleCnt] = volt;
s_iSampleCnt = (s_iSampleCnt + 1) % SAMPLES_NUM;
//采够了一批数据
if(0 == (s_iSampleCnt % BLOCK_SIZE))
{
//计算块起始地址
if(0 == s_iSampleCnt)
{
blockBeginAddr = SAMPLES_NUM - BLOCK_SIZE;
}
else
{
blockBeginAddr = s_iSampleCnt - BLOCK_SIZE;
}
//滤波
arm_fir_f32(&s_FirF32, s_arrInput + blockBeginAddr, s_arrOutput + blockBeginAddr, BLOCK_SIZE);
//打印
for(i = 0; i < BLOCK_SIZE; i++)
{
printf("%.3f\r\n", s_arrOutput[blockBeginAddr + i]);
}
}
}