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

news2025/2/12 5:37:34

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.coloradmin.cn/o/2296672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在本地部署deepseek?

1、打开ollama官网&#xff0c;点download&#xff08;下载需要翻墙 https://ollama.com/ 2、双击下载好的OllamaSetup.exe&#xff0c;一直点下一步即可。 3、winR 输入cmd&#xff0c;打开命令提示符&#xff0c;输入ollama。有以下提示即安装完成。 4、可以根据 nvidia-…

AJAX项目——数据管理平台

黑马程序员视频地址&#xff1a; 黑马程序员——数据管理平台 前言 功能&#xff1a; 1.登录和权限判断 2.查看文章内容列表&#xff08;筛选&#xff0c;分页&#xff09; 3.编辑文章&#xff08;数据回显&#xff09; 4.删除文章 5.发布文章&#xff08;图片上传&#xff0…

MarsCode AI插件在IntelliJ IDEA中使用

文章目录 前言一、MarsCode是什么&#xff1f;二、下载三、使用1、登录2、操作界面3、生成代码4、解释代码5、注释代码6、生成单测7、智能修复8、代码补全 总结 前言 随着 AI 技术浪潮席卷而来&#xff0c;各类 AI 工具呈爆发式涌现&#xff0c;深度融入我们的日常与职场&…

如何将网站提交百度收录完整SEO教程

百度收录是中文网站获取流量的重要渠道。本文以我的网站&#xff0c;www.mnxz.fun&#xff08;当然现在没啥流量&#xff09; 为例&#xff0c;详细讲解从提交收录到自动化维护的全流程。 一、百度收录提交方法 1. 验证网站所有权 1、登录百度搜索资源平台 2、选择「用户中心…

C# OpenCV机器视觉:SoftNMS非极大值抑制

嘿&#xff0c;你知道吗&#xff1f;阿强最近可忙啦&#xff01;他正在处理一个超级棘手的问题呢&#xff0c;就好像在一个混乱的战场里&#xff0c;到处都是乱糟糟的候选框&#xff0c;这些候选框就像一群调皮的小精灵&#xff0c;有的重叠在一起&#xff0c;让阿强头疼不已。…

生信云服务器:让生物信息学分析更高效、更简单【附带西柚云优惠码】

随着生物信息学的快速发展&#xff0c;基因组测序、单细胞分析等复杂任务逐渐成为研究者们的日常工作。然而&#xff0c;个人电脑在处理这些任务时往往面临性能瓶颈&#xff0c;如内存不足、运算速度慢等问题&#xff0c;导致分析任务频繁失败或崩溃。为了解决这一难题&#xf…

【清晰教程】通过Docker为本地DeepSeek-r1部署WebUI界面

【清晰教程】本地部署DeepSeek-r1模型-CSDN博客 目录 安装Docker 配置&检查 Open WebUI 部署Open WebUI 安装Docker 完成本地DeepSeek-r1的部署后【清晰教程】本地部署DeepSeek-r1模型-CSDN博客&#xff0c;通过Docker为本地DeepSeek-r1部署WebUI界面。 访问Docker官…

Flink-序列化

一、概述 几乎每个Flink作业都必须在其运算符之间交换数据&#xff0c;由于这些记录不仅可以发送到同一JVM中的另一个实例&#xff0c;还可以发送到单独的进程&#xff0c;因此需要先将记录序列化为字节。类似地&#xff0c;Flink的堆外状态后端基于本地嵌入式RocksDB实例&…

快速部署 DeepSeek R1 模型

1. DeepSeek R1 模型的介绍 DeepSeek R1 模型是专为自然语言处理&#xff08;NLP&#xff09;和其他复杂任务设计的先进大规模深度学习模型 &#xff0c;其高效的架构设计是一大亮点&#xff0c;能够更高效地提取特征&#xff0c;减少冗余计算。这意味着在处理海量数据时&…

数据库系统概念第六版记录 四

1.sql组成 SQL 是最有影响力的商用市场化的关系查询语言。SQL 语言包括几个部分: 数据定义语言(DDL) &#xff0c;它提供了定义关系模式、删除关系以及修改关系模式的命令。 数据操纵语言(DML) &#xff0c;它包括查询语言&#xff0c;以及往数据库中插入元组、从数据库中删…

DeepSeek在FPGA/IC开发中的创新应用与未来潜力

随着人工智能技术的飞速发展&#xff0c;以DeepSeek为代表的大语言模型&#xff08;LLM&#xff09;正在逐步渗透到传统硬件开发领域。在FPGA&#xff08;现场可编程门阵列&#xff09;和IC&#xff08;集成电路&#xff09;开发这一技术密集型行业中&#xff0c;DeepSeek凭借其…

DeepSeek-V3 的核心技术创新

DeepSeek-V3 的核心技术创新 flyfish DeepSeek-V3 的核心技术创新主要体现在其架构设计和训练目标上&#xff0c;通过 多头潜在注意力&#xff08;MLA&#xff09;、DeepSeekMoE 架构、无辅助损失的负载均衡策略 和 多 Token 预测训练目标&#xff08;MTP&#xff09; 1. 多…

【Elasticsearch】监控与管理:集群监控指标

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

鸿蒙接入支付宝SDK后模拟器无法运行,报错error: install parse native so failed.

鸿蒙项目接入支付宝后&#xff0c;运行提示error: install parse native so failed. 该问题可能由于设备支持的 Abi 类型与 C 工程中的不匹配导致. 官网error: install parse native so failed.错误解决办法 根据官网提示在模块build-profile.json5中添加“x86_64”依然报错 问…

react redux用法学习

参考资料&#xff1a; https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具&#xff1a;deepseek&#xff0c;通义灵码 第一天 安装相关依赖&#xff1a; 使用redux的中间件&#xff1a; npm i react-redu…

【Matlab优化算法-第13期】基于多目标优化算法的水库流量调度

一、前言 水库流量优化是水资源管理中的一个重要环节&#xff0c;通过合理调度水库流量&#xff0c;可以有效平衡防洪、发电和水资源利用等多方面的需求。本文将介绍一个水库流量优化模型&#xff0c;包括其约束条件、目标函数以及应用场景。 二、模型概述 水库流量优化模型…

Redis 集群(Cluster)和基础的操作 部署实操篇

三主三从 集群概念 Redis 的哨兵模式&#xff0c;提高了系统的可用性&#xff0c;但是正在用来存储数据的还是 master 和 slave 节点&#xff0c;所有的数据都需要存储在单个 master 和 salve 节点中。 如果数据量很大&#xff0c;接近超出了 master / slave 所在机器的物理内…

[2025年最新]2024.3版本idea无法安装插件问题解决

背景 随着大模型的持续发展&#xff0c;特别年前年后deepseek的优异表现&#xff0c;编程过程中&#xff0c;需要解决ai来辅助编程&#xff0c;因此需要安装一些大模型插件 问题描述 在线安装插件的时候会遇到以下问题&#xff1a; 1.数据一直在加载&#xff0c;加载的很满 2.点…

elasticsearch安装插件analysis-ik分词器(深度研究docker内elasticsearch安装插件的位置)

最近在学习使用elasticsearch&#xff0c;但是在安装插件ik的时候遇到许多问题。 所以在这里开始对elasticsearch做一个深度的研究。 首先提供如下链接&#xff1a; https://github.com/infinilabs/analysis-ik/releases 我们下载elasticsearch-7-17-2的Linux x86_64版本 …

【Unity3D】UGUI的anchoredPosition锚点坐标

本文直接以实战去理解锚点坐标&#xff0c;围绕着将一个UI移动到另一个UI位置的需求进行说明。 &#xff08;anchoredPosition&#xff09;UI锚点坐标&#xff0c;它是UI物体的中心点坐标&#xff0c;以UI物体锚点为中心的坐标系得来&#xff0c;UI锚点坐标受锚点(Anchors Min…