【STM32】STM32F4调用DSP库实现FFT运算

这篇具有很好参考价值的文章主要介绍了【STM32】STM32F4调用DSP库实现FFT运算。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面

最近在整理之前的stm32笔记,打算把一些有价值的笔记发到CSDN分享一下。

奎斯特定理

在进行模拟/数字信号的转换过程中,当采样频率F大于信号中最高频率 fmax 的 2 倍时(F>2*fmax),采样之后的数字信号完整地保留了原始信号中的信息。

采样结果

  • 设采样频率(单位时间可以采多少个信号样本)为Fs,信号频率F,采样点数为N。那么FFT之后结果就是一个为N点的复数。每一个点对应一个频率点,并且这个点对应的幅值就是该频率下的幅度特性。

  • 而每个点的相位,就是在该频率下的信号的相位。

  • 假设原始信号的峰值为A

    那么FFT的第一个点(直流分量)的模值就是A的N倍

    FFT的其他点的模值就是A的N/2倍

    比如

  • 第一个点表示直流分量(即0Hz),而最后一个点N的再下一个点(实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后)则表示采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率依次增加。第n所表示的频率为:Fn=(n-1) * Fs/N。

    比如采样频率为10240Hz,采样点数为1024。即采样一次的时间为1/10240s,100ms可以采样1024个点,1s可以采样10次。则结果中第1个点代表0Hz,第2个点代表10Hz,第3个点代表20Hz,以此类推,第1024个点代表1024Hz。则频率分辨率为10Hz

  • 如果要提高频率分辨力,则必须增加采样点数,也即采样时间。频率分辨率和采样时间是倒数关系。 假设FFT之后某点n用复数a+bi表示,那么这个复数的模就是An=根号aa+bb,相位就是Pn=atan2(b,a)。根据以上的结果,就可以计算出n点(n≠1,且n<=N/2)对应的信号的表达式为An/(N/2)cos(2piFnt+Pn),即2An/Ncos(2piFn*t+Pn)。对于n=1点的信号,是直流分量,幅度即为A1/N。 由于FFT结果的对称性,通常我们只使用前半部分的结果,即小于采样频率一半的结果。

stm32中相关函数

/*
 * 函数1  初始化FFT运算相关参数
 *	fftLen 			用于指定 FFT长度(16/64/256/1024/4096)本章设置为1024
 *	ifftFlag 		用于指定是傅里叶变换(0)还是反傅里叶变换(1) 本章设置为0
 *	bitReverseFlag  用于设置是否按位取反 本章设置为 1
 * */
arm_status arm_cfft_radix4_init_f32(
	arm_cfft_radix4_instance_f32 * S,
	uint16_t fftLen,uint8_t ifftFlag,uint8_t bitReverseFlag)


/*
 *  函数2  执行基 4 浮点FFT运算
 * 	S结构体指针参数 先由 arm_cfft_radix4_init_f32 函数设置好 然后传入该函数的
 * 	pSrc 		  传入采集到的输入信号数据(实部+虚部形式)同时FFT变换后的数据也按顺序存放在pSrc里面pSrc 				  必须大于等于2倍fftLen长度
 * */
void arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 * S,float32_t * pSrc)


/*
 *  函数3  计算复数模值 对 FFT 变换后的结果数据,执行取模操作
 *	pSrc 		复数输入数组(大小为 2*numSamples)指针,指向 FFT 变换后的结果
 *	pDst		输出数组(大小为 numSamples)指针,存储取模后的值
 *	numSamples  就是总共有多少个数据需要取模
 * */
void arm_cmplx_mag_f32(float32_t * pSrc,float32_t * pDst,uint32_t numSamples)

arm_cfft_radix4_init_f32 用于初始化 FFT 运算相关参数,

  • fftLen 用于指定 FFT 长度(16/64/256/1024/4096),本章设置为 1024;
  • ifftFlag 用于指定是傅里叶变换(0)还是反傅里叶变换(1),本章设置为 0;
  • bitReverseFlag 用于设置是否按位取反,本章设置为 1;
  • 最后,所有这些参数存储在一个 arm_cfft_radix4_instance_f32 结构体指针 S 里面

arm_cfft_radix4_f32 就是执行基 4 浮点 FFT 运算的

  • pSrc 传入采集到的输入信号数据(实部+虚部形式),同时 FFT 变换后的数据,也按顺序存放在 pSrc 里面,pSrc 必须大于等于 2 倍 fftLen 长度
  • S 结构体指针参数是先由 arm_cfft_radix4_init_f32 函数设置好,然后传入该函数的

**arm_cmplx_mag_f32 **用于计算复数模值,可以对 FFT 变换后的结果数据,执行取模操作

  • pSrc 为复数输入数组(大小为 2*numSamples)指针,指向 FFT 变换后的结果
  • pDst为输出数组(大小为 numSamples)指针,存储取模后的值;
  • numSamples 就是总共有多少个数据需要取模

stm32配置

配置时钟树

【STM32】STM32F4调用DSP库实现FFT运算

添加DSP库

可以从MDK中添加,可以手动添加,这里演示从STM32CubeMX添加
【STM32】STM32F4调用DSP库实现FFT运算
如果没有安装先点击Install,安装完之后点击框框选中
【STM32】STM32F4调用DSP库实现FFT运算
选择添加DSP库
【STM32】STM32F4调用DSP库实现FFT运算

配置定时器触发ADC

这里以TIM3触发ADC1-CH1为例

TIM3挂在APB1上, APB1默认timer时钟为84MHz,这里配置TIM3频率为84000000/(42*100)=20000Hz=20KHz

即采样频率为20KHz,50us触发一次ADC采一次数据,如果是1024个点0.0512s可以采完一次
【STM32】STM32F4调用DSP库实现FFT运算
配置ADC,先打开DMA
【STM32】STM32F4调用DSP库实现FFT运算
别忘了点circular
【STM32】STM32F4调用DSP库实现FFT运算
ADC基础设置
【STM32】STM32F4调用DSP库实现FFT运算

打开串口,方便调试

很简单,自行配置。打开串口是为了方便查看运算后的信息

生成代码

添加宏

ARM_MATH_CM4//F4是这个
ARM_MATH_MATRIX_CHECK   
ARM_MATH_ROUNDING    

【STM32】STM32F4调用DSP库实现FFT运算

验证库是否正常

添加头文件

#include "arm_math.h"

编译,可以通过!

编写用户函数

#define FFT_LENGTH		1024 		//FFT长度,默认是1024点FFT

/*添加的头文件*/
#include "arm_math.h"
#include "stdio.h"


/*printf重定向*/
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}


/*全局变量,在main之前定义*/
arm_cfft_radix4_instance_f32 scfft;//定义scfft结构体
float FFT_InputBuf[FFT_LENGTH*2];	//FFT输入数组
float FFT_OutputBuf[FFT_LENGTH];	//FFT输出数组
uint16_t ADC_1_Value_DMA[1024] = {0};//存放ADC的值


/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim3);//开启TIM3
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_1_Value_DMA, FFT_LENGTH);//开启ADC
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT参数
/* USER CODE END 2 */



/*while(1)中*/
for(int i=0; i < FFT_LENGTH; i++)
{
    FFT_InputBuf[2*i]=ADC_1_Value_DMA[i]; //实部
    FFT_InputBuf[2*i+1]=0;				  //虚部
}
arm_cfft_radix4_f32(&scfft,FFT_InputBuf);					//FFT计算(基4)
arm_cmplx_mag_f32(FFT_InputBuf,FFT_OutputBuf,FFT_LENGTH);	//取模得幅值

之后可以用vofa+软件方便地查看频谱图。

可以动手实现的小项目

外接一个mic采集、oled实现音乐频谱等文章来源地址https://www.toymoban.com/news/detail-423495.html

到了这里,关于【STM32】STM32F4调用DSP库实现FFT运算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

    使用DSP中的函数加快计算。 本文首先讲述如何通过添加dsp库。 再讲述使用DSP库进行实数FFT运算。(FFT运算用到了前面讲述的STM32CubeMX-ADC hal库 3定时器触发) 参考1文章 参考2文章 先找到文件路径 然后设置如下路径 双击如下并找到路径 D:STM32CubeMXSTM32Cube_FW_F4_V1.26.2DriversCMS

    2024年02月16日
    浏览(30)
  • GD32F4移植STM32F4

    近期在项目中采用了GD32F407VET6替换原项目中的STM32F407VET6,网传GD的兼容性很好,之前也用F1系统的替换了一下,按照CSND各位大佬的经验一步步改进了代码,测试直接通过,现在也一直在项目中实际应用了,一直没有出问题。 所以这SMT时,嘉立创没有STM的货果断换成了GD,可换时

    2024年02月16日
    浏览(72)
  • STM32CubeMx移植DSP库 傅立叶变化(FFT)测试

    本篇文章采用的是ST公司的STM32L496的DSP库进行FFT函数测试,将计算得到的数据通过串口工具打印出来,其他支持DSP库的型号也是类似做法。 STM32L496为超低功耗Cortex-M4内核的MCU,具有64个引脚,并且外设资源丰富(4个IIC硬件通信接口、5个串口通信接口、3个SPI通信接口、3个12位

    2023年04月08日
    浏览(34)
  • 运动控制器设计——基于FreeModbus在STM32F4平台实现ModbusTCP和ModbusRTU

    本文笔者最近的项目是设计一款运动控制器,MCU使用的是STM32F429,要求是通过Modbus TCP协议实现与示教器通讯,并通过ModbusRTU实现与触摸屏通讯。 本文将介绍在STM32F4上实现 ModbusTCP和ModbusRTU通讯 的过程。笔者才疏学浅,如有错误还请指正。 Modbus协议是典型的主-从通讯结构,链

    2024年02月05日
    浏览(41)
  • 基于STM32F407实现快速傅里叶变化(FFT),计算指定频率的幅值

    前言: 本人的课题是关于EIT采集系统设计,所谓的EIT,简单的说就是往人体注入特定频率的电流信号,通过采集反馈的电压信号,进而使用成像算法重构人体内部的阻抗分布。由于采集到的电压包含其它频率的热噪声,为了只保留注入频率的信号成分,需要对采集到的电压信

    2024年02月12日
    浏览(37)
  • [GD32F4]基于GD32固件库移植cherryusb[STM32F4]

    [GD32F4]基于GD32固件库移植cherryusb[STM32F4] 使用开发板是淘宝买的不知名开发板,没什么好说的,具体的型号是GD32F450VET6。 使用的cherryusb版本是0.9.0版本。 使用的GD32官方固件库版本是:GD32F4xx_Firmware_Library_V3.0.4 cherryusb最牛的地方在于抛弃掉所有的依赖,只需要知道芯片的usb中断

    2024年02月06日
    浏览(44)
  • 基于STM32F407实现离散傅里叶变换(FFT、DFT),计算指定频率的幅值

    前言: 本人的课题是关于EIT采集系统设计,所谓的EIT,简单的说就是往人体注入特定频率的电流信号,通过采集反馈的电压信号,进而使用成像算法重构人体内部的阻抗分布。由于采集到的电压包含其它频率的热噪声,为了只保留注入频率的信号成分,需要对采集到的电压信

    2024年02月16日
    浏览(47)
  • 【STM32】STM32F4 GPIO详解与配置

    GPIO是通用输入输出端口的简称,为STM32可控制的引脚,STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。STM32芯片的GPIO被分成很多组,每组有16个引脚,所有的GPIO引脚都有基本的输入输出功能。 其中保护二极管使GPIO能够5V电压容忍。在

    2024年02月07日
    浏览(44)
  • STM32F4Timer

    ref https://blog.csdn.net/zhuxinmingde/article/details/131784852?ops_request_misc=request_id=biz_id=102utm_term=STM32%20%E9%AB%98%E7%BA%A7%EF%BC%8C%E6%99%AE%E9%80%9A%EF%BC%8C%E5%9F%BA%E6%9C%AC%E5%AE%9A%E6%97%B6%E5%99%A8utm_medium=distribute.pc_search_result.none-task-blog-2 all sobaiduweb~default-1-131784852.142 v99 controlspm=1018.2226.3001.4187 1. Timer re

    2024年02月02日
    浏览(35)
  • 【GD32F310开发板试用】浮点DSP运算及Modbus移植测评

    首发极术社区。如对兆易创新GD32F310 MCU感兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论群。 1. 测评背景 GD32作为国产化ARM中的旗舰,其全系列产品不仅市场占有率高,而且各具特色,广受使用者好评。 笔者在测评这款GD32F310之前,曾经使用过GD32F450,其强大的性能,低廉的价

    2023年04月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包