硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1487|回复: 9
收起左侧

[DSP] 我用STM32F405,主频配置120M,做4096个FFT,时间居然要225ms左右,出问题了吗?

[复制链接]

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-10-30 16:47:35 | 显示全部楼层 |阅读模式
void FFT_Calculate(void)// FFT 计算函数
{
    for(int j=0;j<FFT_SIZE;j++)//采样数据转换
        {
                inputSignal[j*2]=ADC1_ConvertedValue[j];//12位采样数字值对应为0-3.3伏
                inputSignal[j*2+1]=0;//交替插零,添加数据的虚部
        }


//    for (uint16_t i = 0; i < FFT_SIZE; i++)
//    {  
//        inputSignal[2 * i] = 10000 * arm_sin_f32(PI2 * i * 50.0 / 4096)+20000* arm_sin_f32(PI2 * i * 100.0 / 4096);  // 实部  
//        inputSignal[2 * i + 1] = 0.0f;  // 虚部  
//    }  
   
//    Generate_Hanning_Window(inputSignal,FFT_SIZE);




    arm_cfft_f32(&arm_cfft_sR_f32_len4096, inputSignal, 0, 1);// 执行 FFT 计算
    arm_cmplx_mag_f32(inputSignal, fftOutput, FFT_SIZE/2);// 计算 FFT 输出的幅度
   
    Max_Index = Find_Fundamental_Frequency(fftOutput, FFT_SIZE);// 查找 FFT 输出中的最大值
    Frequency = (float32_t)Max_Index * 1;//(float32_t)SAMPLING_FREQUENCY;


//    for(int j=1;j<FFT_SIZE;j++)
//        {
//                 printf("%f\r\n", fftOutput[j]); //
//        }

}




void Analyze_Dma_Data(void)
{
    uint32_t i, m;

        HAL_GPIO_WritePin(GPIOC, THS7001_G2_Pin,1);

        for(i = 0, m = 0; m < ADC1_DMA_Size && i < (ADC1_DMA_Size * 2);)  //分解3ADC数据,归一化数据
        {
            ADC1_ConvertedValue = (float)(ADC123_Buff[m] & 0x0000FFFF) * 3.3f / 4095.0f;
            i++;
            ADC1_ConvertedValue = (float)((ADC123_Buff[m] & 0xFFFF0000) >> 16) * 3.3f / 4095.0f;
            i++;
            m++;
        }
        Generate_Hanning_Window(ADC1_ConvertedValue,FFT_SIZE);//汉宁窗
        FFT_Calculate();
        DMA_FLAG = 0;
        HAL_GPIO_WritePin(GPIOC, THS7001_G2_Pin,0);
}
已经开启了FPU,USE_HAL_DRIVER,STM32F405xx,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,__TARGET_FPU_VFP,__FPU_PRESENT=1用的是DSP库,不至于需要这么长时间吧
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-10-31 08:15:55 | 显示全部楼层
那你这个执行时间太长了,这个我之前测试的,F407,主频168, 测试的arm_cfft_f32
你测试下你的arm_cfft_f32执行时间多少

123456.png
回复

使用道具 举报

356

主题

2180

回帖

3253

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3253
发表于 2024-10-31 09:56:39 | 显示全部楼层
本帖最后由 caicaptain2 于 2024-10-31 10:16 编辑

---
你这个IO口测时间,包含了多个函数,还是一个函数一个函数的测时间看看。
另外。FPU是不是正常开启了,用别的方法确认一下。
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-10-31 10:11:38 | 显示全部楼层
光执行arm_cfft_f32,时间大约4ms,
大量时间是消耗在这个汉宁窗函数Generate_Hanning_Window(inputSignal,FFT_SIZE);执行了220ms左右
#define M_PI 3.14159265358979323846
void Generate_Hanning_Window(float32_t *window, uint16_t size)
{
    for (uint16_t i = 0; i < size; i++)
    {  
        window[i] = 0.5 * (1 - cos(2 * M_PI * i / (size - 1)));  
    }  
}
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-10-31 10:13:42 | 显示全部楼层
光这个arm_cfft_f32(&arm_cfft_sR_f32_len4096, inputSignal, 0, 1)的执行时间还是和您的执行时间差了1ms
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-10-31 10:19:27 | 显示全部楼层
caicaptain2 发表于 2024-10-31 09:56
---
你这个IO口测时间,包含了多个函数,还是一个函数一个函数的测时间看看。
另外。FPU是不是正常开启了 ...

是的,IO口测时间,包含了多个函数,所以今天针对单独的函数进行了测试,主要时间都消耗在了汉宁窗函数上了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-10-31 16:06:55 | 显示全部楼层
ljfljfljf123 发表于 2024-10-31 10:19
是的,IO口测时间,包含了多个函数,所以今天针对单独的函数进行了测试,主要时间都消耗在了汉宁窗函数上 ...

使用ARM DSP的三角函数API试试
window = 0.5 * (1 - cos(2 * M_PI * i / (size - 1)));  

他是查表实现的

回复

使用道具 举报

5

主题

269

回帖

284

积分

高级会员

积分
284
发表于 2024-11-1 09:21:04 | 显示全部楼层
本帖最后由 DX3906 于 2024-11-1 09:22 编辑

函数本身可以优化一下,用单精度的cosf,cos是双精度,在f405上会慢
然后减少每个循环的计算量,比如2 * M_PI / (size - 1)可以提到循环外面
如果传进来的size是4的倍数,那可以把循环展开,每个循环计算4次

代码类似这样:
[C] 纯文本查看 复制代码
void Generate_Hanning_Window(float32_t *window, uint16_t size)
{
    float32_t scale = 2.0f * M_PI / (size - 1);

    uint16_t i;
    for (i = 0; i < size - 4; i += 4)
    {
        float32_t t0 = i * scale;
        float32_t t1 = (i + 1) * scale;
        float32_t t2 = (i + 2) * scale;
        float32_t t3 = (i + 3) * scale;

        window[i] = 0.5f * (1.0f - cosf(t0));
        window[i + 1] = 0.5f * (1.0f - cosf(t1));
        window[i + 2] = 0.5f * (1.0f - cosf(t2));
        window[i + 3] = 0.5f * (1.0f - cosf(t3));
    }
}

回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-11-2 08:55:23 | 显示全部楼层
现在我把这个窗提前算好,不放在处理计算数据部分,
#define M_PI 3.14159265358979323846
void generateHanningWindow(float32_t *hanningWindow,uint32_t numSamples)
{  
    for (uint32_t i = 0; i < numSamples; i++)
    {  
        hanningWindow[i] = 0.5f * (1 - cos(2 * PI * i / (numSamples - 1)));  
    }   
}


// 应用汉宁窗到信号  
void applyHanningWindowToSignal(float32_t *signal, float32_t *hanningWindow, uint32_t numSamples)   
{  
    for (uint32_t i = 0; i < numSamples; i++)
    {  
        signal[2 * i] *= hanningWindow[i]; // 只处理实部,因为虚部为零  
    }  
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-11-2 09:40:34 | 显示全部楼层
除了上坛友贴的,三角函数的选择问题


DSP视频教程第8期:DSP库三角函数,C库三角函数和硬件三角函数的性能比较,以及与Matlab的精度比较(2022-06-04)
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=112675


123.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 02:48 , Processed in 0.048082 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表