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

ps.源码放在最后面

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


前言

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

理论基础

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

设计FIR低通滤波器

MATLAB配置

filterDesigner滤波器设计工具

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

设计步骤

跟着下图步骤选择:

滤波器幅频响应图像

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

导出滤波器系数

根据以下步骤,导出MATLAB滤波器的系数(千万不要用"目标"->"生成C头文件"来导出,主要是为了后面操作方便):

最后得到的浮窗是这样的,选择一个合适的位置导出即可。

导出后系数转换

导出后大概率会出现这样一个MATLAB窗口(可知导出后的文件也可在MATLAB中打开,在打开这类文件的时候,记得选择文件类别为"全部文件"):

那么多数字就是滤波器所需的参数了,接下来就是随便找一个AI,让它帮你将其整理为一个一行四个元素的数组就行。

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,以避免悬挂指针 */
}
/*******************************************************/
相关推荐
白天学嵌入式30 分钟前
STM32f103 标准库 零基础学习之按键点灯(不涉及中断)
stm32·单片机·学习
四夕白告木贞1 小时前
stm32week15
stm32·单片机·嵌入式硬件·学习
sword devil9004 小时前
stm32实战项目:无刷驱动
arm开发·stm32·单片机·嵌入式硬件
小石(努力版)6 小时前
嵌入式STM32学习——振动传感器控制继电器开关灯
stm32·嵌入式硬件·学习
passionSnail6 小时前
《用MATLAB玩转游戏开发》Flappy Bird:小鸟飞行大战MATLAB趣味实现
开发语言·matlab
茯苓gao7 小时前
stm32 串口通讯 和 USART学习 二(HEX和文本数据包收发)
stm32·嵌入式硬件·学习
番茄灭世神7 小时前
第31讲 循环缓冲区与命令解析
stm32
茯苓gao9 小时前
stm32 I2C通信协议(一)(基本知识和软件实现)
stm32·单片机·嵌入式硬件
可乐鸡翅好好吃12 小时前
not a genuine st device abort connection的问题
c语言·stm32·单片机·keil
小森776712 小时前
(九)PMSM驱动控制学习---分流电阻采样及重构
stm32·嵌入式·电机控制·foc·永磁同步电机·pmsm·电流采样