STM32 FIR滤波器使用要点,STM32 DSP篇

本文详细介绍了如何利用MATLAB的FilterDesigner生成STM32 CMSIS DSP库的FIR滤波器参数,并探讨了滤波器阶数选择、状态缓冲大小、FIR实例复用以及循环执行中的优化技巧。特别关注了不同数据类型函数的选用和关键细节问题的解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.综述

STM32搭配的CMSIS的DSP库已经写好了FIR,我们做的就是用好用稳定!

2.使用流程

2.1使用MATLAB的Filter Designer生成滤波器的参数(直接在MATLAB命令中输入filterDesigner即可调出此工具,配置好参数后,选择Targets->Generate C header)

2.2调用arm_fir_init_f32或arm_fir_init_q31或arm_fir_init_q15等等视实际使用情况而定数据类型

2.3调用对应的arm_fir_f32或arm_fir_q31或arm_fir_q15等等与上一步对应的函数开始计算

2.4就这两步算就对了

3.需要注意的细节问题

3.1滤波器阶数选择

滤波器阶数应当选择能整除4或8或16的,具体要求如下图

例如,f32要求4的倍数,与该数值直接相关的是numTaps,即MATLAB生成的参数的个数。numTaps比FIR滤波器的阶数大1,所以如果numTaps-1不能整除4,那就有问题了。

3.2状态缓冲大小

该参数在arm_fir_init函数中会用到,具体要求如下图

 该缓冲状态区域大小为numTaps + 2*blockSize -1

其中,numTaps为FIR滤波器的配置参数个数,该数值比FIR滤波器的阶数大1。blockSize是每次调用arm_fir_f32计算的数值的个数,如果想一口气计算完,就让blockSize等于缓冲区中的元素个数。

3.3有多个FIR滤波器时,哪些能公用,哪些不行

例如笔者使用该FIR滤波器实现数字分频器,需要分别为左右声道配置两个FIR滤波器,显而易见,这两个滤波器的工作模式(低通、高通、带通等)相同;截止频率相同;窗函数相同。孪生兄弟一般,然而还是互相嫌弃,在实际使用时发现有些东西是不能公用的。

两个滤波器的基本属性与MATLAB生成的配置参数相关,所以MATLAB生成的配置参数可以公用。但是FIR滤波器句柄,即arm_fir_instance_f32(arm_fir_init_f32和arm_fir_f32的第一个参数)和状态缓存(arm_fir_init_f32的第四个参数)不能公用!

例如:

先举个反面例子

这是公用的例子,实际结果是,会听到明显的杂音

改正后是

 

 结果就是声音很圆润,(笔者首先做的是低通滤波器)和低音炮上用运放实现的有源滤波器听起来无区别。

3.4在循环执行时,哪些可以省掉

例如笔者的分频器,只要音乐在播放,他就要一刻不停得工作(毕竟替代的是更不怕累的模拟电路),在一遍遍的滤波过程中,实测arm_fir_init开头这个函数可以省去的,即在循环前调用一次就行。

4.简单聊下我们手里的FIR

我们手头的这个FIR是直接型结构的,系统函数和拓扑图如上。上面的图里面,箭头代表乘法,圆圈代表加法。该滤波器的拓扑结构在有些资料上是下图这样,其本质上相同。

 

 

### STM32F103 实现 FIR 数字滤波器 对于在 STM32F103 上实现 FIR(有限脉冲响应)数字滤波器,可以利用 CMSIS-DSP 库来简化开发过程。CMSIS-DSP 提供了一系列优化过的函数用于信号处理应用,其中包括 FIR 滤波器的设计与实现。 #### 初始化 FIR 滤波器结构体并加载系数 首先需要初始化 `arm_fir_instance_f32` 结构体,并填充必要的参数如状态变量数组长度、抽头数以及指针指向存储滤波器系数的位置: ```c #include "arm_math.h" // 定义滤波器阶数 N 和输入/输出缓冲区大小 M #define FILTER_TAPS 5 // 抽头数量 #define BUFFER_SIZE 32 // 输入输出缓存大小 // 声明全局变量保存滤波器实例和数据缓冲区 static float32_t firState[BUFFER_SIZE + FILTER_TAPS - 1]; static arm_fir_instance_f32 S; static const float32_t coeffs[FILTER_TAPS] = { /* 插入实际计算得到的滤波器系数 */ }; void init_FIR(void){ // 初始化 FIR 滤波器对象 arm_fir_init_f32(&S, FILTER_TAPS, (float32_t*)coeffs, firState, BUFFER_SIZE); } ``` 此部分代码展示了如何创建一个单精度浮点型的一维 FIR 滤波器实例[^4]。 #### 执行 FIR 滤波操作 当接收到新的采样点时,调用下面的方法来进行一次完整的 FIR 处理周期: ```c extern uint32_t ADC_Value; // 来自ADC转换后的原始样本值 extern volatile int newSampleFlag; if(newSampleFlag){ // 如果有新采集到的数据,则执行滤波运算 static float32_t outputBuffer[BUFFER_SIZE]; // 输出结果暂存区域 // 将最新的模拟量读数值放入临时变量中准备送入滤波算法 float32_t input = ((float32_t)(ADC_Value)) / UINT_MAX * VREF; // 调用库函数完成本次迭代中的所有乘积累加运算 arm_fir_f32(&S, &input, &outputBuffer[newestIndex], 1); newestIndex++; if(newestIndex >= BUFFER_SIZE) { newestIndex = 0; } newSampleFlag = 0; // 清除标志位等待下一轮更新 } ``` 上述片段说明了怎样把来自外部传感器(比如通过 ADC 获取温度计测量值)的新鲜样本传递给已经配置好的 FIR 过程去获得平滑化之后的结果。 #### 配置项目环境支持 DSP 功能 为了让编译工具链识别这些特定于 Cortex-M 的指令集扩展特性,在工程属性里添加宏定义如下所示: 增加预定义 `ARM_MATH_CM4`, `__CC_ARM`, `ARM_MATH_MATRIX_CHECK`, `ARM_MATH_ROUNDING` . 这样做的目的是确保编译出来的固件能够充分利用目标处理器内部集成的硬件加速单元从而提高性能表现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值