STM32CubeMx移植DSP库 傅立叶变化(FFT)测试


前言

本篇文章采用的是ST公司的STM32L496的DSP库进行FFT函数测试,将计算得到的数据通过串口工具打印出来,其他支持DSP库的型号也是类似做法。


一、STM32L496简介?

STM32L496为超低功耗Cortex-M4内核的MCU,具有64个引脚,并且外设资源丰富(4个IIC硬件通信接口、5个串口通信接口、3个SPI通信接口、3个12位内置ADC等)

二、FFT简介

FFT即快速傅立叶变换,可以将一个时域信号变换到频域。因为有些信号在时域上是很难看出什么特征的,但是如果将其变换到频域之后,就很容易看出特征了,这也就是很多信号分析都会采用FFT变换的原因。其次,FFT可以将一个信号的频谱和相位提取出来,这在频谱和相位分析中也是经常用到的。
在实际工程中,一般的处理过程是先对一个信号在时域进行采样,如ADC采样,按照一定大小采样频率F去采集信号,采集N个点,那么通过对这N个点进行FFT运算,就可以得到这个信号的频谱和相位特征。


三、STM32CubeMx配置

这里主要讲解对DSP库的配置,其他基础配置略过。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过以上步骤就完成了对STM32CubeMx DSP库的配置,然后就可以点生成代码。

四、MDK配置与程序

4.1宏定义的添加

需要添加4各宏定义,分别为:(注意:是英文状态下的分号;内核是M4就是ARM_MATH_CM4,M3就是ARM_MATH_CM3)

ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING

在这里插入图片描述

4.2程序编写

STM32的DSP库里面,提供了定点和浮点FFT实现方式,并且有基4和基2的,对于基4的FFT输入点数必须是4的n次方,而基2的FFT输入点数则必须是2的n次方,且基4的FFT算法比基2要快,大家可以选择自己实现的方式。
这里采用基4浮点FFT来实现FFT变换,所用到的函数分别为:

arm_status arm_cfft_radix4_init_f32(arm_cfft_radix4_instance_f32 *S,uint16_t fftLen,uint8_t ifftFlag,uint8_t bitReverseFlag)
void arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 *S,float32_t *pSrc)
void arm_cmplx_mag_f32(float32_t* pSrc,float32_t* pDst,uint32_t numSamples)

第一个函数是用于初始化FFT运算相关参数的,第二个函数是执行基4浮点FFT运算的,第三个函数是计算复数模值的。通过这三个函数即可完成FFT计算并取模值。
1、头文件的添加
在这里插入图片描述
2、程序实现
本次暂时先对100+10arm_sin_f32(2PIi/FFT_LENGTH)+30arm_sin_f32(2PIi4/FFT_LENGTH)+50arm_cos_f32(2PIi*8/FFT_LENGTH)函数进行FFT变换,求频域幅值和相位。

#define FFT_LENGTH 1024
float fft_inputbuf[FFT_LENGTH*2];
float fft_outputbuf[FFT_LENGTH];
float Phase_Result[FFT_LENGTH];

/***************************进行傅立叶变换********************************************/	
       arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);	   
	   for(int i = 0; i<FFT_LENGTH; i++)
	  {  fft_inputbuf[2*i]=100+10*arm_sin_f32(2*PI*i/FFT_LENGTH)+30*arm_sin_f32(2*PI*i*4/FFT_LENGTH)+50*arm_cos_f32(2*PI*i*8/FFT_LENGTH);
		  fft_inputbuf[2*i+1]=0;
	  }
	  arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4运算)
	  for(int i=0;i<FFT_LENGTH;i++) //求各点的初始相位
	  {
		Phase_Result[i] = atan2(fft_inputbuf[2*i+1],fft_inputbuf[2*i]); //范围为(-PI,PI)
		Phase_Result[i]=(Phase_Result[i]*180.0f)/PI;
	  }
	  
	  arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //求各频点的模
	  
/***************************处理变换结果*********************************************/	  
	  for(int i = 0; i < FFT_LENGTH; i++)
	  {
		  printf("fft_outputbuf[%d]:%f\r\n", i, fft_outputbuf[i]); //幅值
		  printf("Phase_Result[%d]:%f\r\n", i ,Phase_Result[i]); //相位
		  HAL_Delay(1000);
	  }

五、结果

在这里插入图片描述
查看以上数据,可知,第0,1,4,8,1016,1020,1023这几个点的幅值比较大。FFT变换具有对称性,我们只需要看前面半部分,后半部分和前半部分是对称关系,如1和1023,4和1020,8和1016等。

总结

STM32CubeMx移植DSP库测试FFT变换基本配置和操作步骤就是这样,实际应用中经过ADC采样的离散数据点的FFT变换也是相同的操作。

  • 11
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值