【STM32系列】利用MATLAB配合ARM-DSP库设计FIR数字滤波器(保姆级教程)

ps.源码放在最后面

设计IIR数字滤波器可以看这里:利用MATLAB配合ARM-DSP库设计IIR数字滤波器(保姆级教程)


前言

本篇文章将介绍如何利用MATLAB与STM32的ARM-DSP库相结合,简明易懂地实现FIR低通滤波器的设计与应用。文章重点不在于理论深度,而是帮助初学者通过实际操作,掌握数字滤波器的实现流程,为后续深入学习打下基础。

理论基础

详看上一篇文章:数字滤波器的分类

设计FIR低通滤波器

MATLAB配置

filterDesigner滤波器设计工具

首先在命令行窗口输入"filterDesigner",接着就会跳出以下界面:

设计步骤

跟着下图步骤选择:

滤波器幅频响应图像

接着就可得到以下FIR滤波器及其幅频响应图像:

导出滤波器系数

根据以下步骤,导出MATLAB滤波器的系数:
目标"->"生成C头文件",打开所生成的.h文件,将文件中数组的元素复制下来,后面将其粘贴到代码中即可。

STM32部分

DSP库添加

详细请看硬汉哥的这篇文章,讲的十分清晰:ARM DSP源码和库移植方法(MDK5的AC5和AC6)

FIR代码部分

变量参数定义

以下就是需要的变量参数定义,值得注意的是,图中圈起来的两个部分,在FIR滤波器发生变化的时候,即参数改变的时候需要修改的参数:

FIR滤波主要代码

代码部分没什么好说的,千篇一律,主要就是MATLAB中生成的滤波器参数不一样。更换不同的FIR滤波器的时候,将代码中的滤波器参数和数组大小改一下就行。

程序现象

使用串口打印到VOFA+这个软件上

信号频率:4500Hz
采样频率:48000Hz
通带频率:4000Hz
阻带频率:5000Hz
红色:原始信号波形
绿色:滤波后信号波形

源码

变量定义部分

/*********************** FIR ***********************/
/** 采样频率:48kHz 通带频率:4kHz 阻带频率:5kHz **/
#define FIR_LENGTH 256                         									/* FIR滤波器输入输出数据的长度 */
#define FIR_NUMTAPS_LENGTH 98                  									/* FIR滤波器的系数个数 */
#define FIR_PSTATE_LENGTH (FIR_LENGTH + FIR_NUMTAPS_LENGTH - 1) /* FIR滤波器状态变量的长度 */

arm_fir_instance_f32 * fir_S;												/* FIR实例化结构体 */
float32_t FIR_InputBufer[FIR_LENGTH] = {0};					/* 输入数据缓冲区,长度为 FIR_LENGTH */
float32_t FIR_OutputBufer[FIR_LENGTH] = {0};				/* 输出数据缓冲区,长度为 FIR_LENGTH */
uint16_t fir_numTaps = FIR_NUMTAPS_LENGTH;					/* FIR滤波器系数个数 */
uint32_t fir_blockSize = FIR_LENGTH;								/* 块处理大小 */
float32_t fir_pState[FIR_PSTATE_LENGTH] = {0.0f};		/* FIR滤波器状态变量暂存数组:状态数组的大小为 fir_numTaps + fir_blockSize - 1 */
const float32_t fir_pCoeffs[FIR_NUMTAPS_LENGTH] = {	/* FIR滤波器系数数组,长度为 FIR_NUMTAPS_LENGTH */                                                      
    -0.00078254311335225067f, -0.00194089034910090554f, -0.00313185282559110684f, -0.00495539876517352672f,
    -0.00638956086602692451f, -0.00757987454003869986f, -0.00772155390280845032f, -0.00687095084055358400f,
    -0.00476900664053667676f, -0.00188692319952501889f,  0.00134417816349838314f,  0.00407555838576917698f,
     0.00566532906664842656f,  0.00556431360122016001f,  0.00374928839584976175f,  0.00060987014721678768f,
    -0.00296735404678587613f, -0.00591985213343452707f, -0.00723224215293890964f, -0.00632349600819474313f,
    -0.00323442690521178432f,  0.00127132144860143200f,  0.00589453667352991990f,  0.00912956175478252599f,
     0.00974387808929712967f,  0.00719961710314756358f,  0.00192723328839332114f, -0.00469422256804760251f,
    -0.01065481062891286343f, -0.01388627358340486194f, -0.01292296778433829618f, -0.00746430826262267644f,
     0.00136126826115418606f,  0.01114780347633200115f,  0.01879006594120128520f,  0.02136402303334635974f,
     0.01708251376049307185f,  0.00604552989247455347f, -0.00945856323233184963f, -0.02524803257338050638f,
    -0.03611715784341684721f, -0.03710298030813360959f, -0.02483745200229213815f,  0.00137548734160661008f,
     0.03906511682715284317f,  0.08285990139574969660f,  0.12549091009382731809f,  0.15931768100861251614f,
     0.17801724820473396882f,  0.17801724820473396882f,  0.15931768100861251614f,  0.12549091009382731809f,
     0.08285990139574969660f,  0.03906511682715284317f,  0.00137548734160661008f, -0.02483745200229213815f,
    -0.03710298030813360959f, -0.03611715784341684721f, -0.02524803257338050638f, -0.00945856323233184963f,
     0.00604552989247455347f,  0.01708251376049307185f,  0.02136402303334635974f,  0.01879006594120128520f,
     0.01114780347633200115f,  0.00136126826115418606f, -0.00746430826262267644f, -0.01292296778433829618f,
    -0.01388627358340486194f, -0.01065481062891286343f, -0.00469422256804760251f,  0.00192723328839332114f,
     0.00719961710314756358f,  0.00974387808929712967f,  0.00912956175478252599f,  0.00589453667352991990f,
     0.00127132144860143200f, -0.00323442690521178432f, -0.00632349600819474313f, -0.00723224215293890964f,
    -0.00591985213343452707f, -0.00296735404678587613f,  0.00060987014721678768f,  0.00374928839584976175f,
     0.00556431360122016001f,  0.00566532906664842656f,  0.00407555838576917698f,  0.00134417816349838314f,
    -0.00188692319952501889f, -0.00476900664053667676f, -0.00687095084055358400f, -0.00772155390280845032f,
    -0.00757987454003869986f, -0.00638956086602692451f, -0.00495539876517352672f, -0.00313185282559110684f,
    -0.00194089034910090554f, -0.00078254311335225067f
};

主要程序部分

/*********************** FIR滤波 ***********************/
if(filter_Flag == 0){
	for (uint16_t i = 0; i < FIR_LENGTH; i++) {
		FIR_InputBufer[i] = (float)ADC_DMA_ConvertedValue[i] * 3.3 / 65536.0;
	}
	/* 为FIR实例分配内存 */ 
	fir_S = (arm_fir_instance_f32 *)malloc(sizeof(arm_fir_instance_f32));  
	if (fir_S == NULL) {
		return 0; /* 内存分配失败,处理错误 */
	}
	rm_fir_init_f32(fir_S,fir_numTaps,fir_pCoeffs,fir_pState,fir_blockSize);
	arm_fir_f32(fir_S,FIR_InputBufer,FIR_OutputBufer,fir_blockSize);		
	Set_Current_USART(USART1_IDX);/* 使用串口1 */
	for (uint16_t i = 49; i < FIR_LENGTH; i++){ 
		    printf("%d: %lf,%lf\r\n",i,FIR_InputBufer[i],FIR_OutputBufer[i]);
	}
	free(fir_S);    /* 释放内存 */
	fir_S = NULL; 	/* 将指针设置为 NULL,以避免悬挂指针 */
}
/*******************************************************/
### 提高DSPFIR低通滤波器处理速度的方法 #### 选择合适的硬件平台 对于实时信号处理应用,选择高性能的处理器至关重要。专用集成电路(ASIC)、现场可编程门阵列(FPGA)以及数字信号处理器(DSP)都是常见的选项。其中,FPGA由于其高度并行化的架构和灵活的设计能力,在实现高效FIR滤波方面表现出色[^2]。 #### 减少乘法次数 减少卷积计算中的乘法操作数量可以直接降低运算复杂度。一种有效的方式是对称结构的应用——如果滤波器系数呈现对称分布,则只需执行一半长度的有效乘法即可完成整个过程。此外,还可以考虑使用快速傅里叶变换(FFT)来加速长序列间的卷积运算,尤其是在窗口较大时效果明显。 #### 并行化处理单元 充分利用多核或多CPU的优势来进行数据流分割处理也是提升效率的重要手段之一。例如,在一个多通道音频应用场景下,可以分配不同声道给各个核心独立工作;而对于单输入情况下的大规模样本集,则可通过分块技术将其划分为若干子区间分别交给不同的PE (Processing Element) 同步运作。 #### 使用高效的算法和技术 - **分布式算术(Distributed Arithmetic)**:此方法通过查找表(LUTs)预先存储部分中间结果从而省去了大量重复性的乘加指令; - **流水线设计(Pipelining Design)**:允许连续多个阶段的任务重叠执行而不会相互干扰,进而提高了吞吐率; - **循环展开(Unrolling Loops)**:增加每次迭代所涉及的操作数目以摊薄控制开销带来的延迟影响。 ```matlab % MATLAB代码示例 - 利用MATLAB Coder生成C/C++代码用于嵌入式系统部署 function y = fir_filter(x,h) % x 是输入信号向量; h 表示预定义好的滤波器脉冲响应 persistent state; if isempty(state) state = zeros(length(h)-1,1); end [y,state] = filter(h,1,x,[],state); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值