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

ps.源码放在最后面

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


设计IIR滤波器

MATLAB配置

设计步骤

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

滤波器幅频响应图像

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

导出滤波器系数

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

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

导出后的系数转换

导出后大概率会出现这样一个MATLAB窗口(可知导出后的文件也可在MATLAB中打开,在打开这类文件的时候,记得选择文件类别为“全部文件”),IIR没FIR那么简单,多了一些步骤:

系数转换

也是像FIR滤波器一样,把这些数据复制给AI,让AI给你整合好就行,这里图片就不放出来了。

STM32部分

DSP库添加

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

IIR代码部分

变量参数定义

以下就是需要的变量参数定义,值得注意的是,图中圈起来的两个部分,在IIR滤波器发生变化的时候,即参数改变的时候需要修改的参数(修改部分一看注释中的公式修改;修改部分二看数组中有多少行,根据行数修改;修改部分三根据数组参数变化修改):

主要代码

(打印处i初始等于9是为了显示较好的波形,滤波后的波形在前一段还未完全稳定)
也是千篇一律,主要是对导出的IIR滤波器的系数进行处理,还有修改在定义部分的一些变量值,代码在这里就不多说了。

程序现象

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

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

 源码

变量定义部分

/*********************** IIR ***********************/
/** 采样频率:48kHz 通带频率:4kHz 阻带频率:5kHz **/
#define IIR_LENGTH  256							/* 采样点数,即要处理的采样数据的总数 */
#define IIR_BLOCK_SIZE 1						/* 调用一次 arm_biquad_cascade_df1_f32 函数处理的采样点个数 */
#define IIR_NUMTAPS_LENGTH  7				/* 2 阶 IIR 滤波的个数【滤波器阶数 = IIR_NUMTAPS_LENGTH * 2,每个 2 阶滤波器有 5 个系数】 */static uint32_t iir_blockSize = IIR_BLOCK_SIZE;								/* 每次处理的数据个数,与 IIR_BLOCK_SIZE 相同 */
static uint32_t iir_numBlocks = IIR_LENGTH / IIR_BLOCK_SIZE;	/* 需要调用 arm_biquad_cascade_df1_f32 函数的次数,通过总采样点数除以每次处理的数据个数得到 */
static float32_t IIR_InputBufer[IIR_LENGTH];									/* 采样点缓存区,用于存储原始的采样数据 */
static float32_t IIR_OutputBufer[IIR_LENGTH];									/* 滤波后的输出缓存区,滤波后输出的数据个数与采样点个数相同 */
static float32_t iir_pState[13 * IIR_NUMTAPS_LENGTH];					/* 状态缓存,大小为 35 * IIR_NUMTAPS_LENGTH,直接 I 型滤波器需要 2N 个延迟器和 2N 个乘法器 */
const float32_t iir_Coeffs32LP[5 * IIR_NUMTAPS_LENGTH] = {		/* IIR_NUMTAPS_LENGTH组二阶滤波系数,每组代表一个 Section二阶滤波器,有5个系数 */1.0f, -1.581251265113648107885069293843116611242f, 1.0f, 1.64464506366406792992052032786887139082f,  -0.931601507332356026935826776025351136923f,1.0f, -1.534184978348168693074171642365399748087f, 1.0f, 1.510438012818041242368849452759604901075f, -0.798208657466401461100247161084553226829f,1.0f, -1.418424762240857006645455840043723583221f, 1.0f, 1.348418230754467206367053222493268549442f, -0.655285433213672163788032776210457086563f,1.0f, -1.169460742425922239462465768156107515097f, 1.0f, 1.151129772069469092699023349268827587366f, -0.493393743131744000329774735291721299291f,1.0f, -0.608329709345672098308455133519601076841f, 1.0f, 0.930270435976758625074012343247886747122f, -0.319126063671286819278805069188820198178f,1.0f, 0.671963013119381002979935146868228912354f,  1.0f, 0.736945396854642664763446191500406712294f, -0.169496181427103626004893044409982394427f,1.0f, 1.0f, 																			 0.0f, 0.328290240600095484246878640988143160939f, -0.0f
};/*【滤波器的核心选择都在这些系数里面,这些系数的生成使用MATLB进行配置】*/
arm_biquad_casd_df1_inst_f32 iir_S;				/* 定义一个结构体变量,用于 IIR 滤波器的初始化 */
float32_t iir_ScaleValue;									/* 定义一个变量,用于存放放缩系数 */
float32_t *iir_inputF32, *iir_outputF32;	/* 定义两个指针变量,分别用于存放滤波器输入和输出缓存的地址 */

主要程序部分

iir_inputF32 = &IIR_InputBufer[0];		/* 初始化输入缓存指针 */
iir_outputF32 = &IIR_OutputBufer[0];	/* 初始化输出缓存指针 */for (uint16_t i = 0; i < IIR_LENGTH; i++) {IIR_InputBufer[i] = (float)ADC_DMA_ConvertedValue[i] * 3.3 / 65536.0;
}memset(iir_pState, 0, sizeof(iir_pState)); /* 初始化前清零状态 */
//滤波器结构体初始化
arm_biquad_cascade_df1_init_f32(&iir_S, 						/* 初始化结构体S【S就相当于滤波器配置参数,对S结构体的各个成员变量完成初始化】*/IIR_NUMTAPS_LENGTH, 									/* 初始化2阶IIR滤波的个数【滤波器阶数=IIR_NUMTAPS_LENGTH*2,每个IIR_NUMTAPS_LENGTH有5个系数】*/(float32_t *)&iir_Coeffs32LP[0], 			/* 初始化S的滤波器系数地址【滤波器的核心选择都在这些系数里面】*/(float32_t *)&iir_pState[0]);					/* 初始化S的计算缓存空间 */
for(uint16_t i = 0; i < iir_numBlocks; i++){arm_biquad_cascade_df1_f32(&iir_S, 									/* 使用滤波器iir_S */iir_inputF32 + (i * iir_blockSize), 	/* 滤波器原始输入数据地址 */iir_outputF32 + (i * iir_blockSize), /* 滤波器滤波后输出数据地址 */iir_blockSize);											/* 每次处理数据点的个数 */
}
//计算放缩系数
iir_ScaleValue = 0.685271189526501567357286148762796074152 *0.617778799034633618880718586297007277608 *0.527648329116606640276643247489118948579 *0.412098486544746456239352028205757960677 *0.279416489886909980011608922723098658025 *0.161885019533814594749898674308496993035 *0.33585487969995225787656067950592841953; 
Set_Current_USART(USART1_IDX);/* 使用串口1 */
for(uint16_t i = 9; i<IIR_LENGTH; i++){//输出原始数据和滤波之后的数据【注意这里需要乘上放缩系数】printf("%d: %f,%f\r\n",i,IIR_InputBufer[i],IIR_OutputBufer[i]*iir_ScaleValue);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/13848.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星闪开发入门级教程之安装编译器与小项目烧录

系列文章目录 星闪开发入门级教程 好久不见&#xff0c;已经好几年没有发文章了&#xff0c;星闪-作为中国原生的新一代近距离无线联接技术品牌。我想着写点东西。为了适合新手&#xff0c;绝对小白文。 文章目录 系列文章目录前言一、Hispark Studio1.安装Hispark Studio2.安…

【Spring Boot】 SpringBoot自动装配-Condition

目录 一、前言二、 定义 2.1 Conditional2.2 Condition2.2.1 ConditionContext 三、 使用说明 3.1 创建项目 3.1.1 导入依赖3.1.2 添加配置信息3.1.3 创建User类3.1.4 创建条件实现类3.1.5 修改启动类 3.2 测试 3.2.1 当user.enablefalse3.2.2 当user.enabletrue 3.3 小结 四、…

优惠券平台(十一):布隆过滤器、缓存空值、分布式组合的双重判定锁解决缓存穿透问题

业务背景 在上一节中&#xff0c;我们讨论了正常用户在访问优惠券时可能遇到的缓存击穿问题&#xff0c;并介绍了缓存预热、缓存永不过期、分布式锁、双重判定锁、分片分布式锁等技术来应对这些问题。然而&#xff0c;还有一个问题需要解决&#xff1a;如果用户频繁访问数据库…

VUE 集成企微机器人通知

message-robot 便于线上异常问题及时发现处理&#xff0c;项目中集成企微机器人通知&#xff0c;及时接收问题并处理 企微机器人通知工具类 export class MessageRobotUtil {constructor() {}/*** 发送 markdown 消息* param robotKey 机器人 ID* param title 消息标题* param…

阿里云cdn怎样设置图片压缩

阿里云 CDN 提供了图像加速服务&#xff0c;其中包括图像压缩功能。通过设置图片压缩&#xff0c;可以显著减小图片文件的体积&#xff0c;提升网站加载速度&#xff0c;同时减少带宽消耗。九河云来告诉你如何进行图片压缩吧。 如何设置阿里云 CDN 图片压缩&#xff1f; 1. 登…

GB/T28181 开源日记[8]:国标开发速知速会

服务端源代码 github.com/gowvp/gb28181 前端源代码 github.com/gowvp/gb28181_web 介绍 go wvp 是 Go 语言实现的开源 GB28181 解决方案&#xff0c;基于GB28181-2022标准实现的网络视频平台&#xff0c;支持 rtmp/rtsp&#xff0c;客户端支持网页版本和安卓 App。支持rts…

初窥强大,AI识别技术实现图像转文字(OCR技术)

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据、人工智能领域创作者。目前从事python全栈、爬虫和人工智能等相关工作&#xff0c;主要擅长领域有&#xff1a;python…

如何在Docker中运行MySQL容器?

随着容器化技术的普及&#xff0c;Docker已成为开发和部署应用的首选工具之一。MySQL作为最流行的开源关系型数据库&#xff0c;也非常适合在Docker容器中运行。本文将介绍如何在Docker中运行MySQL容器&#xff0c;帮助你快速搭建一个可用的数据库环境。 1. 安装Docker 首先&a…

[ESP32:Vscode+PlatformIO]添加第三方库 开源库 与Arduino导入第三方库的区别

前言 PlatformIO与Arduino在添加第三方库方面的原理存在显著差异 在PlatformIO中&#xff0c;第三方库的使用是基于项目&#xff08;工程&#xff09;的。具体而言&#xff0c;只有当你为一个特定的项目添加了某个第三方库后&#xff0c;该项目才能使用该库。这些第三方库的文…

高端入门:Ollama 本地高效部署DeepSeek模型深度搜索解决方案

目录 一、Ollama 介绍 二、Ollama下载 2.1 官网下载 2.2 GitHub下载 三、模型库 四、Ollmal 使用 4.1 模型运行&#xff08;下载&#xff09; 4.2 模型提问 五、Ollama 常用命令 相关推荐 一、Ollama 介绍 Ollama是一个专为在本地机器上便捷部署和运行大型语言模型&…

【DeepSeek论文精读】2. DeepSeek LLM:以长期主义扩展开源语言模型

欢迎关注[【youcans的AGI学习笔记】](https://blog.csdn.net/youcans/category_12244543.html&#xff09;原创作品 【DeepSeek论文精读】1. 从 DeepSeek LLM 到 DeepSeek R1 【DeepSeek论文精读】2. DeepSeek LLM&#xff1a;以长期主义扩展开源语言模型 【DeepSeek论文精读】…

力扣.623. 在二叉树中增加一行(链式结构的插入操作)

Problem: 623. 在二叉树中增加一行 文章目录 题目描述思路复杂度Code 题目描述 思路 1.首先要说明&#xff0c;对于数据结构无非两大类结构&#xff1a;顺序结构、链式结构&#xff0c;而二叉树实质上就可以等效看作为一个二叉链表&#xff0c;而对于链表插入一个节点的操作是应…

深度学习01 神经网络

深度学习是机器学习领域中的一个新的研究方向。所以在学习深度学习之前我们需要了解一下神经网络。 神经网络 神经网络:是由大量的节点&#xff08;或称“神经元”&#xff09;和之间相互的联接构成。 每个节点代表一种特定的输出函数&#xff0c;称为激励函数、激活函数&…

基于JUnit4和JUnit5配合例子讲解JUnit的两种运行方式

1 引言 最近读的书有老有新&#xff0c;在读的过程中都完全完成了相应例子的构建和运行。在读《Spring in Action》1第4版时&#xff0c;其第37页的例子&#xff08;以下称例子1&#xff09;基于JUnit 4&#xff0c;并需要spring-test.jar&#xff1b;而在读《JUnit in Action…

【提示词工程】探索大语言模型的参数设置:优化提示词交互的技巧

在与大语言模型(Large Language Model, LLM)进行交互时,提示词的设计和参数设置直接影响生成内容的质量和效果。无论是通过 API 调用还是直接使用模型,掌握模型的参数配置方法都至关重要。本文将为您详细解析常见的参数设置及其应用场景,帮助您更高效地利用大语言模型。 …

使用Python创建、读取和修改Word文档

自动化文档处理是提升工作效率的关键路径之一&#xff0c;而Python凭借其简洁语法和丰富的生态工具链&#xff0c;是实现文档自动化处理的理想工具。通过编程手段批量生成结构规范的合同模板、动态注入数据分析结果生成可视化报告&#xff0c;或是快速提取海量文档中的关键信息…

Android Studio 2024.2.2.13版本安装配置详细教程

Android Studio 是由 Google 官方开发和维护的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为 Android 应用开发设计。它是基于 JetBrains 的 IntelliJ IDEA 平台构建的&#xff0c;集成了丰富的工具和功能&#xff0c;帮助开发者高效构建、调试、测试和发布 Androi…

Qt实现简易音乐播放器

使用Qt6实现简易音乐播放器&#xff0c;效果如下&#xff1a; github&#xff1a; Gabriel-gxb/MusicPlayer: qt6实现简易音乐播放器 一、整体架构 基于Qt框架构建 整个音乐播放器程序以Qt框架为基础进行开发。Qt提供了丰富的类库和工具&#xff0c;方便开发者构建图形用户界…

GPT-4使用次数有上限吗?一文了解使用规则

GPT-4的推出&#xff0c;让越来越多的用户开始体验其卓越的功能。无论是用于日常需求还是专业内容制作&#xff0c;GPT-4的应用范围广泛&#xff0c;获得了用户的广泛赞誉。但是&#xff0c;在具体使用过程中&#xff0c;不少用户发现自己似乎触碰到了GPT-4的使用上限&#xff…

水波效果

水波效果指在计算机图形学中模拟水面波纹的视觉效果&#xff0c;通常用于游戏、动画或者其他虚拟场景中。主要用于体现水体的动态感&#xff0c;比如水的波动、反射、折射、透明等&#xff0c;可以让人感觉像真实的水一样流动闪耀。 核心特点就是&#xff1a; 动态波纹光学特…