STM32F7 DSP库 FFT过程记录

STM32F7 DSP库 FFT过程记录

目录

之前做课设的时候接触过FFT,看了一些资料,没整明白,现在做项目又用到FFT了,花了点时间整明白了。但此处的明白并非把FFT的原理啥的整明白了,只是明白在STM32上怎么用了。开发环境如下

  • STM32F767IGT6
  • Keil5.21
  • Cube MX4.24
  • arm_cortexM7lfdp_math.lib
  • 正点原子阿波罗开发板

准备DSP库

打开下载的固件库,文件名为STM32Cube_FW_F7_V1.9.0,
CMSIS文件夹
Drivers文件夹下,CMISIS文件夹中包含上图所示文件夹,DSP_Lib和Lib是DSP库相关文件,其中DSP_Lib又包含两个文件夹,Examples和Source。
Examples 中的文件如下(这些是 ARM 官方提供的 DSP 实例):
Examples文件夹
Source 中的文件如下(这些是 DSP库的源文件):
这里写图片描述
源文件不需要添加到工程中,真正需要添加到工程中的是官方提供的DSP库,文件格式为.lib。库文件位于Lib文件夹中,有ARM和GCC两种开发环境的库,我们选择ARM。如图所示。
DSP库文件
库文件有好多种,关于每种库文件的说明参见官方说明。 CMSIS DSP Software Library。该网站上有详细说明。如下图所示。
不同版本的库说明
确定了用哪个库后,添加到工程中。我的工程是用CubeMX建的,因此添加DSP库的时候在软件中操作,勾选后自动添加,如图。
软件操作
软件操作
下图为DSP库已添加到工程中。
添加到工程中的DSP库
库添加到工程中,在需要用到库函数的文件中引用头文件,#include “arm_math.h”,即可调用所需函数。

函数说明

我用到的是实数FFT,即rfft。相关函数参见官方说明
函数名中f32代表32位浮点数,q31代表32位定点数,q15代表16位定点数,q7代表8位定点数。
arm_rfft_fast_f32是FFT实现的主要函数,函数原型如下。
arm_rfft_fast_f32
S是 arm_rfft_instance_f32 类型的结构体,p和pOut是输入和输出的缓冲区,ifftFlag是变换的标志位。
另外还有一个实现rfft的函数 arm_rfft_instance_f32,函数原型如下。
arm_rfft_instance_f32
官方不推荐使用此函数。“Do not use this function. It has been superceded by arm_rfft_fast_f32 and will be removed in the future. ”
除了FFT函数之外,还要用到一个函数对arm_rfft_fast_f32中的参数S进行初始化,该函数为 arm_rfft_fast_init_f32,用于 初始化结构体S中的参数 ,函数原型如下。
arm_rfft_fast_init_f32
另外一个重要的函数是arm_cmplx_mag_f32,计算频率的幅值。函数原型如下。
arm_cmplx_mag_f32

代码示例

include "DSP.h"
include "arm_math.h"
define NPT  1024  //1024点FFT
define Fs 5120  //采样频率 5120Hz 频率分辨率 5Hz
define PI2 6.28318530717959
float32_t  testInput_f32[NPT];
float32_t  testOutput_f32[NPT];
float32_t  testOutput[NPT];

/* 
********************************************************************************************************* 
*  函 数 名: arm_rfft_fast_f32_app 
*  功能说明: 调用函数arm_rfft_fast_f32计算1024点实数序列的幅频响应并跟使用函数arm_cfft_f32计算结果做对比 
*  形    参:无 
*  返 回 值: 无 
********************************************************************************************************* 
*/ 
void arm_rfft_fast_f32_app(void) 
{ 
  uint16_t i; 
  arm_rfft_fast_instance_f32 S; 

  /* 实数序列FFT长度 */ 
  uint16_t fftSize = NPT;  
  /* 正变换 */ 
    uint8_t ifftFlag = 0;  

  /* 初始化结构体S中的参数 */ 
   arm_rfft_fast_init_f32(&S, fftSize); 

    /* 按照实部,虚部,实部,虚部..... 的顺序存储数据 */ 
  for(i=0; i<1024; i++) 
  { 
    /*3种频率 50Hz 2500Hz 2550Hz */ 
    testInput_f32[i] = 1000*arm_sin_f32(PI2*i*50.0/Fs) + 
               2000*arm_sin_f32(PI2*i*2500.0/Fs)  + 
               3000*arm_sin_f32(PI2*i*2550.0/Fs); 
  } 

  /* 1024点实序列快速FFT */  
  arm_rfft_fast_f32(&S, testInput_f32, testOutput_f32, ifftFlag); 

  /* 为了方便跟函数arm_cfft_f32计算的结果做对比,这里求解了1024组模值,实际函数arm_rfft_fast_f32 
     只求解出了512组   
  */  
   arm_cmplx_mag_f32(testOutput_f32, testOutput, fftSize); 

  /* 串口打印求解的模值 */ 
  for(i=0; i<fftSize/2; i++) 
  { 
    printf("%f\r\n", testOutput[i]); 
  } 
}

结果

在单片机上运行,将串口助手接收到的数据保存到TXT文件,利用matlab进行分析。
串口助手接收幅值数据
保存为TXT文件
导入到MatLab中
对数据plot画图,结果如下
频谱图
可以看出,FFT之后分析出包含信号的频率为50Hz,2500Hz,2550Hz,与生成信号 testInput_f32[i] = 1000*arm_sin_f32(PI2*i*50.0/Fs) + 2000*arm_sin_f32(PI2*i*2500.0/Fs) + 3000*arm_sin_f32(PI2*i*2550.0/Fs);
吻合。

  • 38
    点赞
  • 161
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值