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

1. 引言

ps.源码放在最后面

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

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

2. 理论基础

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

3. 设计FIR低通滤波器

3.1 MATLAB配置

3.1.1 filterDesigner滤波器设计工具

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

image

3.1.2 设计步骤

跟着下图步骤选择:

image

3.1.3 滤波器幅频响应图像

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

image

3.1.4 导出滤波器系数

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

3.2 STM32部分

3.2.1 DSP库添加

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

3.2.2 FIR代码部分

3.2.2.1 变量参数定义

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

image

3.2.2.2 FIR滤波主要代码

image

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

4. 程序现象

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

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

image

5. 源码

5.1 变量定义部分

/*********************** 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
};

5.2 主要程序部分

/*********************** 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; /* 内存分配失败,处理错误 */
	}
	arm_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,以避免悬挂指针 */
}
/*******************************************************/

博客导航

博客导航

posted @ 2025-02-06 16:52  膝盖中箭卫兵  阅读(876)  评论(0)    收藏  举报  来源
ORCID iD icon https://orcid.org/0000-0001-5102-772X