STM32F4学习笔记2——自建库函数整合FFT计算遇到的问题及方法

发布者:ZenMaster123最新更新时间:2019-02-19 来源: eefocus关键字:STM32F4  自建库函数  FFT计算 手机看文章 扫描二维码
随时随地手机看文章

最近采用FFT计算信号频谱,需要先减去信号均值,参考网上看到的范例,实现了功能,代码为:


arm_mean_f32(DataBuffer, SIG_N, &MeanData);

for (int16_t k = 0 ; k <= SIG_N - 1 ; k++) {

DeMeanDataBuffer[k] = DataBuffer[k] - MeanData;

}


arm_mean_f32(DeMeanDataBuffer, SIG_N, &MeanData2);

arm_status status; 

arm_cfft_radix2_instance_f32 S;  

status = ARM_MATH_SUCCESS; 


status = arm_cfft_radix2_init_f32(&S, FFT_N,ifftFlag, doBitReverse); 


arm_cfft_radix2_f32(&S,DeMeanDataBuffer); 


arm_cmplx_mag_f32(DeMeanDataBuffer, FFT_Output, FFT_N);


但是上面这一段代码都要放在main函数中,对于追求简洁的我来说,这是无法忍受的。于是建头文件,自己写了个库函数,将上述代码打包,函数实现代码如下:


#include "xiao_fft.h"

#include "xiao_array.h"


void xiao_FFT_f32(

float32_t* FFT_Data,

  uint32_t FFTSize,

float32_t* FFT_Mag)

{

float32_t MeanData = 0;


float32_t FFT_Mag[FFTSize];

float32_t DeMeanData[FFTSize*2];

uint32_t ifftFlag = 0; 

uint32_t doBitReverse = 1;

arm_mean_f32(FFT_Data, FFTSize*2, &MeanData);

for ( int32_t k = 0 ; k <= FFTSize*2 - 1 ; k++) {

*(DeMeanData+k) = *(FFT_Data+k) - MeanData;

}

  arm_status status; 

arm_cfft_radix2_instance_f32 S;  

status = ARM_MATH_SUCCESS; 


status = arm_cfft_radix2_init_f32(&S, FFTSize,ifftFlag, doBitReverse); 


arm_cfft_radix2_f32(&S,FFT_Data); 


arm_cmplx_mag_f32(FFT_Data, FFT_Mag, FFTSize);

return;

}



    然而,问题出现了。函数始终无法返回FFT幅度值(FFT_Mag)。经断点调试发现,在函数arm_cfft_radix2_f32中进入了HardFault_Handler中断。在网上参考大神资料,发现原因如下:不要在函数内部定义超过几十个字节的大数组,不然会引起数组越界或堆栈溢出。而上述代码定义了大数组DeMeanData(我也不懂,但依照着修改,呵呵)。

1

按照这个约束,重新理清思路:先在main函数中去data均值,得到demean_data,然后再进行FFT。实现代码如下:


/////////////////////////////////////////////////////

xiao_demean_array_f32(DataBuffer,SIG_N,DeMeanDataBuffer);

xiao_FFT_f32(DeMeanDataBuffer,FFT_N,FFT_Output);


///////////////////////////////////////////////////

#include "xiao_array.h"

void xiao_demean_array_f32(

float32_t* xiao_array_data,

  uint32_t xiao_array_size,

float32_t* xiao_array_demean_data)

{

float32_t mean_data = 0;

arm_mean_f32(xiao_array_data, xiao_array_size, &mean_data);

for ( int32_t k = 0 ; k <= xiao_array_size - 1 ; k++) {

*(xiao_array_demean_data+k) = *(xiao_array_data+k) - mean_data;

}

}


/////////////////////////////////////////////////////


#include "xiao_fft.h"

#include "xiao_array.h"



void xiao_FFT_f32(

float32_t* FFT_Data,

  uint32_t FFTSize,

float32_t* FFT_Mag)

{


uint32_t ifftFlag = 0; 

uint32_t doBitReverse = 1;

  arm_status status; 

arm_cfft_radix2_instance_f32 S;  

status = ARM_MATH_SUCCESS; 


status = arm_cfft_radix2_init_f32(&S, FFTSize,ifftFlag, doBitReverse); 


arm_cfft_radix2_f32(&S,FFT_Data); 


arm_cmplx_mag_f32(FFT_Data, FFT_Mag, FFTSize);

return;

}


这下成功了!撒花庆祝! 

另外,STM32的DSP库中,计算FFT时要求数据长度data_len必须是FFT点数FFT_Size的2倍。


关键字:STM32F4  自建库函数  FFT计算 引用地址:STM32F4学习笔记2——自建库函数整合FFT计算遇到的问题及方法

上一篇:STM32F4学习笔记4——STM32的AD用DMA方式时的请注意初始化顺序
下一篇:STM32F4学习笔记1——如何使用DSP库

推荐阅读最新更新时间:2024-03-16 16:24

基于stm32f4的高速信号频谱分析仪的设计与实现
摘 要 本系统是以STM32F407为核心,主要采用FIFO来做高速缓存。高速信号先通过AD采样,然后先将采样后的数据给FIFO先缓存处理,然后再通过STM32F407进行加Blackman预处理,再做1024个点FFT进行频谱分析,最后将数据显示在LCD12864上,以便进行人机交互!该系统可实现任意波形信号的频谱显示,以及可以自动寻找各谐波分量的幅值,频率以及相位并进行8位有效数据显示。 系统设计任务 一、任务 设计并制作一个高速频谱分析仪。 1系统方案 本系统由前置匹配放大电路,AD采样电路,高速FIFO缓存电路,以及液晶显示电路组成。其中高速数据缓存电路,以及高精度的显示数据是本次设计的难点!下面分别论证这几个模块的
[测试测量]
基于<font color='red'>stm32f4</font>的高速信号频谱分析仪的设计与实现
第41章 STM32F429的LTDC应用之LCD汉字显示和2D图形显示
41.1 初学者重要提示 学习本章节前,务必优先学习第40章,需要对LTDC的基础知识和HAL库的几个常用API有个认识。 本章的第4小节LCD驱动设计非常重要。 如果自己观察的话,LCD上电会有一个瞬间高亮的问题,在此贴进行了描述:http://www.armbbs.cn/forum.php?mod=viewthread&tid=82619 。这个解决方案已经应用到本章配套的例子上。 本章节用到的汉字方案会在下章专门为大家讲解,下面是小字库的制作方法:http://www.armbbs.cn/forum.php?mod=viewthread&tid=202 。 调试状态或者刚下载LCD的程序到里面,屏幕会抖动,这个是
[单片机]
第41章 <font color='red'>STM32F4</font>29的LTDC应用之LCD汉字显示和2D图形显示
STM32F4硬件IIC+DMA使用
1.STM32硬件IIC一直被大家说存在问题,实际测试发现确实是有这种情况,借助网上很多人的经验,终于把硬件IIC写完了。 2.使用DMA时,发现发送数据(写寄存器)时序和实际不符,比如发送4字节数据时,如果DMA缓冲区单字节长度配置为4,则实际时序发现只有三个,需要将DMA缓冲区单字节长度配置为5,才可以正常使用 3.当然,如果使用STM32的HAL库,这些问题其实都可以避免,因为底层ST已经做了超时及错误的处理。 4.使用的IIC为自定义的格式, 写寄存器操作为: START+ACK(从机的ACK信号)+IIC设备地址+(从机的ACK信号)+START+ACK(从机的ACK信号)+IIC写寄存器地址+ACK
[单片机]
STM32F407串口的基本使用
串口 串口在嵌入式系统中是一个非常重要的外设,它通信方式简单在软件开发阶段常用作调试工具。本示例中我们只实现串口的输出功能,同时还 会实现一个具有printf功能输出接口。这样咱们以后的例程中就有了一个简单的调试工具。 1. STM32串口简介 STM32的串口功能非常丰富,它可以支持双全工异步通信、LIN、IrDA、智能卡协议、单线半双工通信、支持调制解调器操作。 接下来我们将对使用STM32的串口应该进行的哪些设置给予简单说明,并对需要设置的寄存器给予简单介绍。要使用串口除了应对串口的波特率等进行配置外还需要对串口用到I/O进行设置,下面将分步进行介绍: 1) 串口时钟使能 STM32可以对每个外设进行单独的时钟控制,因此配置
[单片机]
STM32F4 HAL库DMA学习
用了一段时间HAL库,不知道是不是用外设固件库时间长一点的原因,个人感觉没有固件库来的直接。看DMA部分看的有点乱,捋一下。 DMA的使用方法及细节直接看官方的手册就可以了,注意的是如果原地址和目的地址的数据长度不一样的话只能使用FIFO模式,直接模式下原地址和目的地址的数据长度必须一致。 主要是简单整理一下使用DMA的初始化过程,以串口发送使用DMA为例: (1) 定义一个外设的句柄,对外设的基本参数、IO、时钟、中断等进行初始化。 UART_HandleTypeDef UART1_Handler; .... HAL_UART_Init(&UART1_Handler); 调用外设的初始
[单片机]
STM32F401的PWM输出
PWM的说明 PWM有三个关键指标: PWM频率, 占空比, 区分度 对于同一个时钟频率下工作的单片机, 区分度是和PWM工作频率相关的, 因为总频率是固定的, PWM工作频率越高, 留下给区分度的部分就越低, 因此区分度就越低. 对于STM32, 如果时钟是72MHz, 在PWM频率为1KHz时, 区分度为16bit, 在281KHz时, 为8bit, 在4.5MHz时, 就时4bit了. STM32F4 Timers STM32的PWM功能是定时器功能的一部分, STM32F4系列完整的定时器是14个 Timer Type Resolution Prescaler Channels MAX INTERFACE CLOC
[单片机]
STM32F4CubeMX学习笔记之Time2 pwm
开发板:普中PZ6808L-F4 开发环境:keil5+CnbeMx CnbeMx配置为定时器2 配置IO口为PB10 PB11 好了就可以用示波器查看有没有输出了
[单片机]
<font color='red'>STM32F4</font>CubeMX学习笔记之Time2 pwm
stm32f4xx系列的DHT11+HCSR04超声波+LCD1602
先说这次的实验:这次实验历经了差不多两个周,所获不少。最后实现了,还是有点小激动的,这同时也是我的课程设计。这次的设计主要是通过读取DHT11和HCSR04的数值,(Proteus的传感器貌似这两款好用一点)把读取的DHT11和HCSR04数值通过转化在lcd1602中显示出来,还有就是可以设置通过按键设置DHT11的温湿度阈值。 运行结果图: 按下K1,K2为加1设置,K3为减1设置 调整湿度最小值要为88% 湿度低于88%;警报响,红灯亮 在调DHT11使它正常,同时也跳一下超声波,看数据传输是否正常 当超过阈值时警报,红灯亮起,绿灯灭。下面是主要代码: 主要代码: #include stm32f4xx.h
[单片机]
<font color='red'>stm32f4</font>xx系列的DHT11+HCSR04超声波+LCD1602
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved