纪国圣 发表于 2021-12-16 20:10

【华大测评】FFT测试

HC32F460使用CMSIS v5.7.0中的DSP库arm_cortexM4l_math.lib和arm_cortexM4lf_math.lib进行FFT测试。时钟为200MHz,开启FLASH Cache:
分别测试arm_cfft_f32、arm_cfft_radix2_f32、arm_cfft_radix4_f32、arm_rfft_fast_f32的执行效率。测试程序如下:
/*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*                  opensource.org/licenses/BSD-3-Clause
*/
/******************************************************************************/
/** \file main.c
**
** \brief This sample demonstrates how to set GPIO as output function.
**
**   - 2021-04-16 CDT first version for Device Driver Library of GPIO.
**
******************************************************************************/

/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
#include "ev_hc32f460_lqfp100_v1.h"
#include "TIM_Measure.h"

#include "arm_math.h"
#include "arm_const_structs.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define LENGTH                                              1024   
#define DOUBLE_LENGTH                      2*LENGTH            
#define FS                                                              5000.0f

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
float t = 0.0f;       
float CFFT_Inputbuf;    //FFT输入数组
float CFFT_Outputbuf;    //FFT输出数组
float CFFT_x2_Inputbuf;    //FFT输入数组
float CFFT_x2_Outputbuf;    //FFT输出数组
float CFFT_x4_Inputbuf;    //FFT输入数组
float CFFT_x4_Outputbuf;    //FFT输出数组
float RFFT_Inputbuf;    //FFT输入数组
float RFFT_Outputbuf;    //FFT输出数组
float RFFT_Output_buf;    //FFT输出数组
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \briefMain function of GPIO output
**
** \paramNone
**
** \retval int32_t Return value, if needed
**
******************************************************************************/
int32_t main(void)
{
                int i = 0;
    stc_clk_freq_t stc_clk;
       
                arm_rfft_fast_instance_f32 S1;
                arm_cfft_radix2_instance_f32 S2;
                arm_cfft_radix4_instance_f32 S4;
       
                BSP_CLK_Init();

    DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_PortInit);
               
                TIM_Measure_Init();
       
    CLK_GetClockFreq(&stc_clk);
                DDL_Printf("System Clock: %dMHz\n",stc_clk.sysclkFreq/1000/1000);
       
                DDL_Printf("\n");
               
       
                for(i = 0;i < LENGTH;i++)
                {
                                CFFT_Inputbuf = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
                                CFFT_Inputbuf[(i << 1) + 1] = 0;
               
                                CFFT_x2_Inputbuf = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
                                CFFT_x2_Inputbuf[(i << 1) + 1] = 0;
               
                                CFFT_x4_Inputbuf = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
                                CFFT_x4_Inputbuf[(i << 1) + 1] = 0;
               
                                RFFT_Inputbuf = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
                }
               
    while(1)
    {
                        TIM_Measure_Start();
                        arm_cfft_f32(&arm_cfft_sR_f32_len1024,CFFT_Inputbuf,0,1);
                        TIM_Measure_Stop();
                        t = Get_Time();
                        DDL_Printf("arm_cfft_f32 use time: %fus\n",t*1000.0f);
               
                        arm_cmplx_mag_f32(CFFT_Inputbuf,CFFT_Outputbuf,LENGTH);
                        DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_Outputbuf/LENGTH);
                        DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("\n");
                       
                        arm_cfft_radix2_init_f32(&S2,LENGTH,0,1);
                        TIM_Measure_Start();
                        arm_cfft_radix2_f32(&S2,CFFT_x2_Inputbuf);
                        TIM_Measure_Stop();
                        t = Get_Time();
                        DDL_Printf("arm_cfft_radix2_f32 use time: %fus\n",t*1000.0f);
               
                        arm_cmplx_mag_f32(CFFT_x2_Inputbuf,CFFT_x2_Outputbuf,LENGTH);
                        DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_x2_Outputbuf/LENGTH);
                        DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_x2_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_x2_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("\n");
                       
                        arm_cfft_radix4_init_f32(&S4,LENGTH,0,1);
                        TIM_Measure_Start();
                        arm_cfft_radix4_f32(&S4,CFFT_x4_Inputbuf);
                        TIM_Measure_Stop();
                        t = Get_Time();
                        DDL_Printf("arm_cfft_radix4_f32 use time: %fus\n",t*1000.0f);
               
                        arm_cmplx_mag_f32(CFFT_x4_Inputbuf,CFFT_x4_Outputbuf,LENGTH);
                        DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_x4_Outputbuf/LENGTH);
                        DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_x4_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_x4_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("\n");
                       
                        arm_rfft_fast_init_f32(&S1,LENGTH);
                        TIM_Measure_Start();
                        arm_rfft_fast_f32(&S1,RFFT_Inputbuf,RFFT_Outputbuf,0);
                        TIM_Measure_Stop();
                        t = Get_Time();
                        DDL_Printf("arm_rfft_fast_f32 use time: %fus\n",t*1000.0f);
               
                        arm_cmplx_mag_f32(RFFT_Outputbuf,RFFT_Output_buf,LENGTH);
                        DDL_Printf("calc amp at base: %f,actual is 10\n",RFFT_Output_buf/LENGTH);
                        DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",RFFT_Output_buf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",RFFT_Output_buf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
                        DDL_Printf("\n");
                        while(1);
    };
}

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/
不开启FPU:

开启FPU:

可以看出FPU和FLASH Cache对结果影响很大。不知为什么arm_rfft_fast_f32始终不能得到正确结果。

tpgf 发表于 2024-6-4 12:20

fft对时钟的最低要求是多快的呢

paotangsan 发表于 2024-6-4 13:49

执行效率的影响因素一般都有哪些呢

xiaoqizi 发表于 2024-6-4 14:34

fft运行的时间如何能够精确的测量呢

wowu 发表于 2024-6-4 21:45

做fft的测试一定要使用flash才能完成吗

wakayi 发表于 2024-6-4 22:17

想要实现fft的计算 除了对频率 有要求外 对其他硬件有米有要求呢

renzheshengui 发表于 2024-6-4 22:49

我们都可以通过哪些数据来评测fft呢

gouguoccc 发表于 2024-6-10 22:40

200MHZ主频还是已经很不错了

daichaodai 发表于 2024-6-12 19:50

在交流信号测量中会用到FFT算法。

亚瑟 发表于 2024-6-28 19:31

这个对时钟还有要求吗

CarterERO 发表于 2024-6-28 22:39

标准主频就是200M吗?

youtome 发表于 2024-7-7 13:35

CMSIS DSP库中提供了FFT函数

lzbf 发表于 2024-7-7 14:36

HC32F460使用CMSIS v5.7.0中的DSP库arm_cortexM4l_math.lib和arm_cortexM4lf_math.lib进行FFT测试。

claretttt 发表于 2024-7-7 16:07

建议使用非特定于硬件的库函数            

chenjun89 发表于 2024-7-7 20:35

交流信号测量有效值等参数就是用FFT算法

ulystronglll 发表于 2024-7-9 21:05

启用了FPU?               

geraldbetty 发表于 2024-7-10 00:10

#include<stdio.h>
#include "arm_math.h"

#define SAMPLES 128
float32_t input;
float32_t output;

int main(void) {
    arm_rfft_fast_instance_f32 S;
    arm_status status;

    // 初始化实数FFT实例
    status = arm_rfft_fast_init_f32(&S, SAMPLES);
    if (status != ARM_MATH_SUCCESS) {
      printf("Error initializing FFT\n");
      return 1;
    }

    // 生成输入信号(例如正弦波)
    for (int i = 0; i < SAMPLES; i++) {
      input = sin(2 * PI * i / SAMPLES);
    }

    // 执行实数FFT
    arm_rfft_fast_f32(&S, input, output, 0);

    // 输出结果
    for (int i = 0; i < SAMPLES; i++) {
      printf("%d: %f\n", i, output);
    }

    return 0;
}

pixhw 发表于 2024-7-10 03:12

arm_cortexM4l_math.lib和arm_cortexM4lf_math.lib分别是为带有浮点运算的Cortex-M4处理器和带浮点运算的Cortex-M4F处理器优化的。

xiaoyaodz 发表于 2024-7-10 06:15

参考CMSIS DSP库的官方文档和示例代码,可以帮助你更快地理解和使用库中的功能。

bartonalfred 发表于 2024-7-10 20:18

可以在任何Cortex-M处理器上运行
页: [1] 2
查看完整版本: 【华大测评】FFT测试