STM32 DSP库CUBEMX配置+FFT频率计算

文章目录

  • 前言
  • 一、DSP库添加
    • 1.1 加一个define
    • 1.2 添加文件路径
    • 1.3 主函数
  • 二、FFT运算求频率
    • 2.1 初始版本
    • 版本2
  • 总结


前言

使用DSP中的函数加快计算。
本文首先讲述如何通过添加dsp库。
再讲述使用DSP库进行实数FFT运算。(FFT运算用到了前面讲述的STM32CubeMX-ADC hal库 3定时器触发)

参考1文章
参考2文章


一、DSP库添加

1.1 加一个define

,ARM_MATH_CM3//F1是M3,F4是M4,H7是M7

在这里插入图片描述

1.2 添加文件路径

先找到文件路径
在这里插入图片描述
在这里插入图片描述然后设置如下路径
在这里插入图片描述
双击如下并找到路径D:\STM32CubeMX\STM32Cube_FW_F4_V1.26.2\Drivers\CMSIS\Lib\ARM选择arm_cortexM4lf_math.lib
在这里插入图片描述

1.3 主函数

包含头文件

#include "arm_math.h"
#include "arm_const_structs.h"

进行编译

二、FFT运算求频率

FFT运算简单理解就是从时域来求解频域的问题。
对于FFT的思路和代码参考这位大佬写的。
那我们根据他的步骤,将文章简化并复现代码。(在复刻的过程中发现了一些问题,所以不完全按照上面大佬的文章)
这篇大佬讲述了arm_rfft_fast_f32的用法
这里还列出一些其他参考。
参考1
参考2
参考3
参考4,,,这个用的不是实数而是complex。所以稍微看下
cmsis官网

2.1 初始版本

宏定义和全局变量

#define adc_SIZE 2048*2// ADC 采样大小的定义
uint32_t adcConvertValue[adc_SIZE]={0};// 存放 ADC 采样数据的数组
uint8_t flag=0;// 标记位,用于标识 ADC 采样是否完成
float32_t frequency ;// 用于存放计算结果的频率变量
// FFT 相关参数的定义
#define FFT_SIZE 2048
#define FFT_LEN FFT_SIZE 
#define SAMPLING_FREQUENCY 100000
float32_t inputSignal[FFT_SIZE*2];// FFT 输入信号数组
float32_t fftOutput[FFT_SIZE];// FFT 输出数组
uint32_t index_;// 存放 FFT 输出中最大值的索引

运算函数

void fftCalculate(void)// FFT 计算函数
{arm_cfft_f32(&arm_cfft_sR_f32_len2048, inputSignal, 0, 1);// 执行 FFT 计算arm_cmplx_mag_f32(inputSignal, fftOutput, FFT_LEN);// 计算 FFT 输出的幅度index_ = 0;// 查找 FFT 输出中的最大值float32_t maxValue = fftOutput[1];
//    for (uint32_t i = 1; i < FFT_LEN/2; i++)
//    {
//        if (fftOutput[i] > maxValue)
//        {
//            maxValue = fftOutput[i];
//            index = i;
//        }
//    }arm_max_f32(&fftOutput[1], FFT_LEN, &maxValue, &index_); // 使用 arm_max_f32 函数快速找到 FFT 输出中的最大值及其索引frequency = (float32_t)index_ * (float32_t)SAMPLING_FREQUENCY / (float32_t)FFT_SIZE;// 根据最大值的索引计算信号的频率}

主函数

	HAL_TIM_Base_Start(&htim3);//启动定时器3HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adcConvertValue,adc_SIZE);//启动ADC的DMA传输,采200点

主循环

  while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(flag==1){flag=0;for(int j=0;j<FFT_SIZE;j++)//采样数据转换{inputSignal[j*2]=(adcConvertValue[j])*3.3f/4095.0f;//12位采样数字值对应为0-3.3伏inputSignal[j*2+1]=0;//交替插零,添加数据的虚部}fftCalculate();
//			HAL_Delay(2000);HAL_TIM_Base_Start(&htim3);	//重新启动定时器3HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adcConvertValue,adc_SIZE);//重新开始下一轮采集	}			}

版本2

文件

根据抽样定理我们可以知道,采样率要是最高频率的两倍,所以对文中的一些东西进行了优化。
就是将本来size的位置都设置为/2,这样既可以防止跳变也可以减少运算。

	float32_t fftOutput[FFT_SIZE/2];// FFT 输出数组
    arm_cmplx_mag_f32(inputSignal, fftOutput, FFT_LEN/2);// 计算 FFT 输出的幅度arm_max_f32(&fftOutput[1], FFT_LEN/2, &maxValue, &index_); // 使用 arm_max_f32 函数快速找到 FFT 输出中的最大值及其索引

总结

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

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

相关文章

【C++】C/C++内存管理

目录 一、C/C内存管理 二、C语言中动态内存管理方式:malloc/calloc/realloc/free 三、C中动态内存管理 1、new/delete操作内置类型 2、new和delete操作自定义类型 四、operator new与operator delete函数(重点) 五、new和delete的实现原理 1、内置类型 2、自定义类型 六、…

kalibr使用照片生成数据

rosrun kalibr kalibr_bagcreater --folder /home/zf/calib_ws/data/hikvision_chessboard_0707/left --output-bag /home/zf/test.bag 生成照片的目录底下要求有cam0,另外照片的数据格式必须得要求有时间:1639644559400963.png

【GaussDB(DWS)】数据分布式存储-三种类型的表

toc 一、环境说明 华为数据仓库服务DWS&#xff0c;集群版本8.1.3.320集群拓扑结构&#xff1a; 二、数据分布式方式 DWS采用水平分表的方式&#xff0c;将业务数据表的元组打散存储到各个节点内。这样带来的好处在于&#xff0c;查询中通过查询条件过滤不必要的数据&#…

关于IIS安全设置http能访问https不能访问的解决方案

最近折腾IIS&#xff0c;发现网站的http能访问但是https不能访问。 我确认所有关于HTTPS的配置我都配置正确了&#xff0c;结果还是不能访问&#xff0c;一番折腾发现&#xff0c;服务器本身的防火墙和阿里云服务器的安全组规则不是一回事。改完防火墙也没有用&#xff0c;重要…

nginx+Tomcat实现负载均衡、动静分离集群部署

一、负载均衡原理二、动静分离原理三、NginxTomcat负载均衡、动静分离的操作步骤3.1 部署Nginx 负载均衡器3.2 部署2台Tomcat 应用服务器3.2.1 Tomcat服务器1&#xff1a;192.168.147.101:80803.2.2 Tomcat服务器2&#xff1a;192.168.147.102:8080 192.168.147.102:8081 3.3 动…

leetcode 654. 最大二叉树

2023.7.9 又是一道递归构造二叉树的题&#xff0c;和昨天做的那道题从中序与后序遍历序列构造二叉树类似&#xff0c;5分钟AC了。 大致思路就是通过找到数组中的最大值&#xff0c;并将其作为根节点&#xff0c;然后递归地构建左子树和右子树&#xff0c;最终返回整个最大二叉树…

聊聊不同集群的微服务如何通过feign调用

前言 之前业务部门的某项目微服务调用关系如下图 后因业务改造需要&#xff0c;该项目需要将服务A部署到另外一个集群&#xff0c;但服务A仍然需要能调用到服务B&#xff0c;调用关系如下图 之前调用方式是负责服务B的开发团队提供相应的feign客户端包给到服务A开发团队&…

进程间通信的介绍

目录 进程间通信的目的 进程间通信发展 进程间通信分类 进程间通信的分析 进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&a…

星辰天合公司产品完成阿里云 PolarDB 数据库产品生态集成认证

近日&#xff0c;XSKY星辰天合旗下产品与阿里云 PolarDB 开源云原生数据库展开产品集成认证测试&#xff0c;并获得阿里云颁发的产品生态集成认证证书。 测试结果表明&#xff0c;星辰天合旗下的融合计算管理平台 XHERE&#xff08;V2&#xff09;、统一数据平台 XEDP&#xf…

基于Spring Boot的医院信息管理系统设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的医院信息管理系统设计与实现 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 后端&#xff1a;Java springboot框架 mybatis 数据库&#xff1a;mysql5.7 开发工具:IDEA…

Java 定义返回一个不能被修改、删除元素的List

为啥突然分享下这个&#xff0c;也是从mybatis源码看到了&#xff0c;所以想分享下&#xff1a; org.apache.ibatis.plugin.InterceptorChain 使用 Collections.unmodifiableList(); 示例&#xff1a; public static void main(String[] args) {List<String> canNotEdit…

C数据结构与算法——单链表 应用

实验任务 (1) 掌握单链表结构及其 C 语言实现&#xff1b; (2) 掌握插入、删除等基本算法&#xff1b; (3) 掌握单链表的基本应用&#xff08;将两个有序线性表合并为一个有序表&#xff09;。 实验内容 使用 C 语言实现单链表的类型定义与算法函数&#xff1b;编写 main()函…