[方案相关] 【华大测评】FFT测试

[复制链接]
 楼主| 纪国圣 发表于 2021-12-16 20:10 | 显示全部楼层 |阅读模式
HC32F460使用CMSIS v5.7.0中的DSP库arm_cortexM4l_math.lib和arm_cortexM4lf_math.lib进行FFT测试。时钟为200MHz,开启FLASH Cache: 3.PNG
分别测试arm_cfft_f32、arm_cfft_radix2_f32、arm_cfft_radix4_f32、arm_rfft_fast_f32的执行效率。测试程序如下:
  1. /*******************************************************************************
  2. * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
  3. *
  4. * This software component is licensed by HDSC under BSD 3-Clause license
  5. * (the "License"); You may not use this file except in compliance with the
  6. * License. You may obtain a copy of the License at:
  7. *                    opensource.org/licenses/BSD-3-Clause
  8. */
  9. /******************************************************************************/
  10. /** \file main.c
  11. **
  12. ** \brief This sample demonstrates how to set GPIO as output function.
  13. **
  14. **   - 2021-04-16 CDT first version for Device Driver Library of GPIO.
  15. **
  16. ******************************************************************************/

  17. /*******************************************************************************
  18. * Include files
  19. ******************************************************************************/
  20. #include "hc32_ddl.h"
  21. #include "ev_hc32f460_lqfp100_v1.h"
  22. #include "TIM_Measure.h"

  23. #include "arm_math.h"
  24. #include "arm_const_structs.h"
  25. /*******************************************************************************
  26. * Local type definitions ('typedef')
  27. ******************************************************************************/

  28. /*******************************************************************************
  29. * Local pre-processor symbols/macros ('#define')
  30. ******************************************************************************/
  31. #define LENGTH                                                1024   
  32. #define DOUBLE_LENGTH                        2*LENGTH              
  33. #define FS                                                                5000.0f  

  34. /*******************************************************************************
  35. * Global variable definitions (declared in header file with 'extern')
  36. ******************************************************************************/

  37. /*******************************************************************************
  38. * Local function prototypes ('static')
  39. ******************************************************************************/

  40. /*******************************************************************************
  41. * Local variable definitions ('static')
  42. ******************************************************************************/
  43. float t = 0.0f;       
  44. float CFFT_Inputbuf[DOUBLE_LENGTH];    //FFT输入数组
  45. float CFFT_Outputbuf[LENGTH];    //FFT输出数组
  46. float CFFT_x2_Inputbuf[DOUBLE_LENGTH];    //FFT输入数组
  47. float CFFT_x2_Outputbuf[LENGTH];    //FFT输出数组
  48. float CFFT_x4_Inputbuf[DOUBLE_LENGTH];    //FFT输入数组
  49. float CFFT_x4_Outputbuf[LENGTH];    //FFT输出数组
  50. float RFFT_Inputbuf[LENGTH];    //FFT输入数组
  51. float RFFT_Outputbuf[LENGTH];    //FFT输出数组
  52. float RFFT_Output_buf[LENGTH];    //FFT输出数组
  53. /*******************************************************************************
  54. * Function implementation - global ('extern') and local ('static')
  55. ******************************************************************************/
  56. /**
  57. *******************************************************************************
  58. ** \brief  Main function of GPIO output
  59. **
  60. ** \param  None
  61. **
  62. ** \retval int32_t Return value, if needed
  63. **
  64. ******************************************************************************/
  65. int32_t main(void)
  66. {
  67.                 int i = 0;
  68.     stc_clk_freq_t stc_clk;
  69.        
  70.                 arm_rfft_fast_instance_f32 S1;
  71.                 arm_cfft_radix2_instance_f32 S2;
  72.                 arm_cfft_radix4_instance_f32 S4;
  73.        
  74.                 BSP_CLK_Init();

  75.     DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_PortInit);
  76.                
  77.                 TIM_Measure_Init();
  78.        
  79.     CLK_GetClockFreq(&stc_clk);
  80.                 DDL_Printf("System Clock: %dMHz\n",stc_clk.sysclkFreq/1000/1000);
  81.        
  82.                 DDL_Printf("\n");
  83.                
  84.        
  85.                 for(i = 0;i < LENGTH;i++)
  86.                 {
  87.                                 CFFT_Inputbuf[i << 1] = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
  88.                                 CFFT_Inputbuf[(i << 1) + 1] = 0;
  89.                
  90.                                 CFFT_x2_Inputbuf[i << 1] = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
  91.                                 CFFT_x2_Inputbuf[(i << 1) + 1] = 0;
  92.                
  93.                                 CFFT_x4_Inputbuf[i << 1] = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
  94.                                 CFFT_x4_Inputbuf[(i << 1) + 1] = 0;
  95.                
  96.                                 RFFT_Inputbuf[i << 1] = 10 + 4.5*arm_sin_f32(2*PI*i*200/ FS)+ 3.2*arm_sin_f32(2*PI*i*350/ FS);
  97.                 }
  98.                
  99.     while(1)
  100.     {
  101.                         TIM_Measure_Start();
  102.                         arm_cfft_f32(&arm_cfft_sR_f32_len1024,CFFT_Inputbuf,0,1);
  103.                         TIM_Measure_Stop();
  104.                         t = Get_Time();
  105.                         DDL_Printf("arm_cfft_f32 use time: %fus\n",t*1000.0f);
  106.                
  107.                         arm_cmplx_mag_f32(CFFT_Inputbuf,CFFT_Outputbuf,LENGTH);
  108.                         DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_Outputbuf[0]/LENGTH);
  109.                         DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
  110.                         DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
  111.                         DDL_Printf("\n");
  112.                        
  113.                         arm_cfft_radix2_init_f32(&S2,LENGTH,0,1);
  114.                         TIM_Measure_Start();
  115.                         arm_cfft_radix2_f32(&S2,CFFT_x2_Inputbuf);
  116.                         TIM_Measure_Stop();
  117.                         t = Get_Time();
  118.                         DDL_Printf("arm_cfft_radix2_f32 use time: %fus\n",t*1000.0f);
  119.                
  120.                         arm_cmplx_mag_f32(CFFT_x2_Inputbuf,CFFT_x2_Outputbuf,LENGTH);
  121.                         DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_x2_Outputbuf[0]/LENGTH);
  122.                         DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_x2_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
  123.                         DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_x2_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
  124.                         DDL_Printf("\n");
  125.                        
  126.                         arm_cfft_radix4_init_f32(&S4,LENGTH,0,1);
  127.                         TIM_Measure_Start();
  128.                         arm_cfft_radix4_f32(&S4,CFFT_x4_Inputbuf);
  129.                         TIM_Measure_Stop();
  130.                         t = Get_Time();
  131.                         DDL_Printf("arm_cfft_radix4_f32 use time: %fus\n",t*1000.0f);
  132.                
  133.                         arm_cmplx_mag_f32(CFFT_x4_Inputbuf,CFFT_x4_Outputbuf,LENGTH);
  134.                         DDL_Printf("calc amp at base: %f,actual is 10\n",CFFT_x4_Outputbuf[0]/LENGTH);
  135.                         DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",CFFT_x4_Outputbuf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
  136.                         DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",CFFT_x4_Outputbuf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
  137.                         DDL_Printf("\n");
  138.                        
  139.                         arm_rfft_fast_init_f32(&S1,LENGTH);
  140.                         TIM_Measure_Start();
  141.                         arm_rfft_fast_f32(&S1,RFFT_Inputbuf,RFFT_Outputbuf,0);
  142.                         TIM_Measure_Stop();
  143.                         t = Get_Time();
  144.                         DDL_Printf("arm_rfft_fast_f32 use time: %fus\n",t*1000.0f);
  145.                
  146.                         arm_cmplx_mag_f32(RFFT_Outputbuf,RFFT_Output_buf,LENGTH);
  147.                         DDL_Printf("calc amp at base: %f,actual is 10\n",RFFT_Output_buf[0]/LENGTH);
  148.                         DDL_Printf("calc amp at 200Hz: %f,actual is 4.5\n",RFFT_Output_buf[(unsigned int)(200*LENGTH/FS) + 1]/(LENGTH/2.0f));
  149.                         DDL_Printf("calc amp at 350Hz: %f,actual is 3.2\n",RFFT_Output_buf[(unsigned int)(350*LENGTH/FS) + 1]/(LENGTH/2.0f));
  150.                         DDL_Printf("\n");
  151.                         while(1);
  152.     };
  153. }

  154. /*******************************************************************************
  155. * EOF (not truncated)
  156. ******************************************************************************/
不开启FPU:
2.PNG
开启FPU:
1.PNG
可以看出FPU和FLASH Cache对结果影响很大。不知为什么arm_rfft_fast_f32始终不能得到正确结果。
HC32F460_FFT.zip (2.72 MB, 下载次数: 44)
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[SAMPLES];
float32_t output[SAMPLES];

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[i] = 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[i]);
    }

    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处理器上运行
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

407

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部